Commit 8a186f3b authored by Dan Rubel's avatar Dan Rubel Committed by GitHub

tests to assert futures complete as expected (#5947)

parent 74f50bfb
...@@ -154,6 +154,8 @@ class AnimationController extends Animation<double> ...@@ -154,6 +154,8 @@ class AnimationController extends Animation<double>
AnimationStatus _status; AnimationStatus _status;
/// Starts running this animation forwards (towards the end). /// Starts running this animation forwards (towards the end).
///
/// Returns a [Future] that completes when the animation is complete.
Future<Null> forward({ double from }) { Future<Null> forward({ double from }) {
_direction = _AnimationDirection.forward; _direction = _AnimationDirection.forward;
if (from != null) if (from != null)
...@@ -162,6 +164,8 @@ class AnimationController extends Animation<double> ...@@ -162,6 +164,8 @@ class AnimationController extends Animation<double>
} }
/// Starts running this animation in reverse (towards the beginning). /// Starts running this animation in reverse (towards the beginning).
///
/// Returns a [Future] that completes when the animation is complete.
Future<Null> reverse({ double from }) { Future<Null> reverse({ double from }) {
_direction = _AnimationDirection.reverse; _direction = _AnimationDirection.reverse;
if (from != null) if (from != null)
...@@ -170,6 +174,8 @@ class AnimationController extends Animation<double> ...@@ -170,6 +174,8 @@ class AnimationController extends Animation<double>
} }
/// Drives the animation from its current value to target. /// Drives the animation from its current value to target.
///
/// Returns a [Future] that completes when the animation is complete.
Future<Null> animateTo(double target, { Duration duration, Curve curve: Curves.linear }) { Future<Null> animateTo(double target, { Duration duration, Curve curve: Curves.linear }) {
Duration simulationDuration = duration; Duration simulationDuration = duration;
if (simulationDuration == null) { if (simulationDuration == null) {
......
...@@ -472,6 +472,8 @@ class ScrollableState<T extends Scrollable> extends State<T> { ...@@ -472,6 +472,8 @@ class ScrollableState<T extends Scrollable> extends State<T> {
/// This function does not accept a zero duration. To jump-scroll to /// This function does not accept a zero duration. To jump-scroll to
/// the new offset, do not provide a duration, rather than providing /// the new offset, do not provide a duration, rather than providing
/// a zero duration. /// a zero duration.
///
/// The returned [Future] completes when the scrolling animation is complete.
Future<Null> scrollTo(double newScrollOffset, { Future<Null> scrollTo(double newScrollOffset, {
Duration duration, Duration duration,
Curve curve: Curves.ease, Curve curve: Curves.ease,
...@@ -550,6 +552,8 @@ class ScrollableState<T extends Scrollable> extends State<T> { ...@@ -550,6 +552,8 @@ class ScrollableState<T extends Scrollable> extends State<T> {
/// Calling this function starts a physics-based animation of the scroll /// Calling this function starts a physics-based animation of the scroll
/// offset with the given value as the initial velocity. The physics /// offset with the given value as the initial velocity. The physics
/// simulation is determined by the scroll behavior. /// simulation is determined by the scroll behavior.
///
/// The returned [Future] completes when the scrolling animation is complete.
Future<Null> fling(double scrollVelocity) { Future<Null> fling(double scrollVelocity) {
if (scrollVelocity.abs() > kPixelScrollTolerance.velocity) if (scrollVelocity.abs() > kPixelScrollTolerance.velocity)
return _startToEndAnimation(scrollVelocity); return _startToEndAnimation(scrollVelocity);
......
...@@ -9,7 +9,6 @@ import 'package:flutter/widgets.dart'; ...@@ -9,7 +9,6 @@ import 'package:flutter/widgets.dart';
void main() { void main() {
testWidgets('Verify that a tap dismisses a modal BottomSheet', (WidgetTester tester) async { testWidgets('Verify that a tap dismisses a modal BottomSheet', (WidgetTester tester) async {
BuildContext savedContext; BuildContext savedContext;
bool showBottomSheetThenCalled = false;
await tester.pumpWidget(new MaterialApp( await tester.pumpWidget(new MaterialApp(
home: new Builder( home: new Builder(
...@@ -23,6 +22,7 @@ void main() { ...@@ -23,6 +22,7 @@ void main() {
await tester.pump(); await tester.pump();
expect(find.text('BottomSheet'), findsNothing); expect(find.text('BottomSheet'), findsNothing);
bool showBottomSheetThenCalled = false;
showModalBottomSheet/*<Null>*/( showModalBottomSheet/*<Null>*/(
context: savedContext, context: savedContext,
builder: (BuildContext context) => new Text('BottomSheet') builder: (BuildContext context) => new Text('BottomSheet')
...@@ -44,14 +44,23 @@ void main() { ...@@ -44,14 +44,23 @@ void main() {
await tester.pump(new Duration(seconds: 1)); // frame after the animation (sheet has been removed) await tester.pump(new Duration(seconds: 1)); // frame after the animation (sheet has been removed)
expect(find.text('BottomSheet'), findsNothing); expect(find.text('BottomSheet'), findsNothing);
showModalBottomSheet/*<Null>*/(context: savedContext, builder: (BuildContext context) => new Text('BottomSheet')); showBottomSheetThenCalled = false;
showModalBottomSheet/*<Null>*/(
context: savedContext,
builder: (BuildContext context) => new Text('BottomSheet'),
).then((Null result) {
expectSync(result, isNull);
showBottomSheetThenCalled = true;
});
await tester.pump(); // bottom sheet show animation starts await tester.pump(); // bottom sheet show animation starts
await tester.pump(new Duration(seconds: 1)); // animation done await tester.pump(new Duration(seconds: 1)); // animation done
expect(find.text('BottomSheet'), findsOneWidget); expect(find.text('BottomSheet'), findsOneWidget);
expect(showBottomSheetThenCalled, isFalse);
// Tap above the the bottom sheet to dismiss it // Tap above the the bottom sheet to dismiss it
await tester.tapAt(new Point(20.0, 20.0)); await tester.tapAt(new Point(20.0, 20.0));
await tester.pump(); // bottom sheet dismiss animation starts await tester.pump(); // bottom sheet dismiss animation starts
expect(showBottomSheetThenCalled, isTrue);
await tester.pump(new Duration(seconds: 1)); // animation done await tester.pump(new Duration(seconds: 1)); // animation done
await tester.pump(new Duration(seconds: 1)); // rebuild frame await tester.pump(new Duration(seconds: 1)); // rebuild frame
expect(find.text('BottomSheet'), findsNothing); expect(find.text('BottomSheet'), findsNothing);
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -53,22 +55,31 @@ void main() { ...@@ -53,22 +55,31 @@ void main() {
) )
); // t=0 ); // t=0
recordMetrics(); recordMetrics();
controller.forward(); Completer<Null> completer = new Completer<Null>();
controller.forward().whenComplete(completer.complete);
expect(completer.isCompleted, isFalse);
await tester.pump(); // t=0 again await tester.pump(); // t=0 again
expect(completer.isCompleted, isFalse);
recordMetrics(); recordMetrics();
await tester.pump(const Duration(seconds: 1)); // t=1 await tester.pump(const Duration(seconds: 1)); // t=1
expect(completer.isCompleted, isFalse);
recordMetrics(); recordMetrics();
await tester.pump(const Duration(seconds: 1)); // t=2 await tester.pump(const Duration(seconds: 1)); // t=2
expect(completer.isCompleted, isFalse);
recordMetrics(); recordMetrics();
await tester.pump(const Duration(seconds: 3)); // t=5 await tester.pump(const Duration(seconds: 3)); // t=5
expect(completer.isCompleted, isFalse);
recordMetrics(); recordMetrics();
await tester.pump(const Duration(seconds: 5)); // t=10 await tester.pump(const Duration(seconds: 5)); // t=10
expect(completer.isCompleted, isFalse);
recordMetrics(); recordMetrics();
expect(sizes, equals(<Size>[const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0)])); expect(sizes, equals(<Size>[const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0)]));
expect(positions, equals(<Offset>[const Offset(10.0, 10.0), const Offset(10.0, 10.0), const Offset(17.0, 17.0), const Offset(24.0, 24.0), const Offset(45.0, 45.0), const Offset(80.0, 80.0)])); expect(positions, equals(<Offset>[const Offset(10.0, 10.0), const Offset(10.0, 10.0), const Offset(17.0, 17.0), const Offset(24.0, 24.0), const Offset(45.0, 45.0), const Offset(80.0, 80.0)]));
controller.stop(); controller.stop();
await tester.pump();
expect(completer.isCompleted, isTrue);
}); });
} }
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
...@@ -57,8 +59,11 @@ Future<Null> performTest(WidgetTester tester, bool maintainState) async { ...@@ -57,8 +59,11 @@ Future<Null> performTest(WidgetTester tester, bool maintainState) async {
expect(find.text('10'), findsNothing); expect(find.text('10'), findsNothing);
expect(find.text('100'), findsNothing); expect(find.text('100'), findsNothing);
tester.state/*<ScrollableState>*/(find.byType(Scrollable)).scrollTo(1000.0); Completer<Null> completer = new Completer<Null>();
tester.state/*<ScrollableState>*/(find.byType(Scrollable)).scrollTo(1000.0).whenComplete(completer.complete);
expect(completer.isCompleted, isFalse);
await tester.pump(new Duration(seconds: 1)); await tester.pump(new Duration(seconds: 1));
expect(completer.isCompleted, isTrue);
// we're 600 pixels high, each item is 100 pixels high, scroll position is // we're 600 pixels high, each item is 100 pixels high, scroll position is
// 1000, so we should have exactly 6 items, 10..15. // 1000, so we should have exactly 6 items, 10..15.
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -22,6 +24,14 @@ Widget _buildScroller({Key key, List<String> log}) { ...@@ -22,6 +24,14 @@ Widget _buildScroller({Key key, List<String> log}) {
} }
void main() { void main() {
GlobalKey<ScrollableState<Scrollable>> scrollKey;
Completer<Null> scrollTo(double newScrollOffset, { Duration duration }) {
Completer<Null> completer = new Completer<Null>();
scrollKey.currentState.scrollTo(newScrollOffset, duration: duration).whenComplete(completer.complete);
return completer;
}
testWidgets('Scroll event drag', (WidgetTester tester) async { testWidgets('Scroll event drag', (WidgetTester tester) async {
List<String> log = <String>[]; List<String> log = <String>[];
await tester.pumpWidget(_buildScroller(log: log)); await tester.pumpWidget(_buildScroller(log: log));
...@@ -42,12 +52,13 @@ void main() { ...@@ -42,12 +52,13 @@ void main() {
}); });
testWidgets('Scroll scrollTo animation', (WidgetTester tester) async { testWidgets('Scroll scrollTo animation', (WidgetTester tester) async {
GlobalKey<ScrollableState<Scrollable>> scrollKey = new GlobalKey<ScrollableState<Scrollable>>(); scrollKey = new GlobalKey<ScrollableState<Scrollable>>();
List<String> log = <String>[]; List<String> log = <String>[];
await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); await tester.pumpWidget(_buildScroller(key: scrollKey, log: log));
expect(log, equals(<String>[])); expect(log, equals(<String>[]));
scrollKey.currentState.scrollTo(100.0, duration: const Duration(seconds: 1)); Completer<Null> completer = scrollTo(100.0, duration: const Duration(seconds: 1));
expect(completer.isCompleted, isFalse);
expect(log, equals(<String>['scrollstart'])); expect(log, equals(<String>['scrollstart']));
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['scrollstart'])); expect(log, equals(<String>['scrollstart']));
...@@ -55,60 +66,74 @@ void main() { ...@@ -55,60 +66,74 @@ void main() {
expect(log, equals(<String>['scrollstart', 'scroll'])); expect(log, equals(<String>['scrollstart', 'scroll']));
await tester.pump(const Duration(milliseconds: 1500)); await tester.pump(const Duration(milliseconds: 1500));
expect(log, equals(<String>['scrollstart', 'scroll', 'scroll', 'scrollend'])); expect(log, equals(<String>['scrollstart', 'scroll', 'scroll', 'scrollend']));
expect(completer.isCompleted, isTrue);
}); });
testWidgets('Scroll scrollTo no animation', (WidgetTester tester) async { testWidgets('Scroll scrollTo no animation', (WidgetTester tester) async {
GlobalKey<ScrollableState<Scrollable>> scrollKey = new GlobalKey<ScrollableState<Scrollable>>(); scrollKey = new GlobalKey<ScrollableState<Scrollable>>();
List<String> log = <String>[]; List<String> log = <String>[];
await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); await tester.pumpWidget(_buildScroller(key: scrollKey, log: log));
expect(log, equals(<String>[])); expect(log, equals(<String>[]));
scrollKey.currentState.scrollTo(100.0); Completer<Null> completer = scrollTo(100.0);
expect(completer.isCompleted, isFalse);
expect(log, equals(<String>['scrollstart', 'scroll', 'scrollend'])); expect(log, equals(<String>['scrollstart', 'scroll', 'scrollend']));
await tester.pump();
expect(completer.isCompleted, isTrue);
}); });
testWidgets('Scroll during animation', (WidgetTester tester) async { testWidgets('Scroll during animation', (WidgetTester tester) async {
GlobalKey<ScrollableState<Scrollable>> scrollKey = new GlobalKey<ScrollableState<Scrollable>>(); scrollKey = new GlobalKey<ScrollableState<Scrollable>>();
List<String> log = <String>[]; List<String> log = <String>[];
await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); await tester.pumpWidget(_buildScroller(key: scrollKey, log: log));
expect(log, equals(<String>[])); expect(log, equals(<String>[]));
scrollKey.currentState.scrollTo(100.0, duration: const Duration(seconds: 1)); Completer<Null> completer = scrollTo(100.0, duration: const Duration(seconds: 1));
expect(completer.isCompleted, isFalse);
expect(log, equals(<String>['scrollstart'])); expect(log, equals(<String>['scrollstart']));
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['scrollstart'])); expect(log, equals(<String>['scrollstart']));
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['scrollstart', 'scroll'])); expect(log, equals(<String>['scrollstart', 'scroll']));
scrollKey.currentState.scrollTo(100.0); expect(completer.isCompleted, isFalse);
completer = scrollTo(100.0);
expect(completer.isCompleted, isFalse);
expect(log, equals(<String>['scrollstart', 'scroll', 'scroll'])); expect(log, equals(<String>['scrollstart', 'scroll', 'scroll']));
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['scrollstart', 'scroll', 'scroll', 'scrollend'])); expect(log, equals(<String>['scrollstart', 'scroll', 'scroll', 'scrollend']));
await tester.pump(const Duration(milliseconds: 1500)); await tester.pump(const Duration(milliseconds: 1500));
expect(log, equals(<String>['scrollstart', 'scroll', 'scroll', 'scrollend'])); expect(log, equals(<String>['scrollstart', 'scroll', 'scroll', 'scrollend']));
expect(completer.isCompleted, isTrue);
}); });
testWidgets('Scroll during animation', (WidgetTester tester) async { testWidgets('Scroll during animation', (WidgetTester tester) async {
GlobalKey<ScrollableState<Scrollable>> scrollKey = new GlobalKey<ScrollableState<Scrollable>>(); scrollKey = new GlobalKey<ScrollableState<Scrollable>>();
List<String> log = <String>[]; List<String> log = <String>[];
await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); await tester.pumpWidget(_buildScroller(key: scrollKey, log: log));
expect(log, equals(<String>[])); expect(log, equals(<String>[]));
scrollKey.currentState.scrollTo(100.0, duration: const Duration(seconds: 1)); Completer<Null> completer = scrollTo(100.0, duration: const Duration(seconds: 1));
expect(completer.isCompleted, isFalse);
expect(log, equals(<String>['scrollstart'])); expect(log, equals(<String>['scrollstart']));
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['scrollstart'])); expect(log, equals(<String>['scrollstart']));
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['scrollstart', 'scroll'])); expect(log, equals(<String>['scrollstart', 'scroll']));
scrollKey.currentState.scrollTo(100.0, duration: const Duration(seconds: 1)); expect(completer.isCompleted, isFalse);
completer = scrollTo(100.0, duration: const Duration(seconds: 1));
expect(completer.isCompleted, isFalse);
expect(log, equals(<String>['scrollstart', 'scroll'])); expect(log, equals(<String>['scrollstart', 'scroll']));
await tester.pump(const Duration(milliseconds: 100)); await tester.pump(const Duration(milliseconds: 100));
expect(log, equals(<String>['scrollstart', 'scroll'])); expect(log, equals(<String>['scrollstart', 'scroll']));
await tester.pump(const Duration(milliseconds: 1500)); await tester.pump(const Duration(milliseconds: 1500));
expect(log, equals(<String>['scrollstart', 'scroll', 'scroll', 'scrollend'])); expect(log, equals(<String>['scrollstart', 'scroll', 'scroll', 'scrollend']));
expect(completer.isCompleted, isTrue);
}); });
testWidgets('fling, fling generates two start/end pairs', (WidgetTester tester) async { testWidgets('fling, fling generates two start/end pairs', (WidgetTester tester) async {
GlobalKey<ScrollableState<Scrollable>> scrollKey = new GlobalKey<ScrollableState<Scrollable>>(); scrollKey = new GlobalKey<ScrollableState<Scrollable>>();
List<String> log = <String>[]; List<String> log = <String>[];
await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); await tester.pumpWidget(_buildScroller(key: scrollKey, log: log));
...@@ -127,7 +152,7 @@ void main() { ...@@ -127,7 +152,7 @@ void main() {
}); });
testWidgets('fling up ends', (WidgetTester tester) async { testWidgets('fling up ends', (WidgetTester tester) async {
GlobalKey<ScrollableState<Scrollable>> scrollKey = new GlobalKey<ScrollableState<Scrollable>>(); scrollKey = new GlobalKey<ScrollableState<Scrollable>>();
List<String> log = <String>[]; List<String> log = <String>[];
await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); await tester.pumpWidget(_buildScroller(key: scrollKey, log: log));
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -85,6 +87,11 @@ void main() { ...@@ -85,6 +87,11 @@ void main() {
), ),
right: new Text('Not Today') right: new Text('Not Today')
); );
Completer<Null> scrollTo(double newScrollOffset) {
Completer<Null> completer = new Completer<Null>();
scrollableKey.currentState.scrollTo(newScrollOffset).whenComplete(completer.complete);
return completer;
}
await tester.pumpWidget(testWidget); await tester.pumpWidget(testWidget);
...@@ -92,12 +99,14 @@ void main() { ...@@ -92,12 +99,14 @@ void main() {
callbackTracker.clear(); callbackTracker.clear();
scrollableKey.currentState.scrollTo(400.0); Completer<Null> completer = scrollTo(400.0);
expect(completer.isCompleted, isFalse);
// now only 3 should fit, numbered 2-4. // now only 3 should fit, numbered 2-4.
await tester.pumpWidget(testWidget); await tester.pumpWidget(testWidget);
expect(callbackTracker, equals(<int>[2, 3, 4])); expect(callbackTracker, equals(<int>[2, 3, 4]));
expect(completer.isCompleted, isTrue);
callbackTracker.clear(); callbackTracker.clear();
}); });
...@@ -134,6 +143,11 @@ void main() { ...@@ -134,6 +143,11 @@ void main() {
), ),
right: new Text('Not Today') right: new Text('Not Today')
); );
Completer<Null> scrollTo(double newScrollOffset) {
Completer<Null> completer = new Completer<Null>();
scrollableKey.currentState.scrollTo(newScrollOffset).whenComplete(completer.complete);
return completer;
}
await tester.pumpWidget(testWidget); await tester.pumpWidget(testWidget);
...@@ -141,12 +155,14 @@ void main() { ...@@ -141,12 +155,14 @@ void main() {
callbackTracker.clear(); callbackTracker.clear();
scrollableKey.currentState.scrollTo(400.0); Completer<Null> completer = scrollTo(400.0);
expect(completer.isCompleted, isFalse);
// now only 4 should fit, numbered 2-5. // now only 4 should fit, numbered 2-5.
await tester.pumpWidget(testWidget); await tester.pumpWidget(testWidget);
expect(callbackTracker, equals(<int>[2, 3, 4, 5])); expect(callbackTracker, equals(<int>[2, 3, 4, 5]));
expect(completer.isCompleted, isTrue);
callbackTracker.clear(); callbackTracker.clear();
}); });
...@@ -174,24 +190,35 @@ void main() { ...@@ -174,24 +190,35 @@ void main() {
itemExtent: 300.0, itemExtent: 300.0,
itemCount: 10 itemCount: 10
); );
Completer<Null> scrollTo(double newScrollOffset) {
Completer<Null> completer = new Completer<Null>();
scrollableKey.currentState.scrollTo(newScrollOffset).whenComplete(completer.complete);
return completer;
}
await tester.pumpWidget(testWidget); await tester.pumpWidget(testWidget);
expect(callbackTracker, equals(<int>[0, 1])); expect(callbackTracker, equals(<int>[0, 1]));
callbackTracker.clear(); callbackTracker.clear();
scrollableKey.currentState.scrollTo(150.0); Completer<Null> completer = scrollTo(150.0);
expect(completer.isCompleted, isFalse);
await tester.pumpWidget(testWidget); await tester.pumpWidget(testWidget);
expect(callbackTracker, equals(<int>[0, 1, 2])); expect(callbackTracker, equals(<int>[0, 1, 2]));
expect(completer.isCompleted, isTrue);
callbackTracker.clear(); callbackTracker.clear();
scrollableKey.currentState.scrollTo(600.0); completer = scrollTo(600.0);
expect(completer.isCompleted, isFalse);
await tester.pumpWidget(testWidget); await tester.pumpWidget(testWidget);
expect(callbackTracker, equals(<int>[2, 3])); expect(callbackTracker, equals(<int>[2, 3]));
expect(completer.isCompleted, isTrue);
callbackTracker.clear(); callbackTracker.clear();
scrollableKey.currentState.scrollTo(750.0); completer = scrollTo(750.0);
expect(completer.isCompleted, isFalse);
await tester.pumpWidget(testWidget); await tester.pumpWidget(testWidget);
expect(callbackTracker, equals(<int>[2, 3, 4])); expect(callbackTracker, equals(<int>[2, 3, 4]));
expect(completer.isCompleted, isTrue);
callbackTracker.clear(); callbackTracker.clear();
}); });
......
...@@ -46,8 +46,10 @@ set scrollOffset(double value) { ...@@ -46,8 +46,10 @@ set scrollOffset(double value) {
scrollableState.scrollTo(value); scrollableState.scrollTo(value);
} }
Future<Null> fling(double velocity) { Completer<Null> fling(double velocity) {
return scrollableState.fling(velocity); Completer<Null> completer = new Completer<Null>();
scrollableState.fling(velocity).whenComplete(completer.complete);
return completer;
} }
void main() { void main() {
...@@ -60,49 +62,55 @@ void main() { ...@@ -60,49 +62,55 @@ void main() {
Duration dt = const Duration(seconds: 2); Duration dt = const Duration(seconds: 2);
fling(1000.0); Completer<Null> completer = fling(1000.0);
expect(completer.isCompleted, isFalse);
await tester.pump(); // Start the scheduler at 0.0 await tester.pump(); // Start the scheduler at 0.0
await tester.pump(dt); await tester.pump(dt);
expect(scrollOffset, closeTo(200.0, 1.0)); expect(scrollOffset, closeTo(200.0, 1.0));
expect(completer.isCompleted, isTrue);
scrollOffset = 0.0; scrollOffset = 0.0;
await tester.pump(); await tester.pump();
expect(scrollOffset, 0.0); expect(scrollOffset, 0.0);
fling(2000.0); completer = fling(2000.0);
expect(completer.isCompleted, isFalse);
await tester.pump(); await tester.pump();
await tester.pump(dt); await tester.pump(dt);
expect(scrollOffset, closeTo(400.0, 1.0)); expect(scrollOffset, closeTo(400.0, 1.0));
expect(completer.isCompleted, isTrue);
scrollOffset = 400.0; scrollOffset = 400.0;
await tester.pump(); await tester.pump();
expect(scrollOffset, 400.0); expect(scrollOffset, 400.0);
fling(-800.0); completer = fling(-800.0);
expect(completer.isCompleted, isFalse);
await tester.pump(); await tester.pump();
await tester.pump(dt); await tester.pump(dt);
expect(scrollOffset, closeTo(0.0, 1.0)); expect(scrollOffset, closeTo(0.0, 1.0));
expect(completer.isCompleted, isTrue);
scrollOffset = 800.0; scrollOffset = 800.0;
await tester.pump(); await tester.pump();
expect(scrollOffset, 800.0); expect(scrollOffset, 800.0);
fling(-2000.0); completer = fling(-2000.0);
expect(completer.isCompleted, isFalse);
await tester.pump(); await tester.pump();
await tester.pump(dt); await tester.pump(dt);
expect(scrollOffset, closeTo(200.0, 1.0)); expect(scrollOffset, closeTo(200.0, 1.0));
expect(completer.isCompleted, isTrue);
scrollOffset = 800.0; scrollOffset = 800.0;
await tester.pump(); await tester.pump();
expect(scrollOffset, 800.0); expect(scrollOffset, 800.0);
bool completed = false; completer = fling(-2000.0);
fling(-2000.0).then((_) { expect(completer.isCompleted, isFalse);
completed = true;
expectSync(scrollOffset, closeTo(200.0, 1.0));
});
await tester.pump(); await tester.pump();
await tester.pump(dt); await tester.pump(dt);
expect(completed, true); expect(completer.isCompleted, isTrue);
expectSync(scrollOffset, closeTo(200.0, 1.0));
}); });
} }
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