| // 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'])); |
| }); |
| } |