Merge branch 'feat/update-spl' into feat/message-list-view-shrink-wrap

This commit is contained in:
Sahil Kumar
2023-05-03 16:28:16 +05:30
committed by GitHub
4 changed files with 171 additions and 150 deletions
@@ -391,12 +391,14 @@ void main() {
), ),
)); ));
// Insert a new opaque OverlayEntry that would prevent the first OverlayEntry // Insert a new opaque OverlayEntry that would prevent the first
// from doing re-layout. Since there's no relayout boundaries in the first // OverlayEntry from doing re-layout. Since there's no relayout boundaries
// OverlayEntry, no dirty RenderObjects in its render subtree can update // in the first OverlayEntry, no dirty RenderObjects in its render subtree
// layout. // can update layout.
final newOverlay = final newOverlay = OverlayEntry(
OverlayEntry(builder: (context) => const SizedBox.expand(), opaque: true); builder: (context) => const SizedBox.expand(),
opaque: true,
);
tester.state<OverlayState>(find.byType(Overlay)).insert(newOverlay); tester.state<OverlayState>(find.byType(Overlay)).insert(newOverlay);
await tester.pump(); await tester.pump();
@@ -48,7 +48,10 @@ void main() {
itemCount: itemCount, itemCount: itemCount,
itemScrollController: itemScrollController, itemScrollController: itemScrollController,
itemBuilder: (context, index) { itemBuilder: (context, index) {
assert(index >= 0 && index <= itemCount - 1); assert(
index >= 0 && index <= itemCount - 1,
'index must be in the range of 0 to itemCount - 1',
);
return SizedBox( return SizedBox(
height: height:
variableHeight ? (itemHeight + (index % 13) * 5) : itemHeight, variableHeight ? (itemHeight + (index % 13) * 5) : itemHeight,
@@ -1133,34 +1136,35 @@ void main() {
}, skip: true); }, skip: true);
testWidgets( testWidgets(
'Jump to 400 at bottom, manually scroll, scroll to 100 at bottom and back', 'Jump to 400 at bottom, manually scroll, scroll to 100 at bottom and back',
(WidgetTester tester) async { (WidgetTester tester) async {
final itemScrollController = ItemScrollController(); final itemScrollController = ItemScrollController();
final itemPositionsListener = ItemPositionsListener.create(); final itemPositionsListener = ItemPositionsListener.create();
await setUpWidgetTest(tester, await setUpWidgetTest(tester,
itemScrollController: itemScrollController, itemScrollController: itemScrollController,
itemPositionsListener: itemPositionsListener); itemPositionsListener: itemPositionsListener);
itemScrollController.jumpTo(index: 400, alignment: 1); itemScrollController.jumpTo(index: 400, alignment: 1);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final listFinder = find.byType(ScrollablePositionedList); final listFinder = find.byType(ScrollablePositionedList);
await tester.drag(listFinder, const Offset(0, -screenHeight)); await tester.drag(listFinder, const Offset(0, -screenHeight));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
unawaited(itemScrollController.scrollTo( unawaited(itemScrollController.scrollTo(
index: 100, alignment: 1, duration: scrollDuration)); index: 100, alignment: 1, duration: scrollDuration));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
unawaited(itemScrollController.scrollTo( unawaited(itemScrollController.scrollTo(
index: 400, alignment: 1, duration: scrollDuration)); index: 400, alignment: 1, duration: scrollDuration));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final itemFinder = find.text('Item 399'); final itemFinder = find.text('Item 399');
expect(itemFinder, findsOneWidget); expect(itemFinder, findsOneWidget);
expect(tester.getBottomLeft(itemFinder).dy, screenHeight); expect(tester.getBottomLeft(itemFinder).dy, screenHeight);
}); },
);
testWidgets('physics', (WidgetTester tester) async { testWidgets('physics', (WidgetTester tester) async {
final itemScrollController = ItemScrollController(); final itemScrollController = ItemScrollController();
@@ -1652,70 +1656,71 @@ void main() {
}); });
testWidgets( testWidgets(
'Maintain programmatic and user position (9 half way off top) in page view', 'Maintain programmatic and user position (9 half way off top) in page view',
(WidgetTester tester) async { (WidgetTester tester) async {
final itemPositionsListener = ItemPositionsListener.create(); final itemPositionsListener = ItemPositionsListener.create();
final itemScrollController = ItemScrollController(); final itemScrollController = ItemScrollController();
tester.binding.window.devicePixelRatioTestValue = 1.0; tester.binding.window.devicePixelRatioTestValue = 1.0;
tester.binding.window.physicalSizeTestValue = tester.binding.window.physicalSizeTestValue =
const Size(screenWidth, screenHeight); const Size(screenWidth, screenHeight);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: PageView( home: PageView(
children: [ children: [
KeyedSubtree( KeyedSubtree(
key: const PageStorageKey('key'), key: const PageStorageKey('key'),
child: ScrollablePositionedList.builder( child: ScrollablePositionedList.builder(
itemCount: defaultItemCount, itemCount: defaultItemCount,
itemScrollController: itemScrollController, itemScrollController: itemScrollController,
itemBuilder: (context, index) => SizedBox( itemBuilder: (context, index) => SizedBox(
height: itemHeight, height: itemHeight,
child: Text('Item $index'), child: Text('Item $index'),
),
itemPositionsListener: itemPositionsListener,
), ),
itemPositionsListener: itemPositionsListener,
), ),
), const Center(
const Center( child: Text('Test'),
child: Text('Test'), )
) ],
], ),
), ),
), );
);
itemScrollController.jumpTo(index: 9); itemScrollController.jumpTo(index: 9);
await tester.pump(); await tester.pump();
expect(tester.getBottomRight(find.text('Item 9')).dy, itemHeight); expect(tester.getBottomRight(find.text('Item 9')).dy, itemHeight);
await tester.drag( await tester.drag(
find.byType(ScrollablePositionedList), const Offset(0, -itemHeight)); find.byType(ScrollablePositionedList), const Offset(0, -itemHeight));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final item9Bottom = tester.getBottomRight(find.text('Item 9')).dy; final item9Bottom = tester.getBottomRight(find.text('Item 9')).dy;
expect(item9Bottom, lessThan(itemHeight)); expect(item9Bottom, lessThan(itemHeight));
await tester.drag(find.byType(PageView), const Offset(-500, 0)); await tester.drag(find.byType(PageView), const Offset(-500, 0));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await tester.drag(find.byType(PageView), const Offset(500, 0)); await tester.drag(find.byType(PageView), const Offset(500, 0));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tester.getBottomRight(find.text('Item 9')).dy, item9Bottom); expect(tester.getBottomRight(find.text('Item 9')).dy, item9Bottom);
expect( expect(
itemPositionsListener.itemPositions.value itemPositionsListener.itemPositions.value
.firstWhere((position) => position.index == 9) .firstWhere((position) => position.index == 9)
.itemLeadingEdge, .itemLeadingEdge,
-(itemHeight / screenHeight) / 2); -(itemHeight / screenHeight) / 2);
expect( expect(
itemPositionsListener.itemPositions.value itemPositionsListener.itemPositions.value
.firstWhere((position) => position.index == 9) .firstWhere((position) => position.index == 9)
.itemTrailingEdge, .itemTrailingEdge,
(itemHeight / screenHeight) / 2); (itemHeight / screenHeight) / 2);
}); },
);
testWidgets('List with no items', (WidgetTester tester) async { testWidgets('List with no items', (WidgetTester tester) async {
final itemScrollController = ItemScrollController(); final itemScrollController = ItemScrollController();
@@ -1746,7 +1751,10 @@ void main() {
itemScrollController: itemScrollController, itemScrollController: itemScrollController,
itemPositionsListener: itemPositionsListener, itemPositionsListener: itemPositionsListener,
itemBuilder: (context, index) { itemBuilder: (context, index) {
assert(index >= 0 && index <= itemCount - 1); assert(
index >= 0 && index <= itemCount - 1,
'index must be in the range of 0 to itemCount - 1',
);
return SizedBox( return SizedBox(
height: itemHeight, height: itemHeight,
child: Text('Item $index'), child: Text('Item $index'),
@@ -1788,7 +1796,10 @@ void main() {
initialScrollIndex: min(100, itemCount - 1), initialScrollIndex: min(100, itemCount - 1),
itemCount: itemCount, itemCount: itemCount,
itemBuilder: (context, index) { itemBuilder: (context, index) {
assert(index >= 0 && index <= itemCount - 1); assert(
index >= 0 && index <= itemCount - 1,
'index must be in the range of 0 to itemCount - 1',
);
return SizedBox( return SizedBox(
height: itemHeight, height: itemHeight,
child: Text('Item $index'), child: Text('Item $index'),
@@ -1827,7 +1838,10 @@ void main() {
initialScrollIndex: itemCount - 1, initialScrollIndex: itemCount - 1,
itemCount: itemCount, itemCount: itemCount,
itemBuilder: (context, index) { itemBuilder: (context, index) {
assert(index >= 0 && index <= itemCount - 1); assert(
index >= 0 && index <= itemCount - 1,
'index must be in the range of 0 to itemCount - 1',
);
return SizedBox( return SizedBox(
height: itemHeight, height: itemHeight,
child: Text('Item $index'), child: Text('Item $index'),
@@ -31,12 +31,13 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
// Use flex layout to ensure that the minimum height is not limited to screenHeight // Use flex layout to ensure that the minimum height is not limited to
// screenHeight.
home: Column(children: [ home: Column(children: [
// Use Constrained to make max height not more than screenHeight // Use Constrained to make max height not more than screenHeight
ConstrainedBox( ConstrainedBox(
constraints: constraints: const BoxConstraints(
const BoxConstraints(maxHeight: screenHeight, maxWidth: screenWidth), maxHeight: screenHeight, maxWidth: screenWidth),
child: PositionedList( child: PositionedList(
key: key, key: key,
itemCount: itemCount, itemCount: itemCount,
@@ -292,73 +293,75 @@ void main() {
}); });
testWidgets( testWidgets(
'List positioned with 5 at top then scroll up 2 programatically and shrink wrap', '''List positioned with 5 at top then scroll up 2 programatically and shrink wrap''',
(WidgetTester tester) async { (WidgetTester tester) async {
final scrollController = ScrollController(); final scrollController = ScrollController();
await setUpWidgetTest(tester, await setUpWidgetTest(tester,
topItem: 5, scrollController: scrollController); topItem: 5, scrollController: scrollController);
scrollController.jumpTo(-2 * itemHeight); scrollController.jumpTo(-2 * itemHeight);
await tester.pump(); await tester.pump();
expect(find.text('Item 2'), findsNothing); expect(find.text('Item 2'), findsNothing);
expect(find.text('Item 3'), findsOneWidget); expect(find.text('Item 3'), findsOneWidget);
expect(find.text('Item 12'), findsOneWidget); expect(find.text('Item 12'), findsOneWidget);
expect(find.text('Item 13'), findsNothing); expect(find.text('Item 13'), findsNothing);
expect( expect(
itemPositionsNotifier.itemPositions.value itemPositionsNotifier.itemPositions.value
.firstWhere((position) => position.index == 2) .firstWhere((position) => position.index == 2)
.itemLeadingEdge, .itemLeadingEdge,
-1 / 10); -1 / 10);
expect( expect(
itemPositionsNotifier.itemPositions.value itemPositionsNotifier.itemPositions.value
.firstWhere((position) => position.index == 3) .firstWhere((position) => position.index == 3)
.itemLeadingEdge, .itemLeadingEdge,
0); 0);
expect( expect(
itemPositionsNotifier.itemPositions.value itemPositionsNotifier.itemPositions.value
.firstWhere((position) => position.index == 12) .firstWhere((position) => position.index == 12)
.itemTrailingEdge, .itemTrailingEdge,
1); 1);
}); },
);
testWidgets( testWidgets(
'List positioned with 5 at top then scroll down 20 programatically and shrink wrap', '''List positioned with 5 at top then scroll down 20 programatically and shrink wrap''',
(WidgetTester tester) async { (WidgetTester tester) async {
final scrollController = ScrollController(); final scrollController = ScrollController();
await setUpWidgetTest(tester, await setUpWidgetTest(tester,
topItem: 5, scrollController: scrollController); topItem: 5, scrollController: scrollController);
scrollController.jumpTo(itemHeight * 20); scrollController.jumpTo(itemHeight * 20);
await tester.pump(); await tester.pump();
expect( expect(
itemPositionsNotifier.itemPositions.value itemPositionsNotifier.itemPositions.value
.firstWhere((position) => position.index == 23) .firstWhere((position) => position.index == 23)
.itemLeadingEdge, .itemLeadingEdge,
-2 / 10); -2 / 10);
expect( expect(
itemPositionsNotifier.itemPositions.value itemPositionsNotifier.itemPositions.value
.firstWhere((position) => position.index == 24) .firstWhere((position) => position.index == 24)
.itemLeadingEdge, .itemLeadingEdge,
-1 / 10); -1 / 10);
expect( expect(
itemPositionsNotifier.itemPositions.value itemPositionsNotifier.itemPositions.value
.firstWhere((position) => position.index == 25) .firstWhere((position) => position.index == 25)
.itemLeadingEdge, .itemLeadingEdge,
0); 0);
expect( expect(
itemPositionsNotifier.itemPositions.value itemPositionsNotifier.itemPositions.value
.firstWhere((position) => position.index == 4) .firstWhere((position) => position.index == 4)
.itemLeadingEdge, .itemLeadingEdge,
-21 / 10); -21 / 10);
expect( expect(
itemPositionsNotifier.itemPositions.value itemPositionsNotifier.itemPositions.value
.firstWhere((position) => position.index == 5) .firstWhere((position) => position.index == 5)
.itemLeadingEdge, .itemLeadingEdge,
-20 / 10); -20 / 10);
}); },
);
testWidgets( testWidgets(
'List positioned with 5 at top and initial scroll offset and shrink wrap', 'List positioned with 5 at top and initial scroll offset and shrink wrap',
@@ -424,7 +427,8 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
// Use flex layout to ensure that the minimum height is not limited to screenHeight // Use flex layout to ensure that the minimum height is not limited to
// screenHeight.
home: PositionedList( home: PositionedList(
itemCount: 5, itemCount: 5,
itemBuilder: (context, index) { itemBuilder: (context, index) {
@@ -27,12 +27,13 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
// Use flex layout to ensure that the minimum height is not limited to screenHeight // Use flex layout to ensure that the minimum height is not limited to
// screenHeight.
home: Column(children: [ home: Column(children: [
// Use Constrained to make max height not more than screenHeight // Use Constrained to make max height not more than screenHeight
ConstrainedBox( ConstrainedBox(
constraints: constraints: const BoxConstraints(
const BoxConstraints(maxHeight: screenHeight, maxWidth: screenWidth), maxHeight: screenHeight, maxWidth: screenWidth),
child: ScrollablePositionedList.builder( child: ScrollablePositionedList.builder(
itemCount: itemCount, itemCount: itemCount,
initialScrollIndex: initialIndex, initialScrollIndex: initialIndex,