diff --git a/packages/flutter/lib/src/rendering/sliver.dart b/packages/flutter/lib/src/rendering/sliver.dart index 505be9347b3..393c9cf18a7 100644 --- a/packages/flutter/lib/src/rendering/sliver.dart +++ b/packages/flutter/lib/src/rendering/sliver.dart @@ -1117,7 +1117,7 @@ abstract class RenderAbstractViewport implements RenderObject { return null; } - double getOffsetToReveal(RenderObject descendant, double alignment); + double getOffsetToReveal(RenderObject target, double alignment); } // /// @@ -1339,9 +1339,83 @@ abstract class RenderViewportBase2 find.byKey(new ValueKey(i)); @@ -34,125 +35,402 @@ Widget buildSingleChildScrollView(Axis scrollDirection, { bool reverse: false }) ); } +Widget buildListView(Axis scrollDirection, { bool reverse: false, bool shrinkWrap: false }) { + return new Center( + child: new SizedBox( + width: 600.0, + height: 400.0, + child: new ListView( + scrollDirection: scrollDirection, + reverse: reverse, + shrinkWrap: shrinkWrap, + children: [ + new Container(key: new ValueKey(0), width: 200.0, height: 200.0), + new Container(key: new ValueKey(1), width: 200.0, height: 200.0), + new Container(key: new ValueKey(2), width: 200.0, height: 200.0), + new Container(key: new ValueKey(3), width: 200.0, height: 200.0), + new Container(key: new ValueKey(4), width: 200.0, height: 200.0), + new Container(key: new ValueKey(5), width: 200.0, height: 200.0), + new Container(key: new ValueKey(6), width: 200.0, height: 200.0), + ], + ), + ), + ); +} + void main() { - testWidgets('SingleChildScollView ensureVisible Axis.vertical', (WidgetTester tester) async { - BuildContext findContext(int i) => tester.element(findKey(i)); - await tester.pumpWidget(buildSingleChildScrollView(Axis.vertical)); + group('SingleChildScollView', () { + testWidgets('SingleChildScollView ensureVisible Axis.vertical', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); - Scrollable2.ensureVisible(findContext(3)); - await tester.pump(); - expect(tester.getTopLeft(findKey(3)).y, equals(100.0)); + await tester.pumpWidget(buildSingleChildScrollView(Axis.vertical)); - Scrollable2.ensureVisible(findContext(6)); - await tester.pump(); - expect(tester.getTopLeft(findKey(6)).y, equals(300.0)); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getTopLeft(findKey(3)).y, equals(100.0)); - Scrollable2.ensureVisible(findContext(4), alignment: 1.0); - await tester.pump(); - expect(tester.getBottomRight(findKey(4)).y, equals(500.0)); + Scrollable2.ensureVisible(findContext(6)); + await tester.pump(); + expect(tester.getTopLeft(findKey(6)).y, equals(300.0)); - Scrollable2.ensureVisible(findContext(0), alignment: 1.0); - await tester.pump(); - expect(tester.getTopLeft(findKey(0)).y, equals(100.0)); + Scrollable2.ensureVisible(findContext(4), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(4)).y, equals(500.0)); - Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); - await tester.pump(); - await tester.pump(const Duration(milliseconds: 1020)); - expect(tester.getTopLeft(findKey(3)).y, equals(100.0)); + Scrollable2.ensureVisible(findContext(0), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(0)).y, equals(100.0)); + + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getTopLeft(findKey(3)).y, equals(100.0)); + }); + + testWidgets('SingleChildScollView ensureVisible Axis.horizontal', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + + await tester.pumpWidget(buildSingleChildScrollView(Axis.horizontal)); + + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getTopLeft(findKey(3)).x, equals(100.0)); + + Scrollable2.ensureVisible(findContext(6)); + await tester.pump(); + expect(tester.getTopLeft(findKey(6)).x, equals(500.0)); + + Scrollable2.ensureVisible(findContext(4), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(4)).x, equals(700.0)); + + Scrollable2.ensureVisible(findContext(0), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(0)).x, equals(100.0)); + + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getTopLeft(findKey(3)).x, equals(100.0)); + }); + + testWidgets('SingleChildScollView ensureVisible Axis.vertical reverse', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + + await tester.pumpWidget(buildSingleChildScrollView(Axis.vertical, reverse: true)); + + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getBottomRight(findKey(3)).y, equals(500.0)); + + Scrollable2.ensureVisible(findContext(0)); + await tester.pump(); + expect(tester.getBottomRight(findKey(0)).y, equals(300.0)); + + Scrollable2.ensureVisible(findContext(2), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(2)).y, equals(100.0)); + + Scrollable2.ensureVisible(findContext(6), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(6)).y, equals(500.0)); + + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getBottomRight(findKey(3)).y, equals(500.0)); + }); + + testWidgets('SingleChildScollView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + + await tester.pumpWidget(buildSingleChildScrollView(Axis.horizontal, reverse: true)); + + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getBottomRight(findKey(3)).x, equals(700.0)); + + Scrollable2.ensureVisible(findContext(0)); + await tester.pump(); + expect(tester.getBottomRight(findKey(0)).x, equals(300.0)); + + Scrollable2.ensureVisible(findContext(2), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(2)).x, equals(100.0)); + + Scrollable2.ensureVisible(findContext(6), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(6)).x, equals(700.0)); + + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getBottomRight(findKey(3)).x, equals(700.0)); + }); + + testWidgets('SingleChildScollView ensureVisible rotated child', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + + await tester.pumpWidget( + new Center( + child: new SizedBox( + width: 600.0, + height: 400.0, + child: new SingleChildScrollView( + child: new BlockBody( + children: [ + new Container(height: 200.0), + new Container(height: 200.0), + new Container(height: 200.0), + new Container( + height: 200.0, + child: new Center( + child: new Transform( + transform: new Matrix4.rotationZ(math.PI), + child: new Container( + key: new ValueKey(0), + width: 100.0, + height: 100.0, + decoration: const BoxDecoration( + backgroundColor: const Color(0xFFFFFFFF), + ), + ), + ), + ), + ), + new Container(height: 200.0), + new Container(height: 200.0), + new Container(height: 200.0), + ], + ), + ), + ), + ) + ); + + Scrollable2.ensureVisible(findContext(0)); + await tester.pump(); + expect(tester.getBottomRight(findKey(0)).y, closeTo(100.0, 0.1)); + + Scrollable2.ensureVisible(findContext(0), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(0)).y, closeTo(500.0, 0.1)); + }); }); - testWidgets('SingleChildScollView ensureVisible Axis.horizontal', (WidgetTester tester) async { - BuildContext findContext(int i) => tester.element(findKey(i)); + group('ListView', () { + testWidgets('ListView ensureVisible Axis.vertical', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } - await tester.pumpWidget(buildSingleChildScrollView(Axis.horizontal)); + await tester.pumpWidget(buildListView(Axis.vertical)); - Scrollable2.ensureVisible(findContext(3)); - await tester.pump(); - expect(tester.getTopLeft(findKey(3)).x, equals(100.0)); + await prepare(480.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getTopLeft(findKey(3)).y, equals(100.0)); - Scrollable2.ensureVisible(findContext(6)); - await tester.pump(); - expect(tester.getTopLeft(findKey(6)).x, equals(500.0)); + await prepare(1083.0); + Scrollable2.ensureVisible(findContext(6)); + await tester.pump(); + expect(tester.getTopLeft(findKey(6)).y, equals(300.0)); - Scrollable2.ensureVisible(findContext(4), alignment: 1.0); - await tester.pump(); - expect(tester.getBottomRight(findKey(4)).x, equals(700.0)); + await prepare(735.0); + Scrollable2.ensureVisible(findContext(4), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(4)).y, equals(500.0)); - Scrollable2.ensureVisible(findContext(0), alignment: 1.0); - await tester.pump(); - expect(tester.getTopLeft(findKey(0)).x, equals(100.0)); + await prepare(123.0); + Scrollable2.ensureVisible(findContext(0), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(0)).y, equals(100.0)); - Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); - await tester.pump(); - await tester.pump(const Duration(milliseconds: 1020)); - expect(tester.getTopLeft(findKey(3)).x, equals(100.0)); - }); + await prepare(523.0); + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getTopLeft(findKey(3)).y, equals(100.0)); + }); - testWidgets('SingleChildScollView ensureVisible Axis.vertical reverse', (WidgetTester tester) async { - BuildContext findContext(int i) => tester.element(findKey(i)); + testWidgets('ListView ensureVisible Axis.horizontal', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } - await tester.pumpWidget(buildSingleChildScrollView(Axis.vertical, reverse: true)); + await tester.pumpWidget(buildListView(Axis.horizontal)); - Scrollable2.ensureVisible(findContext(3)); - await tester.pump(); - expect(tester.getBottomRight(findKey(3)).y, equals(500.0)); + await prepare(23.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getTopLeft(findKey(3)).x, equals(100.0)); - Scrollable2.ensureVisible(findContext(0)); - await tester.pump(); - expect(tester.getBottomRight(findKey(0)).y, equals(300.0)); + await prepare(843.0); + Scrollable2.ensureVisible(findContext(6)); + await tester.pump(); + expect(tester.getTopLeft(findKey(6)).x, equals(500.0)); - Scrollable2.ensureVisible(findContext(2), alignment: 1.0); - await tester.pump(); - expect(tester.getTopLeft(findKey(2)).y, equals(100.0)); + await prepare(415.0); + Scrollable2.ensureVisible(findContext(4), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(4)).x, equals(700.0)); - Scrollable2.ensureVisible(findContext(6), alignment: 1.0); - await tester.pump(); - expect(tester.getBottomRight(findKey(6)).y, equals(500.0)); + await prepare(46.0); + Scrollable2.ensureVisible(findContext(0), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(0)).x, equals(100.0)); - Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); - await tester.pump(); - await tester.pump(const Duration(milliseconds: 1020)); - expect(tester.getBottomRight(findKey(3)).y, equals(500.0)); - }); + await prepare(211.0); + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getTopLeft(findKey(3)).x, equals(100.0)); + }); - testWidgets('SingleChildScollView ensureVisible Axis.horizontal', (WidgetTester tester) async { - BuildContext findContext(int i) => tester.element(findKey(i)); + testWidgets('ListView ensureVisible Axis.vertical reverse', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } - await tester.pumpWidget(buildSingleChildScrollView(Axis.horizontal, reverse: true)); + await tester.pumpWidget(buildListView(Axis.vertical, reverse: true)); - Scrollable2.ensureVisible(findContext(3)); - await tester.pump(); - expect(tester.getBottomRight(findKey(3)).x, equals(700.0)); + await prepare(211.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getBottomRight(findKey(3)).y, equals(500.0)); - Scrollable2.ensureVisible(findContext(0)); - await tester.pump(); - expect(tester.getBottomRight(findKey(0)).x, equals(300.0)); + await prepare(23.0); + Scrollable2.ensureVisible(findContext(0)); + await tester.pump(); + expect(tester.getBottomRight(findKey(0)).y, equals(500.0)); - Scrollable2.ensureVisible(findContext(2), alignment: 1.0); - await tester.pump(); - expect(tester.getTopLeft(findKey(2)).x, equals(100.0)); + await prepare(230.0); + Scrollable2.ensureVisible(findContext(2), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(2)).y, equals(100.0)); - Scrollable2.ensureVisible(findContext(6), alignment: 1.0); - await tester.pump(); - expect(tester.getBottomRight(findKey(6)).x, equals(700.0)); + await prepare(1083.0); + Scrollable2.ensureVisible(findContext(6), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(6)).y, equals(300.0)); - Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); - await tester.pump(); - await tester.pump(const Duration(milliseconds: 1020)); - expect(tester.getBottomRight(findKey(3)).x, equals(700.0)); - }); + await prepare(345.0); + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getBottomRight(findKey(3)).y, equals(500.0)); + }); - testWidgets('SingleChildScollView ensureVisible rotated child', (WidgetTester tester) async { - BuildContext findContext(int i) => tester.element(findKey(i)); + testWidgets('ListView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } - await tester.pumpWidget( - new Center( + await tester.pumpWidget(buildListView(Axis.horizontal, reverse: true)); + + await prepare(211.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getBottomRight(findKey(3)).x, equals(700.0)); + + await prepare(23.0); + Scrollable2.ensureVisible(findContext(0)); + await tester.pump(); + expect(tester.getBottomRight(findKey(0)).x, equals(700.0)); + + await prepare(230.0); + Scrollable2.ensureVisible(findContext(2), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(2)).x, equals(100.0)); + + await prepare(1083.0); + Scrollable2.ensureVisible(findContext(6), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(6)).x, equals(300.0)); + + await prepare(345.0); + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getBottomRight(findKey(3)).x, equals(700.0)); + }); + + // TODO(abarth): Unskip this test. See https://github.com/flutter/flutter/issues/7919 + testWidgets('ListView ensureVisible negative child', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } + + double getOffset() { + return tester.state(find.byType(Scrollable2)).position.pixels; + } + + Widget buildSliver(int i) { + return new SliverToBoxAdapter( + key: new ValueKey(i), + child: new Container(width: 200.0, height: 200.0), + ); + } + + await tester.pumpWidget(new Center( child: new SizedBox( width: 600.0, height: 400.0, - child: new SingleChildScrollView( - child: new BlockBody( + child: new Scrollable2( + viewportBuilder: (BuildContext context, ViewportOffset offset) { + return new Viewport2( + offset: offset, + center: new ValueKey(4), + slivers: [ + buildSliver(0), + buildSliver(1), + buildSliver(2), + buildSliver(3), + buildSliver(4), + buildSliver(5), + buildSliver(6), + ], + ); + }, + ), + ), + )); + + await prepare(-125.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(getOffset(), equals(-200.0)); + + await prepare(-225.0); + Scrollable2.ensureVisible(findContext(2)); + await tester.pump(); + expect(getOffset(), equals(-400.0)); + }, skip: true); + + testWidgets('ListView ensureVisible rotated child', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } + + await tester.pumpWidget( + new Center( + child: new SizedBox( + width: 600.0, + height: 400.0, + child: new ListView( children: [ new Container(height: 200.0), new Container(height: 200.0), @@ -179,17 +457,163 @@ void main() { ], ), ), - ), - ) - ); + ) + ); - Scrollable2.ensureVisible(findContext(0)); - await tester.pump(); - expect(tester.getBottomRight(findKey(0)).y, closeTo(100.0, 0.1)); + await prepare(321.0); + Scrollable2.ensureVisible(findContext(0)); + await tester.pump(); + expect(tester.getBottomRight(findKey(0)).y, closeTo(100.0, 0.1)); - Scrollable2.ensureVisible(findContext(0), alignment: 1.0); - await tester.pump(); - expect(tester.getTopLeft(findKey(0)).y, closeTo(500.0, 0.1)); + Scrollable2.ensureVisible(findContext(0), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(0)).y, closeTo(500.0, 0.1)); + }); }); + group('ListView shrinkWrap', () { + testWidgets('ListView ensureVisible Axis.vertical', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } + + await tester.pumpWidget(buildListView(Axis.vertical, shrinkWrap: true)); + + await prepare(480.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getTopLeft(findKey(3)).y, equals(100.0)); + + await prepare(1083.0); + Scrollable2.ensureVisible(findContext(6)); + await tester.pump(); + expect(tester.getTopLeft(findKey(6)).y, equals(300.0)); + + await prepare(735.0); + Scrollable2.ensureVisible(findContext(4), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(4)).y, equals(500.0)); + + await prepare(123.0); + Scrollable2.ensureVisible(findContext(0), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(0)).y, equals(100.0)); + + await prepare(523.0); + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getTopLeft(findKey(3)).y, equals(100.0)); + }); + + testWidgets('ListView ensureVisible Axis.horizontal', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } + + await tester.pumpWidget(buildListView(Axis.horizontal, shrinkWrap: true)); + + await prepare(23.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getTopLeft(findKey(3)).x, equals(100.0)); + + await prepare(843.0); + Scrollable2.ensureVisible(findContext(6)); + await tester.pump(); + expect(tester.getTopLeft(findKey(6)).x, equals(500.0)); + + await prepare(415.0); + Scrollable2.ensureVisible(findContext(4), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(4)).x, equals(700.0)); + + await prepare(46.0); + Scrollable2.ensureVisible(findContext(0), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(0)).x, equals(100.0)); + + await prepare(211.0); + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getTopLeft(findKey(3)).x, equals(100.0)); + }); + + testWidgets('ListView ensureVisible Axis.vertical reverse', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } + + await tester.pumpWidget(buildListView(Axis.vertical, reverse: true, shrinkWrap: true)); + + await prepare(211.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getBottomRight(findKey(3)).y, equals(500.0)); + + await prepare(23.0); + Scrollable2.ensureVisible(findContext(0)); + await tester.pump(); + expect(tester.getBottomRight(findKey(0)).y, equals(500.0)); + + await prepare(230.0); + Scrollable2.ensureVisible(findContext(2), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(2)).y, equals(100.0)); + + await prepare(1083.0); + Scrollable2.ensureVisible(findContext(6), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(6)).y, equals(300.0)); + + await prepare(345.0); + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getBottomRight(findKey(3)).y, equals(500.0)); + }); + + testWidgets('ListView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async { + BuildContext findContext(int i) => tester.element(findKey(i)); + Future prepare(double offset) async { + tester.state(find.byType(Scrollable2)).position.jumpTo(offset); + await tester.pump(); + } + + await tester.pumpWidget(buildListView(Axis.horizontal, reverse: true, shrinkWrap: true)); + + await prepare(211.0); + Scrollable2.ensureVisible(findContext(3)); + await tester.pump(); + expect(tester.getBottomRight(findKey(3)).x, equals(700.0)); + + await prepare(23.0); + Scrollable2.ensureVisible(findContext(0)); + await tester.pump(); + expect(tester.getBottomRight(findKey(0)).x, equals(700.0)); + + await prepare(230.0); + Scrollable2.ensureVisible(findContext(2), alignment: 1.0); + await tester.pump(); + expect(tester.getTopLeft(findKey(2)).x, equals(100.0)); + + await prepare(1083.0); + Scrollable2.ensureVisible(findContext(6), alignment: 1.0); + await tester.pump(); + expect(tester.getBottomRight(findKey(6)).x, equals(300.0)); + + await prepare(345.0); + Scrollable2.ensureVisible(findContext(3), duration: const Duration(seconds: 1)); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 1020)); + expect(tester.getBottomRight(findKey(3)).x, equals(700.0)); + }); + }); }