blob: 3692f456f66f803d8c2b63462cf73605f00d8f8f [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/gestures.dart' show DragStartBehavior;
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
const TextStyle testFont = TextStyle(
color: Color(0xFF00FF00),
fontFamily: 'Ahem',
);
Future<void> pumpTest(WidgetTester tester, TargetPlatform platform) async {
await tester.pumpWidget(Container());
await tester.pumpWidget(MaterialApp(
theme: ThemeData(
platform: platform,
),
home: Container(
color: const Color(0xFF111111),
child: ListView.builder(
dragStartBehavior: DragStartBehavior.down,
itemBuilder: (BuildContext context, int index) {
return Text('$index', style: testFont);
},
),
),
));
}
const double dragOffset = 213.82;
void main() {
testWidgets('Flings on different platforms', (WidgetTester tester) async {
double getCurrentOffset() {
return tester.state<ScrollableState>(find.byType(Scrollable)).position.pixels;
}
await pumpTest(tester, TargetPlatform.android);
await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
expect(getCurrentOffset(), dragOffset);
await tester.pump(); // trigger fling
expect(getCurrentOffset(), dragOffset);
await tester.pump(const Duration(seconds: 5));
final double androidResult = getCurrentOffset();
// Regression test for https://github.com/flutter/flutter/issues/83632
// Before changing these values, ensure the fling results in a distance that
// makes sense. See issue for more context.
expect(androidResult, greaterThan(394.0));
expect(androidResult, lessThan(395.0));
await pumpTest(tester, TargetPlatform.linux);
await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
expect(getCurrentOffset(), dragOffset);
await tester.pump(); // trigger fling
expect(getCurrentOffset(), dragOffset);
await tester.pump(const Duration(seconds: 5));
final double linuxResult = getCurrentOffset();
await pumpTest(tester, TargetPlatform.windows);
await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
expect(getCurrentOffset(), dragOffset);
await tester.pump(); // trigger fling
expect(getCurrentOffset(), dragOffset);
await tester.pump(const Duration(seconds: 5));
final double windowsResult = getCurrentOffset();
await pumpTest(tester, TargetPlatform.iOS);
await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
// Scroll starts ease into the scroll on iOS.
expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
await tester.pump(); // trigger fling
expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
await tester.pump(const Duration(seconds: 5));
final double iOSResult = getCurrentOffset();
await pumpTest(tester, TargetPlatform.macOS);
await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
// Scroll starts ease into the scroll on iOS.
expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
await tester.pump(); // trigger fling
expect(getCurrentOffset(), moreOrLessEquals(210.71026666666666));
await tester.pump(const Duration(seconds: 5));
final double macOSResult = getCurrentOffset();
expect(androidResult, lessThan(iOSResult)); // iOS is slipperier than Android
expect(macOSResult, lessThan(iOSResult)); // iOS is slipperier than macOS
expect(macOSResult, lessThan(androidResult)); // Android is slipperier than macOS
expect(linuxResult, lessThan(iOSResult)); // iOS is slipperier than Linux
expect(macOSResult, lessThan(linuxResult)); // Linux is slipperier than macOS
expect(windowsResult, lessThan(iOSResult)); // iOS is slipperier than Windows
expect(macOSResult, lessThan(windowsResult)); // Windows is slipperier than macOS
expect(windowsResult, equals(androidResult));
expect(windowsResult, equals(androidResult));
expect(linuxResult, equals(androidResult));
expect(linuxResult, equals(androidResult));
});
testWidgets('fling and tap to stop', (WidgetTester tester) async {
final List<String> log = <String>[];
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: ListView(
dragStartBehavior: DragStartBehavior.down,
children: List<Widget>.generate(250, (int i) => GestureDetector(
onTap: () { log.add('tap $i'); },
child: Text('$i', style: testFont),
)),
),
),
);
expect(log, equals(<String>[]));
await tester.tap(find.byType(Scrollable));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 21']));
await tester.fling(find.byType(Scrollable), const Offset(0.0, -200.0), 1000.0);
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 21']));
await tester.tap(find.byType(Scrollable)); // should stop the fling but not tap anything
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 21']));
await tester.tap(find.byType(Scrollable));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 21', 'tap 35']));
});
testWidgets('fling and wait and tap', (WidgetTester tester) async {
final List<String> log = <String>[];
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: ListView(
dragStartBehavior: DragStartBehavior.down,
children: List<Widget>.generate(250, (int i) => GestureDetector(
onTap: () { log.add('tap $i'); },
child: Text('$i', style: testFont),
)),
),
),
);
expect(log, equals(<String>[]));
await tester.tap(find.byType(Scrollable));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 21']));
await tester.fling(find.byType(Scrollable), const Offset(0.0, -200.0), 1000.0);
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 21']));
await tester.pump(const Duration(seconds: 50)); // long wait, so the fling will have ended at the end of it
expect(log, equals(<String>['tap 21']));
await tester.tap(find.byType(Scrollable));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 21', 'tap 48']));
});
}