Unverified Commit d672d20f authored by Yegor's avatar Yegor Committed by GitHub

fix draggable_scrollable_sheet_test.dart (#90204)

parent 39513f32
...@@ -113,467 +113,461 @@ void main() { ...@@ -113,467 +113,461 @@ void main() {
expect(tester.takeException(), isAssertionError); expect(tester.takeException(), isAssertionError);
}); });
for (final TargetPlatform platform in TargetPlatform.values) { group('Scroll Physics', () {
group('$platform Scroll Physics', () { testWidgets('Can be dragged up without covering its container', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = platform; int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
testWidgets('Can be dragged up without covering its container', (WidgetTester tester) async {
int taps = 0; expect(find.text('TapHere'), findsOneWidget);
await tester.pumpWidget(_boilerplate(() => taps++)); await tester.tap(find.text('TapHere'));
expect(taps, 1);
expect(find.text('TapHere'), findsOneWidget); expect(find.text('Item 1'), findsOneWidget);
await tester.tap(find.text('TapHere')); expect(find.text('Item 21'), findsOneWidget);
expect(taps, 1); expect(find.text('Item 31'), findsNothing);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget); await tester.drag(find.text('Item 1'), const Offset(0, -200));
expect(find.text('Item 31'), findsNothing); await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.drag(find.text('Item 1'), const Offset(0, -200)); await tester.tap(find.text('TapHere'));
await tester.pumpAndSettle(); expect(taps, 2);
expect(find.text('TapHere'), findsOneWidget); expect(find.text('Item 1'), findsOneWidget);
await tester.tap(find.text('TapHere')); expect(find.text('Item 21'), findsOneWidget);
expect(taps, 2); expect(find.text('Item 31'), findsOneWidget);
expect(find.text('Item 1'), findsOneWidget); }, variant: TargetPlatformVariant.all());
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 31'), findsOneWidget);
}, variant: TargetPlatformVariant.all());
testWidgets('Can be dragged down when not full height', (WidgetTester tester) async {
await tester.pumpWidget(_boilerplate(null));
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 36'), findsNothing);
await tester.drag(find.text('Item 1'), const Offset(0, 325));
await tester.pumpAndSettle();
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 36'), findsNothing);
}, variant: TargetPlatformVariant.all());
testWidgets('Can be dragged down when list is shorter than full height', (WidgetTester tester) async {
await tester.pumpWidget(_boilerplate(null, itemCount: 30, initialChildSize: .25));
expect(find.text('Item 1').hitTestable(), findsOneWidget);
expect(find.text('Item 29').hitTestable(), findsNothing);
await tester.drag(find.text('Item 1'), const Offset(0, -325)); testWidgets('Can be dragged down when not full height', (WidgetTester tester) async {
await tester.pumpAndSettle(); await tester.pumpWidget(_boilerplate(null));
expect(find.text('Item 1').hitTestable(), findsOneWidget); expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 29').hitTestable(), findsOneWidget); expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 36'), findsNothing);
await tester.drag(find.text('Item 1'), const Offset(0, 325)); await tester.drag(find.text('Item 1'), const Offset(0, 325));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Item 1').hitTestable(), findsOneWidget); expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 29').hitTestable(), findsNothing); expect(find.text('Item 21'), findsNothing);
}, variant: TargetPlatformVariant.all()); expect(find.text('Item 36'), findsNothing);
}, variant: TargetPlatformVariant.all());
testWidgets('Can be dragged up and cover its container and scroll in single motion, and then dragged back down', (WidgetTester tester) async {
int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 36'), findsNothing);
await tester.drag(find.text('Item 1'), const Offset(0, -325));
await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'), warnIfMissed: false);
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 36'), findsOneWidget);
await tester.dragFrom(const Offset(20, 20), const Offset(0, 325));
await tester.pumpAndSettle();
await tester.tap(find.text('TapHere'));
expect(taps, 2);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 18'), findsOneWidget);
expect(find.text('Item 36'), findsNothing);
}, variant: TargetPlatformVariant.all());
testWidgets('Can be flung up gently', (WidgetTester tester) async {
int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 36'), findsNothing);
expect(find.text('Item 70'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, -200), 350);
await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 2);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 36'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
}, variant: TargetPlatformVariant.all());
testWidgets('Can be flung up', (WidgetTester tester) async {
int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, -200), 2000);
await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'), warnIfMissed: false);
expect(taps, 1);
expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 70'), findsOneWidget);
}, variant: TargetPlatformVariant.all());
testWidgets('Can be flung down when not full height', (WidgetTester tester) async {
await tester.pumpWidget(_boilerplate(null));
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 36'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, 325), 2000);
await tester.pumpAndSettle();
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 36'), findsNothing);
}, variant: TargetPlatformVariant.all());
testWidgets('Can be flung up and then back down', (WidgetTester tester) async {
int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, -200), 2000);
await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'), warnIfMissed: false);
expect(taps, 1);
expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 70'), findsOneWidget);
await tester.fling(find.text('Item 70'), const Offset(0, 200), 2000);
await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'), warnIfMissed: false);
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, 200), 2000);
await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 2);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 70'), findsNothing);
}, variant: TargetPlatformVariant.all());
testWidgets('Ballistic animation on fling can be interrupted', (WidgetTester tester) async {
int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 31'), findsNothing);
expect(find.text('Item 70'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, -200), 2000);
// Don't pump and settle because we want to interrupt the ballistic scrolling animation.
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'), warnIfMissed: false);
expect(taps, 2);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 31'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
// Use `dragFrom` here because calling `drag` on a list item without
// first calling `pumpAndSettle` fails with a hit test error.
await tester.dragFrom(const Offset(0, 200), const Offset(0, 200));
await tester.pumpAndSettle();
// Verify that the ballistic animation has canceled and the sheet has testWidgets('Can be dragged down when list is shorter than full height', (WidgetTester tester) async {
// returned to it's original position. await tester.pumpWidget(_boilerplate(null, itemCount: 30, initialChildSize: .25));
await tester.tap(find.text('TapHere'));
expect(taps, 3);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 31'), findsNothing);
expect(find.text('Item 70'), findsNothing);
}, variant: TargetPlatformVariant.all());
debugDefaultTargetPlatformOverride = null; expect(find.text('Item 1').hitTestable(), findsOneWidget);
}); expect(find.text('Item 29').hitTestable(), findsNothing);
testWidgets('Does not snap away from initial child on build', (WidgetTester tester) async { await tester.drag(find.text('Item 1'), const Offset(0, -325));
const Key containerKey = ValueKey<String>('container');
const Key stackKey = ValueKey<String>('stack');
await tester.pumpWidget(_boilerplate(null,
snap: true,
initialChildSize: .7,
containerKey: containerKey,
stackKey: stackKey,
));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height; expect(find.text('Item 1').hitTestable(), findsOneWidget);
expect(find.text('Item 29').hitTestable(), findsOneWidget);
// The sheet should not have snapped. await tester.drag(find.text('Item 1'), const Offset(0, 325));
expect( await tester.pumpAndSettle();
tester.getSize(find.byKey(containerKey)).height / screenHeight, expect(find.text('Item 1').hitTestable(), findsOneWidget);
closeTo(.7, precisionErrorTolerance, expect(find.text('Item 29').hitTestable(), findsNothing);
));
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
testWidgets('Does not snap away from initial child on reset', (WidgetTester tester) async { testWidgets('Can be dragged up and cover its container and scroll in single motion, and then dragged back down', (WidgetTester tester) async {
const Key containerKey = ValueKey<String>('container'); int taps = 0;
const Key stackKey = ValueKey<String>('stack'); await tester.pumpWidget(_boilerplate(() => taps++));
await tester.pumpWidget(_boilerplate(null,
snap: true,
containerKey: containerKey,
stackKey: stackKey,
));
await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
await tester.drag(find.text('Item 1'), Offset(0, -.4 * screenHeight)); expect(find.text('TapHere'), findsOneWidget);
await tester.pumpAndSettle(); await tester.tap(find.text('TapHere'));
expect( expect(taps, 1);
tester.getSize(find.byKey(containerKey)).height / screenHeight, expect(find.text('Item 1'), findsOneWidget);
closeTo(1.0, precisionErrorTolerance), expect(find.text('Item 21'), findsOneWidget);
); expect(find.text('Item 36'), findsNothing);
DraggableScrollableActuator.reset(tester.element(find.byKey(containerKey))); await tester.drag(find.text('Item 1'), const Offset(0, -325));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
// The sheet should have reset without snapping away from initial child. await tester.tap(find.text('TapHere'), warnIfMissed: false);
expect( expect(taps, 1);
tester.getSize(find.byKey(containerKey)).height / screenHeight, expect(find.text('Item 1'), findsOneWidget);
closeTo(.5, precisionErrorTolerance), expect(find.text('Item 21'), findsOneWidget);
); expect(find.text('Item 36'), findsOneWidget);
await tester.dragFrom(const Offset(20, 20), const Offset(0, 325));
await tester.pumpAndSettle();
await tester.tap(find.text('TapHere'));
expect(taps, 2);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 18'), findsOneWidget);
expect(find.text('Item 36'), findsNothing);
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
testWidgets('Zero velocity drag snaps to nearest snap target', (WidgetTester tester) async { testWidgets('Can be flung up gently', (WidgetTester tester) async {
const Key stackKey = ValueKey<String>('stack'); int taps = 0;
const Key containerKey = ValueKey<String>('container'); await tester.pumpWidget(_boilerplate(() => taps++));
await tester.pumpWidget(_boilerplate(null,
snap: true,
stackKey: stackKey,
containerKey: containerKey,
snapSizes: <double>[.25, .5, .75, 1.0],
));
await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
// We are dragging up, but we'll snap down because we're closer to .75 than 1. expect(find.text('TapHere'), findsOneWidget);
await tester.drag(find.text('Item 1'), Offset(0, -.35 * screenHeight)); await tester.tap(find.text('TapHere'));
await tester.pumpAndSettle(); expect(taps, 1);
expect( expect(find.text('Item 1'), findsOneWidget);
tester.getSize(find.byKey(containerKey)).height / screenHeight, expect(find.text('Item 21'), findsOneWidget);
closeTo(.75, precisionErrorTolerance), expect(find.text('Item 36'), findsNothing);
); expect(find.text('Item 70'), findsNothing);
// Drag up and snap up. await tester.fling(find.text('Item 1'), const Offset(0, -200), 350);
await tester.drag(find.text('Item 1'), Offset(0, -.2 * screenHeight));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect( expect(find.text('TapHere'), findsOneWidget);
tester.getSize(find.byKey(containerKey)).height / screenHeight, await tester.tap(find.text('TapHere'));
closeTo(1.0, precisionErrorTolerance), expect(taps, 2);
); expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 36'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
}, variant: TargetPlatformVariant.all());
// Drag down and snap up. testWidgets('Can be flung up', (WidgetTester tester) async {
await tester.drag(find.text('Item 1'), Offset(0, .1 * screenHeight)); int taps = 0;
await tester.pumpAndSettle(); await tester.pumpWidget(_boilerplate(() => taps++));
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(1.0, precisionErrorTolerance),
);
// Drag down and snap down. expect(find.text('TapHere'), findsOneWidget);
await tester.drag(find.text('Item 1'), Offset(0, .45 * screenHeight)); await tester.tap(find.text('TapHere'));
await tester.pumpAndSettle(); expect(taps, 1);
expect( expect(find.text('Item 1'), findsOneWidget);
tester.getSize(find.byKey(containerKey)).height / screenHeight, expect(find.text('Item 21'), findsOneWidget);
closeTo(.5, precisionErrorTolerance), expect(find.text('Item 70'), findsNothing);
);
// Fling up with negligible velocity and snap down. await tester.fling(find.text('Item 1'), const Offset(0, -200), 2000);
await tester.fling(find.text('Item 1'), Offset(0, .1 * screenHeight), 1);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect( expect(find.text('TapHere'), findsOneWidget);
tester.getSize(find.byKey(containerKey)).height / screenHeight, await tester.tap(find.text('TapHere'), warnIfMissed: false);
closeTo(.5, precisionErrorTolerance), expect(taps, 1);
); expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 70'), findsOneWidget);
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
for (final List<double>? snapSizes in <List<double>?>[null, <double>[]]) { testWidgets('Can be flung down when not full height', (WidgetTester tester) async {
testWidgets('Setting snapSizes to $snapSizes resolves to min and max', (WidgetTester tester) async { await tester.pumpWidget(_boilerplate(null));
const Key stackKey = ValueKey<String>('stack'); expect(find.text('Item 1'), findsOneWidget);
const Key containerKey = ValueKey<String>('container'); expect(find.text('Item 21'), findsOneWidget);
await tester.pumpWidget(_boilerplate(null, expect(find.text('Item 36'), findsNothing);
snap: true,
stackKey: stackKey, await tester.fling(find.text('Item 1'), const Offset(0, 325), 2000);
containerKey: containerKey,
snapSizes: snapSizes,
));
await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
await tester.drag(find.text('Item 1'), Offset(0, -.4 * screenHeight));
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(1.0, precisionErrorTolerance,
));
await tester.drag(find.text('Item 1'), Offset(0, .7 * screenHeight));
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.25, precisionErrorTolerance),
);
}, variant: TargetPlatformVariant.all());
}
testWidgets('Min and max are implicitly added to snapSizes.', (WidgetTester tester) async {
const Key stackKey = ValueKey<String>('stack');
const Key containerKey = ValueKey<String>('container');
await tester.pumpWidget(_boilerplate(null,
snap: true,
stackKey: stackKey,
containerKey: containerKey,
snapSizes: <double>[.5],
));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height; expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 36'), findsNothing);
}, variant: TargetPlatformVariant.all());
testWidgets('Can be flung up and then back down', (WidgetTester tester) async {
int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
await tester.drag(find.text('Item 1'), Offset(0, -.4 * screenHeight)); expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, -200), 2000);
await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'), warnIfMissed: false);
expect(taps, 1);
expect(find.text('Item 1'), findsNothing);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 70'), findsOneWidget);
await tester.fling(find.text('Item 70'), const Offset(0, 200), 2000);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect( expect(find.text('TapHere'), findsOneWidget);
tester.getSize(find.byKey(containerKey)).height / screenHeight, await tester.tap(find.text('TapHere'), warnIfMissed: false);
closeTo(1.0, precisionErrorTolerance), expect(taps, 1);
); expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, 200), 2000);
await tester.pumpAndSettle();
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 2);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 21'), findsNothing);
expect(find.text('Item 70'), findsNothing);
}, variant: TargetPlatformVariant.all());
await tester.drag(find.text('Item 1'), Offset(0, .7 * screenHeight)); testWidgets('Ballistic animation on fling can be interrupted', (WidgetTester tester) async {
int taps = 0;
await tester.pumpWidget(_boilerplate(() => taps++));
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'));
expect(taps, 1);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 31'), findsNothing);
expect(find.text('Item 70'), findsNothing);
await tester.fling(find.text('Item 1'), const Offset(0, -200), 2000);
// Don't pump and settle because we want to interrupt the ballistic scrolling animation.
expect(find.text('TapHere'), findsOneWidget);
await tester.tap(find.text('TapHere'), warnIfMissed: false);
expect(taps, 2);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 31'), findsOneWidget);
expect(find.text('Item 70'), findsNothing);
// Use `dragFrom` here because calling `drag` on a list item without
// first calling `pumpAndSettle` fails with a hit test error.
await tester.dragFrom(const Offset(0, 200), const Offset(0, 200));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight, // Verify that the ballistic animation has canceled and the sheet has
closeTo(.25, precisionErrorTolerance), // returned to it's original position.
); await tester.tap(find.text('TapHere'));
expect(taps, 3);
expect(find.text('Item 1'), findsOneWidget);
expect(find.text('Item 31'), findsNothing);
expect(find.text('Item 70'), findsNothing);
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
});
testWidgets('Does not snap away from initial child on build', (WidgetTester tester) async {
const Key containerKey = ValueKey<String>('container');
const Key stackKey = ValueKey<String>('stack');
await tester.pumpWidget(_boilerplate(null,
snap: true,
initialChildSize: .7,
containerKey: containerKey,
stackKey: stackKey,
));
await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
// The sheet should not have snapped.
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.7, precisionErrorTolerance,
));
}, variant: TargetPlatformVariant.all());
testWidgets('Does not snap away from initial child on reset', (WidgetTester tester) async {
const Key containerKey = ValueKey<String>('container');
const Key stackKey = ValueKey<String>('stack');
await tester.pumpWidget(_boilerplate(null,
snap: true,
containerKey: containerKey,
stackKey: stackKey,
));
await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
await tester.drag(find.text('Item 1'), Offset(0, -.4 * screenHeight));
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(1.0, precisionErrorTolerance),
);
DraggableScrollableActuator.reset(tester.element(find.byKey(containerKey)));
await tester.pumpAndSettle();
// The sheet should have reset without snapping away from initial child.
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.5, precisionErrorTolerance),
);
}, variant: TargetPlatformVariant.all());
testWidgets('Zero velocity drag snaps to nearest snap target', (WidgetTester tester) async {
const Key stackKey = ValueKey<String>('stack');
const Key containerKey = ValueKey<String>('container');
await tester.pumpWidget(_boilerplate(null,
snap: true,
stackKey: stackKey,
containerKey: containerKey,
snapSizes: <double>[.25, .5, .75, 1.0],
));
await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
// We are dragging up, but we'll snap down because we're closer to .75 than 1.
await tester.drag(find.text('Item 1'), Offset(0, -.35 * screenHeight));
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.75, precisionErrorTolerance),
);
// Drag up and snap up.
await tester.drag(find.text('Item 1'), Offset(0, -.2 * screenHeight));
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(1.0, precisionErrorTolerance),
);
// Drag down and snap up.
await tester.drag(find.text('Item 1'), Offset(0, .1 * screenHeight));
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(1.0, precisionErrorTolerance),
);
// Drag down and snap down.
await tester.drag(find.text('Item 1'), Offset(0, .45 * screenHeight));
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.5, precisionErrorTolerance),
);
// Fling up with negligible velocity and snap down.
await tester.fling(find.text('Item 1'), Offset(0, .1 * screenHeight), 1);
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.5, precisionErrorTolerance),
);
}, variant: TargetPlatformVariant.all());
testWidgets('Fling snaps in direction of momentum', (WidgetTester tester) async { for (final List<double>? snapSizes in <List<double>?>[null, <double>[]]) {
testWidgets('Setting snapSizes to $snapSizes resolves to min and max', (WidgetTester tester) async {
const Key stackKey = ValueKey<String>('stack'); const Key stackKey = ValueKey<String>('stack');
const Key containerKey = ValueKey<String>('container'); const Key containerKey = ValueKey<String>('container');
await tester.pumpWidget(_boilerplate(null, await tester.pumpWidget(_boilerplate(null,
snap: true, snap: true,
stackKey: stackKey, stackKey: stackKey,
containerKey: containerKey, containerKey: containerKey,
snapSizes: <double>[.5, .75], snapSizes: snapSizes,
)); ));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height; final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
await tester.fling(find.text('Item 1'), Offset(0, -.1 * screenHeight), 1000);
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.75, precisionErrorTolerance),
);
await tester.fling(find.text('Item 1'), Offset(0, .3 * screenHeight), 1000); await tester.drag(find.text('Item 1'), Offset(0, -.4 * screenHeight));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect( expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight, tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.25, precisionErrorTolerance), closeTo(1.0, precisionErrorTolerance,
); ));
await tester.drag(find.text('Item 1'), Offset(0, .7 * screenHeight));
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.25, precisionErrorTolerance),
);
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
}
testWidgets('ScrollNotification correctly dispatched when flung without covering its container', (WidgetTester tester) async { testWidgets('Min and max are implicitly added to snapSizes.', (WidgetTester tester) async {
final List<Type> notificationTypes = <Type>[]; const Key stackKey = ValueKey<String>('stack');
await tester.pumpWidget(_boilerplate( const Key containerKey = ValueKey<String>('container');
null, await tester.pumpWidget(_boilerplate(null,
onScrollNotification: (ScrollNotification notification) { snap: true,
notificationTypes.add(notification.runtimeType); stackKey: stackKey,
return false; containerKey: containerKey,
}, snapSizes: <double>[.5],
)); ));
await tester.pumpAndSettle();
await tester.fling(find.text('Item 1'), const Offset(0, -200), 200); final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
await tester.pumpAndSettle();
// TODO(itome): Make sure UserScrollNotification and ScrollUpdateNotification are called correctly. await tester.drag(find.text('Item 1'), Offset(0, -.4 * screenHeight));
final List<Type> types = <Type>[ await tester.pumpAndSettle();
ScrollStartNotification, expect(
ScrollEndNotification, tester.getSize(find.byKey(containerKey)).height / screenHeight,
]; closeTo(1.0, precisionErrorTolerance),
expect(notificationTypes, equals(types)); );
});
testWidgets('ScrollNotification correctly dispatched when flung with contents scroll', (WidgetTester tester) async {
final List<Type> notificationTypes = <Type>[];
await tester.pumpWidget(_boilerplate(
null,
onScrollNotification: (ScrollNotification notification) {
notificationTypes.add(notification.runtimeType);
return false;
},
));
await tester.flingFrom(const Offset(0, 325), const Offset(0, -325), 200);
await tester.pumpAndSettle();
final List<Type> types = <Type>[ await tester.drag(find.text('Item 1'), Offset(0, .7 * screenHeight));
ScrollStartNotification, await tester.pumpAndSettle();
UserScrollNotification, expect(
...List<Type>.filled(5, ScrollUpdateNotification), tester.getSize(find.byKey(containerKey)).height / screenHeight,
ScrollEndNotification, closeTo(.25, precisionErrorTolerance),
UserScrollNotification, );
]; }, variant: TargetPlatformVariant.all());
expect(notificationTypes, types);
}); testWidgets('Fling snaps in direction of momentum', (WidgetTester tester) async {
const Key stackKey = ValueKey<String>('stack');
testWidgets('Do not crash when remove the tree during animation.', (WidgetTester tester) async { const Key containerKey = ValueKey<String>('container');
// Regression test for https://github.com/flutter/flutter/issues/89214 await tester.pumpWidget(_boilerplate(null,
await tester.pumpWidget(_boilerplate( snap: true,
null, stackKey: stackKey,
onScrollNotification: (ScrollNotification notification) { containerKey: containerKey,
return false; snapSizes: <double>[.5, .75],
}, ));
)); await tester.pumpAndSettle();
final double screenHeight = tester.getSize(find.byKey(stackKey)).height;
await tester.flingFrom(const Offset(0, 325), const Offset(0, 325), 200);
await tester.fling(find.text('Item 1'), Offset(0, -.1 * screenHeight), 1000);
// The animation is running. await tester.pumpAndSettle();
expect(
await tester.pumpWidget(const SizedBox.shrink()); tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.75, precisionErrorTolerance),
expect(tester.takeException(), isNull); );
});
} await tester.fling(find.text('Item 1'), Offset(0, .3 * screenHeight), 1000);
await tester.pumpAndSettle();
expect(
tester.getSize(find.byKey(containerKey)).height / screenHeight,
closeTo(.25, precisionErrorTolerance),
);
}, variant: TargetPlatformVariant.all());
testWidgets('ScrollNotification correctly dispatched when flung without covering its container', (WidgetTester tester) async {
final List<Type> notificationTypes = <Type>[];
await tester.pumpWidget(_boilerplate(
null,
onScrollNotification: (ScrollNotification notification) {
notificationTypes.add(notification.runtimeType);
return false;
},
));
await tester.fling(find.text('Item 1'), const Offset(0, -200), 200);
await tester.pumpAndSettle();
// TODO(itome): Make sure UserScrollNotification and ScrollUpdateNotification are called correctly.
final List<Type> types = <Type>[
ScrollStartNotification,
ScrollEndNotification,
];
expect(notificationTypes, equals(types));
});
testWidgets('ScrollNotification correctly dispatched when flung with contents scroll', (WidgetTester tester) async {
final List<Type> notificationTypes = <Type>[];
await tester.pumpWidget(_boilerplate(
null,
onScrollNotification: (ScrollNotification notification) {
notificationTypes.add(notification.runtimeType);
return false;
},
));
await tester.flingFrom(const Offset(0, 325), const Offset(0, -325), 200);
await tester.pumpAndSettle();
final List<Type> types = <Type>[
ScrollStartNotification,
UserScrollNotification,
...List<Type>.filled(5, ScrollUpdateNotification),
ScrollEndNotification,
UserScrollNotification,
];
expect(notificationTypes, types);
});
testWidgets('Do not crash when remove the tree during animation.', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/89214
await tester.pumpWidget(_boilerplate(
null,
onScrollNotification: (ScrollNotification notification) {
return false;
},
));
await tester.flingFrom(const Offset(0, 325), const Offset(0, 325), 200);
// The animation is running.
await tester.pumpWidget(const SizedBox.shrink());
expect(tester.takeException(), isNull);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment