diff --git a/dev/automated_tests/flutter_test/README.md b/dev/automated_tests/flutter_test/README.md new file mode 100644 index 0000000000..efea7261f7 --- /dev/null +++ b/dev/automated_tests/flutter_test/README.md @@ -0,0 +1,4 @@ +The files in this directory are used as part of tests in the +`flutter_tools` package. They are here because here these tests need a +`pubspec.yaml` that references the flutter framework (which is +intentionally not true of the `flutter_tools` package). diff --git a/dev/automated_tests/flutter_test/test_async_utils_guarded_expectation.txt b/dev/automated_tests/flutter_test/test_async_utils_guarded_expectation.txt new file mode 100644 index 0000000000..4f98bad672 --- /dev/null +++ b/dev/automated_tests/flutter_test/test_async_utils_guarded_expectation.txt @@ -0,0 +1,21 @@ +.*(this line contains the test framework's output with the clock and so forth)? +══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════ +The following assertion was thrown running a test: +Guarded function conflict\. You must use "await" with all Future-returning test APIs\. +The guarded "guardedHelper" function was called from .*dev/manual_tests/test_data/test_async_utils_guarded_test\.dart on line [0-9]+\. +Then, the "expect" function was called from .*dev/manual_tests/test_data/test_async_utils_guarded_test\.dart on line [0-9]+\. +The first function \(guardedHelper\) had not yet finished executing at the time that the second function \(expect\) was called\. Since both are guarded, and the second was not a nested call inside the first, the first must complete its execution before the second can be called\. Typically, this is achieved by putting an "await" statement in front of the call to the first\. +If you are confident that all test APIs are being called using "await", and this expect\(\) call is not being invoked at the top level but is itself being called from some sort of callback registered before the guardedHelper method was called, then consider using expectSync\(\) instead\. + +When the first function \(guardedHelper\) was called, this was the stack: +<> +\(elided .+\) + +When the exception was thrown, this was the stack: +<> +\(elided .+\) +════════════════════════════════════════════════════════════════════════════════════════════════════ +.*(this line has more of the test framework's output)? + Test failed\. See exception logs above\. + * +.*..:.. \+0 -1: Some tests failed\. * diff --git a/dev/automated_tests/flutter_test/test_async_utils_guarded_test.dart b/dev/automated_tests/flutter_test/test_async_utils_guarded_test.dart new file mode 100644 index 0000000000..f700bb0abf --- /dev/null +++ b/dev/automated_tests/flutter_test/test_async_utils_guarded_test.dart @@ -0,0 +1,23 @@ +// Copyright 2016 The Chromium 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/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; + +Future guardedHelper(WidgetTester tester) { + return TestAsyncUtils.guard(() async { + await tester.pumpWidget(new Text('Hello')); + }); +} + +void main() { + testWidgets('TestAsyncUtils - custom guarded sections', (WidgetTester tester) async { + debugPrint = (String message, { int wrapWidth }) { print(message); }; + await tester.pumpWidget(new Container()); + expect(find.byElementType(Container), isNotNull); + guardedHelper(tester); + expect(find.byElementType(Container), isNull); + // this should fail + }); +} diff --git a/dev/automated_tests/flutter_test/test_async_utils_unguarded_expectation.txt b/dev/automated_tests/flutter_test/test_async_utils_unguarded_expectation.txt new file mode 100644 index 0000000000..915bd7851b --- /dev/null +++ b/dev/automated_tests/flutter_test/test_async_utils_unguarded_expectation.txt @@ -0,0 +1,20 @@ +.*..:.. \+0: - TestAsyncUtils - handling unguarded async helper functions * +══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════ +The following assertion was thrown running a test: +Guarded function conflict\. You must use "await" with all Future-returning test APIs\. +The guarded method "pump" from class WidgetTester was called from .*dev/flutter/dev/manual_tests/test_data/test_async_utils_unguarded_test.dart on line [0-9]+\. +Then, it was called again from .*dev/manual_tests/test_data/test_async_utils_unguarded_test.dart on line [0-9]+\. +The first method had not yet finished executing at the time that the second method was called\. Since both are guarded, and the second was not a nested call inside the first, the first must complete its execution before the second can be called\. Typically, this is achieved by putting an "await" statement in front of the call to the first\. + +When the first method was called, this was the stack: +<> +(elided [0-9]+ frames from .+) + +When the exception was thrown, this was the stack: +<> +(elided [0-9]+ frames from .+) +════════════════════════════════════════════════════════════════════════════════════════════════════ +.*..:.. \+0 -1: - TestAsyncUtils - handling unguarded async helper functions * + Test failed. See exception logs above. + * +.*..:.. \+0 -1: Some tests failed\. * diff --git a/dev/automated_tests/flutter_test/test_async_utils_unguarded_test.dart b/dev/automated_tests/flutter_test/test_async_utils_unguarded_test.dart new file mode 100644 index 0000000000..9974cd3dbd --- /dev/null +++ b/dev/automated_tests/flutter_test/test_async_utils_unguarded_test.dart @@ -0,0 +1,19 @@ +// Copyright 2016 The Chromium 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/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; + +Future helperFunction(WidgetTester tester) async { + await tester.pump(); +} + +void main() { + testWidgets('TestAsyncUtils - handling unguarded async helper functions', (WidgetTester tester) async { + debugPrint = (String message, { int wrapWidth }) { print(message); }; + helperFunction(tester); + helperFunction(tester); + // this should fail + }); +} diff --git a/dev/manual_tests/test/card_collection_test.dart b/dev/manual_tests/test/card_collection_test.dart index 5c07bb4b55..34defcbb20 100644 --- a/dev/manual_tests/test/card_collection_test.dart +++ b/dev/manual_tests/test/card_collection_test.dart @@ -4,15 +4,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import '../card_collection.dart' as card_collection; void main() { - testWidgets("Card Collection smoke test", (WidgetTester tester) { + testWidgets("Card Collection smoke test", (WidgetTester tester) async { card_collection.main(); // builds the app and schedules a frame but doesn't trigger one - tester.pump(); // see https://github.com/flutter/flutter/issues/1865 - tester.pump(); // triggers a frame + await tester.pump(); // see https://github.com/flutter/flutter/issues/1865 + await tester.pump(); // triggers a frame Finder navigationMenu = find.byWidgetPredicate((Widget widget) { if (widget is Tooltip) @@ -22,18 +21,18 @@ void main() { expect(navigationMenu, findsOneWidget); - tester.tap(navigationMenu); - tester.pump(); // start opening menu - tester.pump(const Duration(seconds: 1)); // wait til it's really opened + await tester.tap(navigationMenu); + await tester.pump(); // start opening menu + await tester.pump(const Duration(seconds: 1)); // wait til it's really opened // smoke test for various checkboxes - tester.tap(find.text('Make card labels editable')); - tester.pump(); - tester.tap(find.text('Let the sun shine')); - tester.pump(); - tester.tap(find.text('Make card labels editable')); - tester.pump(); - tester.tap(find.text('Vary font sizes')); - tester.pump(); + await tester.tap(find.text('Make card labels editable')); + await tester.pump(); + await tester.tap(find.text('Let the sun shine')); + await tester.pump(); + await tester.tap(find.text('Make card labels editable')); + await tester.pump(); + await tester.tap(find.text('Vary font sizes')); + await tester.pump(); }); } diff --git a/examples/flutter_gallery/lib/demo/weather_demo.dart b/examples/flutter_gallery/lib/demo/weather_demo.dart index c7716f2da5..dc630aabb6 100644 --- a/examples/flutter_gallery/lib/demo/weather_demo.dart +++ b/examples/flutter_gallery/lib/demo/weather_demo.dart @@ -41,7 +41,7 @@ class _WeatherDemoState extends State { 'packages/flutter_gallery_assets/icon-snow.png' ]); - String json = await DefaultAssetBundle.of(context).loadString('packages/flutter_gallery_assets/weathersprites.json'); + String json = await bundle.loadString('packages/flutter_gallery_assets/weathersprites.json'); _sprites = new SpriteSheet(_images['packages/flutter_gallery_assets/weathersprites.png'], json); } diff --git a/examples/flutter_gallery/test/smoke_test.dart b/examples/flutter_gallery/test/smoke_test.dart index f8f398f08c..5586f08df7 100644 --- a/examples/flutter_gallery/test/smoke_test.dart +++ b/examples/flutter_gallery/test/smoke_test.dart @@ -7,7 +7,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_gallery/gallery/app.dart' as flutter_gallery_app; import 'package:flutter_gallery/gallery/item.dart' as flutter_gallery_item; import 'package:flutter_gallery/main.dart' as flutter_gallery_main; -import 'package:test/test.dart'; // Warning: the following strings must be kept in sync with GalleryHome. const List demoCategories = const ['Demos', 'Components', 'Style']; @@ -32,34 +31,39 @@ Finder findBackButton(WidgetTester tester) => byTooltip(tester, 'Back'); // Start a gallery demo and then go back. This function assumes that the // we're starting on home route and that the submenu that contains the demo // called 'name' is already open. -void smokeDemo(WidgetTester tester, String routeName) { +Future smokeDemo(WidgetTester tester, String routeName) async { // Ensure that we're (likely to be) on the home page final Finder menuItem = findGalleryItemByRouteName(tester, routeName); expect(menuItem, findsOneWidget); - tester.tap(menuItem); - tester.pump(); // Launch the demo. - tester.pump(const Duration(seconds: 1)); // Wait until the demo has opened. + await tester.tap(menuItem); + await tester.pump(); // Launch the demo. + await tester.pump(const Duration(seconds: 1)); // Wait until the demo has opened. // Go back Finder backButton = findBackButton(tester); expect(backButton, findsOneWidget); - tester.tap(backButton); - tester.pump(); // Start the navigator pop "back" operation. - tester.pump(const Duration(seconds: 1)); // Wait until it has finished. + await tester.tap(backButton); + await tester.pump(); // Start the navigator pop "back" operation. + await tester.pump(const Duration(seconds: 1)); // Wait until it has finished. + return null; } void main() { - testWidgets('Flutter gallery app smoke test', (WidgetTester tester) { + TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized(); + if (binding is LiveTestWidgetsFlutterBinding) + binding.allowAllFrames = true; + + testWidgets('Flutter Gallery app smoke test', (WidgetTester tester) async { flutter_gallery_main.main(); // builds the app and schedules a frame but doesn't trigger one - tester.pump(); // see https://github.com/flutter/flutter/issues/1865 - tester.pump(); // triggers a frame + await tester.pump(); // see https://github.com/flutter/flutter/issues/1865 + await tester.pump(); // triggers a frame // Expand the demo category submenus. for (String category in demoCategories.reversed) { - tester.tap(find.text(category)); - tester.pump(); - tester.pump(const Duration(seconds: 1)); // Wait until the menu has expanded. + await tester.tap(find.text(category)); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); // Wait until the menu has expanded. } final List scrollDeltas = new List(); @@ -74,25 +78,25 @@ void main() { // Launch each demo and then scroll that item out of the way. for (int i = 0; i < routeNames.length; i += 1) { final String routeName = routeNames[i]; - smokeDemo(tester, routeName); - tester.scroll(findGalleryItemByRouteName(tester, routeName), new Offset(0.0, scrollDeltas[i])); - tester.pump(); + await smokeDemo(tester, routeName); + await tester.scroll(findGalleryItemByRouteName(tester, routeName), new Offset(0.0, scrollDeltas[i])); + await tester.pump(); } Finder navigationMenuButton = findNavigationMenuButton(tester); expect(navigationMenuButton, findsOneWidget); - tester.tap(navigationMenuButton); - tester.pump(); // Start opening drawer. - tester.pump(const Duration(seconds: 1)); // Wait until it's really opened. + await tester.tap(navigationMenuButton); + await tester.pump(); // Start opening drawer. + await tester.pump(const Duration(seconds: 1)); // Wait until it's really opened. // switch theme - tester.tap(find.text('Dark')); - tester.pump(); - tester.pump(const Duration(seconds: 1)); // Wait until it's changed. + await tester.tap(find.text('Dark')); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); // Wait until it's changed. // switch theme - tester.tap(find.text('Light')); - tester.pump(); - tester.pump(const Duration(seconds: 1)); // Wait until it's changed. + await tester.tap(find.text('Light')); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); // Wait until it's changed. }, skip: true); } diff --git a/examples/hello_world/test/hello_test.dart b/examples/hello_world/test/hello_test.dart index 0ff5eb19cd..d5ad6b21eb 100644 --- a/examples/hello_world/test/hello_test.dart +++ b/examples/hello_world/test/hello_test.dart @@ -3,14 +3,13 @@ // found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import '../lib/main.dart' as hello_world; void main() { - testWidgets("Hello world smoke test", (WidgetTester tester) { + testWidgets("Hello world smoke test", (WidgetTester tester) async { hello_world.main(); // builds the app and schedules a frame but doesn't trigger one - tester.pump(); // triggers a frame + await tester.pump(); // triggers a frame expect(find.text('Hello, world!'), findsOneWidget); }); diff --git a/examples/stocks/test/icon_color_test.dart b/examples/stocks/test/icon_color_test.dart index 69e112e8d4..cba9f8f7a5 100644 --- a/examples/stocks/test/icon_color_test.dart +++ b/examples/stocks/test/icon_color_test.dart @@ -9,7 +9,6 @@ import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:stocks/main.dart' as stocks; import 'package:stocks/stock_data.dart' as stock_data; -import 'package:test/test.dart'; Element findElementOfExactWidgetTypeGoingDown(Element node, Type targetType) { void walker(Element child) { @@ -52,27 +51,27 @@ void checkIconColor(WidgetTester tester, String label, Color color) { void main() { stock_data.StockDataFetcher.actuallyFetchData = false; - testWidgets("Test icon colors", (WidgetTester tester) { + testWidgets("Test icon colors", (WidgetTester tester) async { stocks.main(); // builds the app and schedules a frame but doesn't trigger one - tester.pump(); // see https://github.com/flutter/flutter/issues/1865 - tester.pump(); // triggers a frame + await tester.pump(); // see https://github.com/flutter/flutter/issues/1865 + await tester.pump(); // triggers a frame // sanity check expect(find.text('MARKET'), findsOneWidget); expect(find.text('Help & Feedback'), findsNothing); - tester.pump(new Duration(seconds: 2)); + await tester.pump(new Duration(seconds: 2)); expect(find.text('MARKET'), findsOneWidget); expect(find.text('Help & Feedback'), findsNothing); // drag the drawer out Point left = new Point(0.0, ui.window.size.height / 2.0); Point right = new Point(ui.window.size.width, left.y); - TestGesture gesture = tester.startGesture(left); - tester.pump(); - gesture.moveTo(right); - tester.pump(); - gesture.up(); - tester.pump(); + TestGesture gesture = await tester.startGesture(left); + await tester.pump(); + await gesture.moveTo(right); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(find.text('MARKET'), findsOneWidget); expect(find.text('Help & Feedback'), findsOneWidget); @@ -82,10 +81,10 @@ void main() { checkIconColor(tester, 'Help & Feedback', Colors.black26); // disabled // switch to dark mode - tester.tap(find.text('Pessimistic')); - tester.pump(); // get the tap and send the notification that the theme has changed - tester.pump(); // start the theme transition - tester.pump(const Duration(seconds: 5)); // end the transition + await tester.tap(find.text('Pessimistic')); + await tester.pump(); // get the tap and send the notification that the theme has changed + await tester.pump(); // start the theme transition + await tester.pump(const Duration(seconds: 5)); // end the transition // check the colour of the icon - dark mode checkIconColor(tester, 'Stock List', Colors.redAccent[200]); // theme accent color diff --git a/examples/stocks/test/locale_test.dart b/examples/stocks/test/locale_test.dart index 4502e97bbb..2dc30ecf0b 100644 --- a/examples/stocks/test/locale_test.dart +++ b/examples/stocks/test/locale_test.dart @@ -5,18 +5,18 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:stocks/main.dart' as stocks; import 'package:stocks/stock_data.dart' as stock_data; -import 'package:test/test.dart'; void main() { stock_data.StockDataFetcher.actuallyFetchData = false; - testWidgets("Test changing locale", (WidgetTester tester) { + testWidgets("Test changing locale", (WidgetTester tester) async { stocks.main(); - tester.flushMicrotasks(); // see https://github.com/flutter/flutter/issues/1865 - tester.pump(); + await tester.idle(); // see https://github.com/flutter/flutter/issues/1865 + await tester.pump(); expect(find.text('MARKET'), findsOneWidget); - tester.binding.setLocale("es", "US"); - tester.pump(); + await tester.binding.setLocale("es", "US"); + await tester.idle(); + await tester.pump(); expect(find.text('MERCADO'), findsOneWidget); }); } diff --git a/packages/flutter/lib/src/foundation/assertions.dart b/packages/flutter/lib/src/foundation/assertions.dart index c190ad55fc..f21b478785 100644 --- a/packages/flutter/lib/src/foundation/assertions.dart +++ b/packages/flutter/lib/src/foundation/assertions.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'basic_types.dart'; import 'print.dart'; /// Signature for [FlutterError.onException] handler. @@ -29,6 +30,7 @@ class FlutterErrorDetails { this.stack, this.library: 'Flutter framework', this.context, + this.stackFilter, this.informationCollector, this.silent: false }); @@ -40,8 +42,14 @@ class FlutterErrorDetails { /// The stack trace from where the [exception] was thrown (as opposed to where /// it was caught). /// - /// StackTrace objects are opaque except for their [toString] function. A - /// stack trace is not expected to be machine-readable. + /// StackTrace objects are opaque except for their [toString] function. + /// + /// If this field is not null, then the [stackFilter] callback, if any, will + /// be invoked with the result of calling [toString] on this object and + /// splitting that result on line breaks. If there's no [stackFilter] + /// callback, then [FlutterError.defaultStackFilter] is used instead. That + /// function expects the stack to be in the format used by + /// [StackTrace.toString]. final StackTrace stack; /// A human-readable brief name describing the library that caught the error @@ -53,6 +61,22 @@ class FlutterErrorDetails { /// where it was thrown). final String context; + /// A callback which filters the [stack] trace. Receives an iterable of + /// strings representing the frames encoded in the way that + /// [StackTrace.toString()] provides. Should return an iterable of lines to + /// output for the stack. + /// + /// If this is not provided, then [FlutterError.dumpErrorToConsole] will use + /// [FlutterError.defaultStackFilter] instead. + /// + /// If the [FlutterError.defaultStackFilter] behavior is desired, then the + /// callback should manually call that function. That function expects the + /// incoming list to be in the [StackTrace.toString()] format. The output of + /// that function, however, does not always follow this format. + /// + /// This won't be called if [stack] is null. + final IterableFilter stackFilter; + /// A callback which, when invoked with a [StringBuffer] will write to that buffer /// information that could help with debugging the problem. /// @@ -153,7 +177,7 @@ class FlutterError extends AssertionError { return; if (_errorCount == 0 || forceReport) { final String header = '\u2550\u2550\u2561 EXCEPTION CAUGHT BY ${details.library} \u255E'.toUpperCase(); - final String footer = '\u2501' * _kWrapWidth; + final String footer = '\u2550' * _kWrapWidth; debugPrint('$header${"\u2550" * (footer.length - header.length)}'); final String verb = 'thrown${ details.context != null ? " ${details.context}" : ""}'; if (details.exception is NullThrownError) { @@ -188,7 +212,14 @@ class FlutterError extends AssertionError { } if (details.stack != null) { debugPrint('When the exception was thrown, this was the stack:', wrapWidth: _kWrapWidth); - debugPrint('${details.stack}$footer'); // StackTrace objects include a trailing newline + Iterable stackLines = details.stack.toString().trimRight().split('\n'); + if (details.stackFilter != null) { + stackLines = details.stackFilter(stackLines); + } else { + stackLines = defaultStackFilter(stackLines); + } + debugPrint(stackLines.join('\n'), wrapWidth: _kWrapWidth); + debugPrint(footer); } else { debugPrint(footer); } @@ -198,6 +229,65 @@ class FlutterError extends AssertionError { _errorCount += 1; } + /// Converts a stack to a string that is more readable by omitting stack + /// frames that correspond to Dart internals. + /// + /// This is the default filter used by [dumpErrorToConsole] if the + /// [FlutterErrorDetails] object has no [FlutterErrorDetails.stackFilter] + /// callback. + /// + /// This function expects its input to be in the format used by + /// [StackTrace.toString()]. The output of this function is similar to that + /// format but the frame numbers will not be consecutive (frames are elided) + /// and the final line may be prose rather than a stack frame. + static Iterable defaultStackFilter(Iterable frames) { + final List result = []; + final List filteredPackages = [ + 'dart:async-patch', + 'dart:async', + 'package:stack_trace', + ]; + final List filteredClasses = [ + '_FakeAsync', + ]; + final RegExp stackParser = new RegExp(r'^#[0-9]+ +([^.]+).* \(([^/]*)/[^:]+:[0-9]+(?::[0-9]+)?\)$'); + final RegExp packageParser = new RegExp(r'^([^:]+):(.+)$'); + final List skipped = []; + for (String line in frames) { + Match match = stackParser.firstMatch(line); + if (match != null) { + assert(match.groupCount == 2); + if (filteredPackages.contains(match.group(2))) { + Match packageMatch = packageParser.firstMatch(match.group(2)); + if (packageMatch != null && packageMatch.group(1) == 'package') { + skipped.add('package ${packageMatch.group(2)}'); // avoid "package package:foo" + } else { + skipped.add('package ${match.group(2)}'); + } + continue; + } + if (filteredClasses.contains(match.group(1))) { + skipped.add('class ${match.group(1)}'); + continue; + } + } + result.add(line); + } + if (skipped == 1) { + result.add('(elided one frame from ${skipped.single})'); + } else if (skipped.length > 1) { + List where = new Set.from(skipped).toList()..sort(); + if (where.length > 1) + where[where.length - 1] = 'and ${where.last}'; + if (where.length > 2) { + result.add('(elided ${skipped.length} frames from ${where.join(", ")})'); + } else { + result.add('(elided ${skipped.length} frames from ${where.join(" ")})'); + } + } + return result; + } + /// Calls [onError] with the given details, unless it is null. static void reportError(FlutterErrorDetails details) { assert(details != null); diff --git a/packages/flutter/lib/src/foundation/basic_types.dart b/packages/flutter/lib/src/foundation/basic_types.dart index 70a389b07f..0d4a98e4f2 100644 --- a/packages/flutter/lib/src/foundation/basic_types.dart +++ b/packages/flutter/lib/src/foundation/basic_types.dart @@ -25,6 +25,9 @@ typedef void ValueSetter(T value); /// See also [ValueSetter]. typedef T ValueGetter(); +/// Signature for callbacks that filter an iterable. +typedef Iterable IterableFilter(Iterable input); + /// A BitField over an enum (or other class whose values implement "index"). /// Only the first 63 values of the enum can be used as indices. class BitField { diff --git a/packages/flutter/lib/src/material/progress_indicator.dart b/packages/flutter/lib/src/material/progress_indicator.dart index 9a6a4178c0..a29f308d8e 100644 --- a/packages/flutter/lib/src/material/progress_indicator.dart +++ b/packages/flutter/lib/src/material/progress_indicator.dart @@ -62,7 +62,11 @@ abstract class ProgressIndicator extends StatefulWidget { @override void debugFillDescription(List description) { super.debugFillDescription(description); - description.add('${(value.clamp(0.0, 1.0) * 100.0).toStringAsFixed(1)}%'); + if (value != null) { + description.add('${(value.clamp(0.0, 1.0) * 100.0).toStringAsFixed(1)}%'); + } else { + description.add(''); + } } } diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 04434fa192..0256019bf9 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -497,6 +497,13 @@ class TabBarSelection extends StatefulWidget { static TabBarSelectionState of/**/(BuildContext context) { return context.ancestorStateOfType(new TypeMatcher>()); } + + @override + void debugFillDescription(List description) { + super.debugFillDescription(description); + description.add('current tab: $value'); + description.add('available tabs: $values'); + } } class TabBarSelectionState extends State> { diff --git a/packages/flutter/lib/src/rendering/binding.dart b/packages/flutter/lib/src/rendering/binding.dart index cecd96482a..0cad857740 100644 --- a/packages/flutter/lib/src/rendering/binding.dart +++ b/packages/flutter/lib/src/rendering/binding.dart @@ -25,6 +25,7 @@ abstract class RendererBinding extends BindingBase implements SchedulerBinding, void initInstances() { super.initInstances(); _instance = this; + _pipelineOwner = new PipelineOwner(onNeedVisualUpdate: ensureVisualUpdate); ui.window.onMetricsChanged = handleMetricsChanged; initRenderView(); initSemantics(); @@ -78,16 +79,15 @@ abstract class RendererBinding extends BindingBase implements SchedulerBinding, /// /// Called automatically when the binding is created. void initRenderView() { - if (renderView == null) { - renderView = new RenderView(); - renderView.scheduleInitialFrame(); - } - handleMetricsChanged(); // configures renderView's metrics + assert(renderView == null); + renderView = new RenderView(configuration: createViewConfiguration()); + renderView.scheduleInitialFrame(); } /// The render tree's owner, which maintains dirty state for layout, /// composite, paint, and accessibility semantics - final PipelineOwner pipelineOwner = new PipelineOwner(); + PipelineOwner get pipelineOwner => _pipelineOwner; + PipelineOwner _pipelineOwner; /// The render tree that's attached to the output surface. RenderView get renderView => _renderView; @@ -109,7 +109,24 @@ abstract class RendererBinding extends BindingBase implements SchedulerBinding, /// See [ui.window.onMetricsChanged]. void handleMetricsChanged() { assert(renderView != null); - renderView.configuration = new ViewConfiguration(size: ui.window.size); + renderView.configuration = createViewConfiguration(); + } + + /// Returns a [ViewConfiguration] configured for the [RenderView] based on the + /// current environment. + /// + /// This is called during construction and also in response to changes to the + /// system metrics. + /// + /// Bindings can override this method to change what size or device pixel + /// ratio the [RenderView] will use. For example, the testing framework uses + /// this to force the display into 800x600 when a test is run on the device + /// using `flutter run`. + ViewConfiguration createViewConfiguration() { + return new ViewConfiguration( + size: ui.window.size, + devicePixelRatio: ui.window.devicePixelRatio + ); } /// Prepares the rendering library to handle semantics requests from the engine. diff --git a/packages/flutter/lib/src/rendering/image.dart b/packages/flutter/lib/src/rendering/image.dart index f9d58628c1..67ec2e32f1 100644 --- a/packages/flutter/lib/src/rendering/image.dart +++ b/packages/flutter/lib/src/rendering/image.dart @@ -164,7 +164,7 @@ class RenderImage extends RenderBox { /// - The RenderImage's dimension are maximal subject to being smaller than /// the intrinsic size of the image. Size _sizeForConstraints(BoxConstraints constraints) { - // Folds the given |width| and |height| into |cosntraints| so they can all + // Folds the given |width| and |height| into |constraints| so they can all // be treated uniformly. constraints = new BoxConstraints.tightFor( width: _width, diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 6765ae2071..545bebefc1 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -703,6 +703,13 @@ class _ForkingSemanticsFragment extends _SemanticsFragment { } class PipelineOwner { + PipelineOwner({ this.onNeedVisualUpdate }); + final VoidCallback onNeedVisualUpdate; + + void requestVisualUpdate() { + if (onNeedVisualUpdate != null) + onNeedVisualUpdate(); + } List _nodesNeedingLayout = []; bool _debugDoingLayout = false; @@ -1094,9 +1101,10 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { debugPrintStack(); return true; }); - if (owner != null) + if (owner != null) { owner._nodesNeedingLayout.add(this); - RendererBinding.instance.ensureVisualUpdate(); + owner.requestVisualUpdate(); + } } } @@ -1502,9 +1510,10 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { // If we always have our own layer, then we can just repaint // ourselves without involving any other nodes. assert(_layer != null); - if (owner != null) + if (owner != null) { owner._nodesNeedingPaint.add(this); - RendererBinding.instance.ensureVisualUpdate(); + owner.requestVisualUpdate(); + } } else if (parent is RenderObject) { // We don't have our own layer; one of our ancestors will take // care of updating the layer we're in and when they do that @@ -1518,7 +1527,8 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { // then we have to paint ourselves, since nobody else can paint // us. We don't add ourselves to _nodesNeedingPaint in this // case, because the root is always told to paint regardless. - RendererBinding.instance.ensureVisualUpdate(); + if (owner != null) + owner.requestVisualUpdate(); } } @@ -1538,6 +1548,22 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { assert(_needsPaint); owner._nodesNeedingPaint.add(this); } + + /// Replace the layer. This is only valid for the root of a render + /// object subtree (whatever object [scheduleInitialPaint] was + /// called on). + /// + /// This might be called if, e.g., the device pixel ratio changed. + void replaceRootLayer(ContainerLayer rootLayer) { + assert(attached); + assert(parent is! RenderObject); + assert(!owner._debugDoingPaint); + assert(isRepaintBoundary); + assert(_layer != null); // use scheduleInitialPaint the first time + _layer = rootLayer; + markNeedsPaint(); + } + void _paintWithContext(PaintingContext context, Offset offset) { assert(!_debugDoingThisPaint); assert(!_needsLayout); @@ -1636,7 +1662,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { assert(owner._semanticsEnabled == false); owner._semanticsEnabled = true; owner._nodesNeedingSemantics.add(this); - RendererBinding.instance.ensureVisualUpdate(); + owner.requestVisualUpdate(); } /// Whether this RenderObject introduces a new box for accessibility purposes. diff --git a/packages/flutter/lib/src/rendering/view.dart b/packages/flutter/lib/src/rendering/view.dart index 7d8a188ac5..44dcbede73 100644 --- a/packages/flutter/lib/src/rendering/view.dart +++ b/packages/flutter/lib/src/rendering/view.dart @@ -17,17 +17,26 @@ import 'binding.dart'; class ViewConfiguration { const ViewConfiguration({ this.size: Size.zero, + this.devicePixelRatio: 1.0, this.orientation }); /// The size of the output surface. final Size size; + /// The pixel density of the output surface. + final double devicePixelRatio; + /// The orientation of the output surface (aspirational). final int orientation; + /// Creates a transformation matrix that applies the [devicePixelRatio]. + Matrix4 toMatrix() { + return new Matrix4.diagonal3Values(devicePixelRatio, devicePixelRatio, 1.0); + } + @override - String toString() => '$size'; + String toString() => '$size at ${devicePixelRatio}x'; } /// The root of the render tree. @@ -38,8 +47,9 @@ class ViewConfiguration { class RenderView extends RenderObject with RenderObjectWithChildMixin { RenderView({ RenderBox child, - this.timeForRotation: const Duration(microseconds: 83333) - }) { + this.timeForRotation: const Duration(microseconds: 83333), + ViewConfiguration configuration + }) : _configuration = configuration { this.child = child; } @@ -61,19 +71,16 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin if (configuration == value) return; _configuration = value; + replaceRootLayer(new TransformLayer(transform: _configuration.toMatrix())); markNeedsLayout(); } - Matrix4 get _logicalToDeviceTransform { - double devicePixelRatio = ui.window.devicePixelRatio; - return new Matrix4.diagonal3Values(devicePixelRatio, devicePixelRatio, 1.0); - } - /// Bootstrap the rendering pipeline by scheduling the first frame. void scheduleInitialFrame() { + assert(owner != null); scheduleInitialLayout(); - scheduleInitialPaint(new TransformLayer(transform: _logicalToDeviceTransform)); - RendererBinding.instance.ensureVisualUpdate(); + scheduleInitialPaint(new TransformLayer(transform: _configuration.toMatrix())); + owner.requestVisualUpdate(); } // We never call layout() on this class, so this should never get @@ -127,11 +134,8 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin void compositeFrame() { Timeline.startSync('Compositing'); try { - final TransformLayer transformLayer = layer; - transformLayer.transform = _logicalToDeviceTransform; ui.SceneBuilder builder = new ui.SceneBuilder(); - transformLayer.addToScene(builder, Offset.zero); - assert(layer == transformLayer); + layer.addToScene(builder, Offset.zero); ui.Scene scene = builder.build(); ui.window.render(scene); scene.dispose(); diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index 0ed95fef4b..3fabe9d69d 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart @@ -308,10 +308,12 @@ abstract class SchedulerBinding extends BindingBase { _postFrameCallbacks.add(callback); } - // Whether this scheduler as requested that handleBeginFrame be called soon. + /// Whether this scheduler as requested that handleBeginFrame be called soon. + bool get hasScheduledFrame => _hasScheduledFrame; bool _hasScheduledFrame = false; - // Whether this scheduler is currently producing a frame in handleBeginFrame. + /// Whether this scheduler is currently producing a frame in [handleBeginFrame]. + bool get isProducingFrame => _isProducingFrame; bool _isProducingFrame = false; /// If necessary, schedules a new frame by calling diff --git a/packages/flutter/test/foundation/caching_iterable_test.dart b/packages/flutter/test/foundation/caching_iterable_test.dart index f935b37154..3a36579a4c 100644 --- a/packages/flutter/test/foundation/caching_iterable_test.dart +++ b/packages/flutter/test/foundation/caching_iterable_test.dart @@ -20,7 +20,7 @@ void main() { yieldCount = 0; }); - test("The Caching Iterable: length caches", () { + test('The Caching Iterable: length caches', () { Iterable i = new CachingIterable(range(1, 5).iterator); expect(yieldCount, equals(0)); expect(i.length, equals(5)); @@ -36,7 +36,7 @@ void main() { expect(yieldCount, equals(5)); }); - test("The Caching Iterable: laziness", () { + test('The Caching Iterable: laziness', () { Iterable i = new CachingIterable(range(1, 5).iterator); expect(yieldCount, equals(0)); @@ -50,7 +50,7 @@ void main() { expect(yieldCount, equals(5)); }); - test("The Caching Iterable: where and map", () { + test('The Caching Iterable: where and map', () { Iterable integers = new CachingIterable(range(1, 5).iterator); expect(yieldCount, equals(0)); diff --git a/packages/flutter/test/foundation/stack_trace_test.dart b/packages/flutter/test/foundation/stack_trace_test.dart new file mode 100644 index 0000000000..bed9deeb89 --- /dev/null +++ b/packages/flutter/test/foundation/stack_trace_test.dart @@ -0,0 +1,24 @@ +// Copyright 2016 The Chromium 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/foundation.dart'; +import 'package:test/test.dart'; + +void main() { + test('FlutterError.defaultStackFilter', () { + List filtered = FlutterError.defaultStackFilter(StackTrace.current.toString().trimRight().split('\n')).toList(); + expect(filtered.length, 4); + expect(filtered[0], matches(r'^#0 +main\. \(.*stack_trace_test\.dart:[0-9]+:[0-9]+\)$')); + expect(filtered[1], matches(r'^#1 +Declarer\.test\.\.<_async_body>\.\.<_async_body> \(package:test/.+:[0-9]+:[0-9]+\)$')); + expect(filtered[2], matches(r'^#[1-9][0-9]+ +Declarer\._runSetUps\.<_runSetUps_async_body> \(package:test/.+:[0-9]+:[0-9]+\)$')); + expect(filtered[3], matches(r'^\(elided [1-9][0-9]+ frames from package dart:async, package dart:async-patch, and package stack_trace\)$')); + }); + + test('FlutterError.defaultStackFilter (async test body)', () async { + List filtered = FlutterError.defaultStackFilter(StackTrace.current.toString().trimRight().split('\n')).toList(); + expect(filtered.length, 2); + expect(filtered[0], matches(r'^#0 +main\.\.<_async_body> \(.*stack_trace_test\.dart:[0-9]+:[0-9]+\)$')); + expect(filtered[1], matches(r'^\(elided [1-9][0-9]+ frames from package dart:async and package stack_trace\)$')); + }); +} diff --git a/packages/flutter/test/gestures/pointer_router_test.dart b/packages/flutter/test/gestures/pointer_router_test.dart index c5c0582bfe..876c070029 100644 --- a/packages/flutter/test/gestures/pointer_router_test.dart +++ b/packages/flutter/test/gestures/pointer_router_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/gestures.dart'; -import 'package:test/test.dart'; void main() { test('Should route pointers', () { diff --git a/packages/flutter/test/gestures/scale_test.dart b/packages/flutter/test/gestures/scale_test.dart index 789b4f1c3e..d5af80dc1e 100644 --- a/packages/flutter/test/gestures/scale_test.dart +++ b/packages/flutter/test/gestures/scale_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/gestures.dart'; -import 'package:test/test.dart'; import 'gesture_tester.dart'; diff --git a/packages/flutter/test/gestures/scroll_test.dart b/packages/flutter/test/gestures/scroll_test.dart index 4db97935d3..4d623867d2 100644 --- a/packages/flutter/test/gestures/scroll_test.dart +++ b/packages/flutter/test/gestures/scroll_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/gestures.dart'; -import 'package:test/test.dart'; import 'gesture_tester.dart'; diff --git a/packages/flutter/test/material/drop_down_test.dart b/packages/flutter/test/material/drop_down_test.dart index f48d6a7ce6..d9c55754e1 100644 --- a/packages/flutter/test/material/drop_down_test.dart +++ b/packages/flutter/test/material/drop_down_test.dart @@ -4,10 +4,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Drop down screen edges', (WidgetTester tester) { + testWidgets('Drop down screen edges', (WidgetTester tester) async { int value = 4; List> items = >[]; for (int i = 0; i < 20; ++i) @@ -23,7 +22,7 @@ void main() { items: items ); - tester.pumpWidget( + await tester.pumpWidget( new MaterialApp( home: new Material( child: new Align( @@ -34,9 +33,9 @@ void main() { ) ); - tester.tap(find.text('4')); - tester.pump(); - tester.pump(const Duration(seconds: 1)); // finish the menu animation + await tester.tap(find.text('4')); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); // finish the menu animation // We should have two copies of item 5, one in the menu and one in the // button itself. @@ -46,7 +45,7 @@ void main() { // The copy in the menu shouldn't be in the tree because it's off-screen. expect(find.text('19').evaluate().length, 1); - tester.tap(find.byConfig(button)); + await tester.tap(find.byConfig(button)); // Ideally this would be 4 because the menu would be overscrolled to the // correct position, but currently we just reposition the menu so that it @@ -55,8 +54,8 @@ void main() { // TODO(abarth): Remove these calls to pump once navigator cleans up its // pop transitions. - tester.pump(); - tester.pump(const Duration(seconds: 1)); // finish the menu animation + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); // finish the menu animation }); } diff --git a/packages/flutter/test/material/progress_indicator_test.dart b/packages/flutter/test/material/progress_indicator_test.dart index 6be3e23677..389a4d9995 100644 --- a/packages/flutter/test/material/progress_indicator_test.dart +++ b/packages/flutter/test/material/progress_indicator_test.dart @@ -5,15 +5,14 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { // The "can be constructed" tests that follow are primarily to ensure that any // animations started by the progress indicators are stopped at dispose() time. - testWidgets('LinearProgressIndicator(value: 0.0) can be constructed', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('LinearProgressIndicator(value: 0.0) can be constructed', (WidgetTester tester) async { + await tester.pumpWidget( new Center( child: new SizedBox( width: 200.0, @@ -23,8 +22,8 @@ void main() { ); }); - testWidgets('LinearProgressIndicator(value: null) can be constructed', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('LinearProgressIndicator(value: null) can be constructed', (WidgetTester tester) async { + await tester.pumpWidget( new Center( child: new SizedBox( width: 200.0, @@ -34,26 +33,26 @@ void main() { ); }); - testWidgets('CircularProgressIndicator(value: 0.0) can be constructed', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('CircularProgressIndicator(value: 0.0) can be constructed', (WidgetTester tester) async { + await tester.pumpWidget( new Center( child: new CircularProgressIndicator(value: 0.0) ) ); }); - testWidgets('CircularProgressIndicator(value: null) can be constructed', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('CircularProgressIndicator(value: null) can be constructed', (WidgetTester tester) async { + await tester.pumpWidget( new Center( child: new CircularProgressIndicator(value: null) ) ); }); - testWidgets('LinearProgressIndicator causes a repaint when it changes', (WidgetTester tester) { - tester.pumpWidget(new Block(children: [new LinearProgressIndicator(value: 0.0)])); + testWidgets('LinearProgressIndicator causes a repaint when it changes', (WidgetTester tester) async { + await tester.pumpWidget(new Block(children: [new LinearProgressIndicator(value: 0.0)])); List layers1 = tester.layers; - tester.pumpWidget(new Block(children: [new LinearProgressIndicator(value: 0.5)])); + await tester.pumpWidget(new Block(children: [new LinearProgressIndicator(value: 0.5)])); List layers2 = tester.layers; expect(layers1, isNot(equals(layers2))); }); diff --git a/packages/flutter/test/material/refresh_indicator_test.dart b/packages/flutter/test/material/refresh_indicator_test.dart index fb5cfbb95d..7ba299cdf0 100644 --- a/packages/flutter/test/material/refresh_indicator_test.dart +++ b/packages/flutter/test/material/refresh_indicator_test.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { @@ -17,8 +16,8 @@ void main() { return new Future.value(); } - testWidgets('RefreshIndicator', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('RefreshIndicator', (WidgetTester tester) async { + await tester.pumpWidget( new RefreshIndicator( refresh: refresh, child: new Block( @@ -32,11 +31,11 @@ void main() { ) ); - tester.fling(find.text('A'), const Offset(0.0, 200.0), -1000.0); - tester.pump(); - tester.pump(const Duration(seconds: 1)); // finish the scroll animation - tester.pump(const Duration(seconds: 1)); // finish the indicator settle animation - tester.pump(const Duration(seconds: 1)); // finish the indicator hide animation + await tester.fling(find.text('A'), const Offset(0.0, 200.0), -1000.0); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); // finish the scroll animation + await tester.pump(const Duration(seconds: 1)); // finish the indicator settle animation + await tester.pump(const Duration(seconds: 1)); // finish the indicator hide animation expect(refreshCalled, true); }); } diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart index fdd414890f..6fac3b7ec9 100644 --- a/packages/flutter/test/material/scaffold_test.dart +++ b/packages/flutter/test/material/scaffold_test.dart @@ -5,12 +5,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Scaffold control test', (WidgetTester tester) { + testWidgets('Scaffold control test', (WidgetTester tester) async { Key bodyKey = new UniqueKey(); - tester.pumpWidget(new Scaffold( + await tester.pumpWidget(new Scaffold( appBar: new AppBar(title: new Text('Title')), body: new Container(key: bodyKey) )); @@ -18,7 +17,7 @@ void main() { RenderBox bodyBox = tester.renderObject(find.byKey(bodyKey)); expect(bodyBox.size, equals(new Size(800.0, 544.0))); - tester.pumpWidget(new MediaQuery( + await tester.pumpWidget(new MediaQuery( data: new MediaQueryData(padding: new EdgeInsets.only(bottom: 100.0)), child: new Scaffold( appBar: new AppBar(title: new Text('Title')), @@ -29,7 +28,7 @@ void main() { bodyBox = tester.renderObject(find.byKey(bodyKey)); expect(bodyBox.size, equals(new Size(800.0, 444.0))); - tester.pumpWidget(new MediaQuery( + await tester.pumpWidget(new MediaQuery( data: new MediaQueryData(padding: new EdgeInsets.only(bottom: 100.0)), child: new Scaffold( appBar: new AppBar(title: new Text('Title')), diff --git a/packages/flutter/test/material/slider_test.dart b/packages/flutter/test/material/slider_test.dart index ea5f181b84..5de33bc548 100644 --- a/packages/flutter/test/material/slider_test.dart +++ b/packages/flutter/test/material/slider_test.dart @@ -5,14 +5,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Slider can move when tapped', (WidgetTester tester) { + testWidgets('Slider can move when tapped', (WidgetTester tester) async { Key sliderKey = new UniqueKey(); double value = 0.0; - tester.pumpWidget( + await tester.pumpWidget( new StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return new Material( @@ -33,17 +32,17 @@ void main() { ); expect(value, equals(0.0)); - tester.tap(find.byKey(sliderKey)); + await tester.tap(find.byKey(sliderKey)); expect(value, equals(0.5)); - tester.pump(); // No animation should start. + await tester.pump(); // No animation should start. expect(SchedulerBinding.instance.transientCallbackCount, equals(0)); }); - testWidgets('Slider take on discrete values', (WidgetTester tester) { + testWidgets('Slider take on discrete values', (WidgetTester tester) async { Key sliderKey = new UniqueKey(); double value = 0.0; - tester.pumpWidget( + await tester.pumpWidget( new StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return new Material( @@ -67,19 +66,19 @@ void main() { ); expect(value, equals(0.0)); - tester.tap(find.byKey(sliderKey)); + await tester.tap(find.byKey(sliderKey)); expect(value, equals(50.0)); - tester.scroll(find.byKey(sliderKey), const Offset(5.0, 0.0)); + await tester.scroll(find.byKey(sliderKey), const Offset(5.0, 0.0)); expect(value, equals(50.0)); - tester.scroll(find.byKey(sliderKey), const Offset(40.0, 0.0)); + await tester.scroll(find.byKey(sliderKey), const Offset(40.0, 0.0)); expect(value, equals(80.0)); - tester.pump(); // Starts animation. + await tester.pump(); // Starts animation. expect(SchedulerBinding.instance.transientCallbackCount, greaterThan(0)); - tester.pump(const Duration(milliseconds: 200)); - tester.pump(const Duration(milliseconds: 200)); - tester.pump(const Duration(milliseconds: 200)); - tester.pump(const Duration(milliseconds: 200)); + await tester.pump(const Duration(milliseconds: 200)); + await tester.pump(const Duration(milliseconds: 200)); + await tester.pump(const Duration(milliseconds: 200)); + await tester.pump(const Duration(milliseconds: 200)); // Animation complete. expect(SchedulerBinding.instance.transientCallbackCount, equals(0)); }); diff --git a/packages/flutter/test/material/snack_bar_test.dart b/packages/flutter/test/material/snack_bar_test.dart index c28da981fc..8a10348ba5 100644 --- a/packages/flutter/test/material/snack_bar_test.dart +++ b/packages/flutter/test/material/snack_bar_test.dart @@ -4,13 +4,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('SnackBar control test', (WidgetTester tester) { + testWidgets('SnackBar control test', (WidgetTester tester) async { String helloSnackBar = 'Hello SnackBar'; Key tapTarget = new Key('tap-target'); - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Scaffold( body: new Builder( builder: (BuildContext context) { @@ -33,29 +32,29 @@ void main() { ) )); expect(find.text(helloSnackBar), findsNothing); - tester.tap(find.byKey(tapTarget)); + await tester.tap(find.byKey(tapTarget)); expect(find.text(helloSnackBar), findsNothing); - tester.pump(); // schedule animation + await tester.pump(); // schedule animation expect(find.text(helloSnackBar), findsOneWidget); - tester.pump(); // begin animation + await tester.pump(); // begin animation expect(find.text(helloSnackBar), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 0.75s // animation last frame; two second timer starts here + await tester.pump(new Duration(milliseconds: 750)); // 0.75s // animation last frame; two second timer starts here expect(find.text(helloSnackBar), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 1.50s + await tester.pump(new Duration(milliseconds: 750)); // 1.50s expect(find.text(helloSnackBar), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 2.25s + await tester.pump(new Duration(milliseconds: 750)); // 2.25s expect(find.text(helloSnackBar), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 3.00s // timer triggers to dismiss snackbar, reverse animation is scheduled - tester.pump(); // begin animation + await tester.pump(new Duration(milliseconds: 750)); // 3.00s // timer triggers to dismiss snackbar, reverse animation is scheduled + await tester.pump(); // begin animation expect(find.text(helloSnackBar), findsOneWidget); // frame 0 of dismiss animation - tester.pump(new Duration(milliseconds: 750)); // 3.75s // last frame of animation, snackbar removed from build + await tester.pump(new Duration(milliseconds: 750)); // 3.75s // last frame of animation, snackbar removed from build expect(find.text(helloSnackBar), findsNothing); }); - testWidgets('SnackBar twice test', (WidgetTester tester) { + testWidgets('SnackBar twice test', (WidgetTester tester) async { int snackBarCount = 0; Key tapTarget = new Key('tap-target'); - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Scaffold( body: new Builder( builder: (BuildContext context) { @@ -80,59 +79,59 @@ void main() { )); expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsNothing); - tester.tap(find.byKey(tapTarget)); // queue bar1 - tester.tap(find.byKey(tapTarget)); // queue bar2 + await tester.tap(find.byKey(tapTarget)); // queue bar1 + await tester.tap(find.byKey(tapTarget)); // queue bar2 expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsNothing); - tester.pump(); // schedule animation for bar1 + await tester.pump(); // schedule animation for bar1 expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(); // begin animation + await tester.pump(); // begin animation expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 0.75s // animation last frame; two second timer starts here + await tester.pump(new Duration(milliseconds: 750)); // 0.75s // animation last frame; two second timer starts here expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 1.50s + await tester.pump(new Duration(milliseconds: 750)); // 1.50s expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 2.25s + await tester.pump(new Duration(milliseconds: 750)); // 2.25s expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 3.00s // timer triggers to dismiss snackbar, reverse animation is scheduled - tester.pump(); // begin animation + await tester.pump(new Duration(milliseconds: 750)); // 3.00s // timer triggers to dismiss snackbar, reverse animation is scheduled + await tester.pump(); // begin animation expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 3.75s // last frame of animation, snackbar removed from build, new snack bar put in its place + await tester.pump(new Duration(milliseconds: 750)); // 3.75s // last frame of animation, snackbar removed from build, new snack bar put in its place expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(); // begin animation + await tester.pump(); // begin animation expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 4.50s // animation last frame; two second timer starts here + await tester.pump(new Duration(milliseconds: 750)); // 4.50s // animation last frame; two second timer starts here expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 5.25s + await tester.pump(new Duration(milliseconds: 750)); // 5.25s expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 6.00s + await tester.pump(new Duration(milliseconds: 750)); // 6.00s expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 6.75s // timer triggers to dismiss snackbar, reverse animation is scheduled - tester.pump(); // begin animation + await tester.pump(new Duration(milliseconds: 750)); // 6.75s // timer triggers to dismiss snackbar, reverse animation is scheduled + await tester.pump(); // begin animation expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 7.50s // last frame of animation, snackbar removed from build, new snack bar put in its place + await tester.pump(new Duration(milliseconds: 750)); // 7.50s // last frame of animation, snackbar removed from build, new snack bar put in its place expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsNothing); }); - testWidgets('SnackBar cancel test', (WidgetTester tester) { + testWidgets('SnackBar cancel test', (WidgetTester tester) async { int snackBarCount = 0; Key tapTarget = new Key('tap-target'); int time; ScaffoldFeatureController lastController; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Scaffold( body: new Builder( builder: (BuildContext context) { @@ -158,65 +157,65 @@ void main() { expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsNothing); time = 1000; - tester.tap(find.byKey(tapTarget)); // queue bar1 + await tester.tap(find.byKey(tapTarget)); // queue bar1 ScaffoldFeatureController firstController = lastController; time = 2; - tester.tap(find.byKey(tapTarget)); // queue bar2 + await tester.tap(find.byKey(tapTarget)); // queue bar2 expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsNothing); - tester.pump(); // schedule animation for bar1 + await tester.pump(); // schedule animation for bar1 expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(); // begin animation + await tester.pump(); // begin animation expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 0.75s // animation last frame; two second timer starts here + await tester.pump(new Duration(milliseconds: 750)); // 0.75s // animation last frame; two second timer starts here expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 1.50s + await tester.pump(new Duration(milliseconds: 750)); // 1.50s expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 2.25s + await tester.pump(new Duration(milliseconds: 750)); // 2.25s expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 10000)); // 12.25s + await tester.pump(new Duration(milliseconds: 10000)); // 12.25s expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); firstController.close(); // snackbar is manually dismissed - tester.pump(new Duration(milliseconds: 750)); // 13.00s // reverse animation is scheduled - tester.pump(); // begin animation + await tester.pump(new Duration(milliseconds: 750)); // 13.00s // reverse animation is scheduled + await tester.pump(); // begin animation expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 13.75s // last frame of animation, snackbar removed from build, new snack bar put in its place + await tester.pump(new Duration(milliseconds: 750)); // 13.75s // last frame of animation, snackbar removed from build, new snack bar put in its place expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(); // begin animation + await tester.pump(); // begin animation expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 14.50s // animation last frame; two second timer starts here + await tester.pump(new Duration(milliseconds: 750)); // 14.50s // animation last frame; two second timer starts here expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 15.25s + await tester.pump(new Duration(milliseconds: 750)); // 15.25s expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 16.00s + await tester.pump(new Duration(milliseconds: 750)); // 16.00s expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 16.75s // timer triggers to dismiss snackbar, reverse animation is scheduled - tester.pump(); // begin animation + await tester.pump(new Duration(milliseconds: 750)); // 16.75s // timer triggers to dismiss snackbar, reverse animation is scheduled + await tester.pump(); // begin animation expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); - tester.pump(new Duration(milliseconds: 750)); // 17.50s // last frame of animation, snackbar removed from build, new snack bar put in its place + await tester.pump(new Duration(milliseconds: 750)); // 17.50s // last frame of animation, snackbar removed from build, new snack bar put in its place expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsNothing); }); - testWidgets('SnackBar dismiss test', (WidgetTester tester) { + testWidgets('SnackBar dismiss test', (WidgetTester tester) async { int snackBarCount = 0; Key tapTarget = new Key('tap-target'); - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Scaffold( body: new Builder( builder: (BuildContext context) { @@ -241,26 +240,26 @@ void main() { )); expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsNothing); - tester.tap(find.byKey(tapTarget)); // queue bar1 - tester.tap(find.byKey(tapTarget)); // queue bar2 + await tester.tap(find.byKey(tapTarget)); // queue bar1 + await tester.tap(find.byKey(tapTarget)); // queue bar2 expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsNothing); - tester.pump(); // schedule animation for bar1 + await tester.pump(); // schedule animation for bar1 expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(); // begin animation + await tester.pump(); // begin animation expect(find.text('bar1'), findsOneWidget); expect(find.text('bar2'), findsNothing); - tester.pump(new Duration(milliseconds: 750)); // 0.75s // animation last frame; two second timer starts here - tester.scroll(find.text('bar1'), new Offset(0.0, 50.0)); - tester.pump(); // bar1 dismissed, bar2 begins animating + await tester.pump(new Duration(milliseconds: 750)); // 0.75s // animation last frame; two second timer starts here + await tester.scroll(find.text('bar1'), new Offset(0.0, 50.0)); + await tester.pump(); // bar1 dismissed, bar2 begins animating expect(find.text('bar1'), findsNothing); expect(find.text('bar2'), findsOneWidget); }); - testWidgets('SnackBar cannot be tapped twice', (WidgetTester tester) { + testWidgets('SnackBar cannot be tapped twice', (WidgetTester tester) async { int tapCount = 0; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Scaffold( body: new Builder( builder: (BuildContext context) { @@ -283,17 +282,17 @@ void main() { ) ) )); - tester.tap(find.text('X')); - tester.pump(); // start animation - tester.pump(const Duration(milliseconds: 750)); + await tester.tap(find.text('X')); + await tester.pump(); // start animation + await tester.pump(const Duration(milliseconds: 750)); expect(tapCount, equals(0)); - tester.tap(find.text('ACTION')); + await tester.tap(find.text('ACTION')); expect(tapCount, equals(1)); - tester.tap(find.text('ACTION')); + await tester.tap(find.text('ACTION')); expect(tapCount, equals(1)); - tester.pump(); - tester.tap(find.text('ACTION')); + await tester.pump(); + await tester.tap(find.text('ACTION')); expect(tapCount, equals(1)); }); } diff --git a/packages/flutter/test/material/tabs_test.dart b/packages/flutter/test/material/tabs_test.dart index d394758422..d7cd51182f 100644 --- a/packages/flutter/test/material/tabs_test.dart +++ b/packages/flutter/test/material/tabs_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class StateMarker extends StatefulWidget { StateMarker({ Key key, this.child }) : super(key: key); @@ -42,10 +41,10 @@ Widget buildFrame({ List tabs, String value, bool isScrollable: false, K } void main() { - testWidgets('TabBar tap selects tab', (WidgetTester tester) { + testWidgets('TabBar tap selects tab', (WidgetTester tester) async { List tabs = ['A', 'B', 'C']; - tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: false)); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: false)); TabBarSelectionState selection = TabBarSelection.of(tester.element(find.text('A'))); expect(selection, isNotNull); expect(selection.indexOf('A'), equals(0)); @@ -59,40 +58,40 @@ void main() { expect(selection.value, equals('C')); expect(selection.previousValue, equals('C')); - tester.pumpWidget(buildFrame(tabs: tabs, value: 'C' ,isScrollable: false)); - tester.tap(find.text('B')); - tester.pump(); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C' ,isScrollable: false)); + await tester.tap(find.text('B')); + await tester.pump(); expect(selection.valueIsChanging, true); - tester.pump(const Duration(seconds: 1)); // finish the animation + await tester.pump(const Duration(seconds: 1)); // finish the animation expect(selection.valueIsChanging, false); expect(selection.value, equals('B')); expect(selection.previousValue, equals('C')); expect(selection.index, equals(1)); expect(selection.previousIndex, equals(2)); - tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: false)); - tester.tap(find.text('C')); - tester.pump(); - tester.pump(const Duration(seconds: 1)); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: false)); + await tester.tap(find.text('C')); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); expect(selection.value, equals('C')); expect(selection.previousValue, equals('B')); expect(selection.index, equals(2)); expect(selection.previousIndex, equals(1)); - tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: false)); - tester.tap(find.text('A')); - tester.pump(); - tester.pump(const Duration(seconds: 1)); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: false)); + await tester.tap(find.text('A')); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); expect(selection.value, equals('A')); expect(selection.previousValue, equals('C')); expect(selection.index, equals(0)); expect(selection.previousIndex, equals(2)); }); - testWidgets('Scrollable TabBar tap selects tab', (WidgetTester tester) { + testWidgets('Scrollable TabBar tap selects tab', (WidgetTester tester) async { List tabs = ['A', 'B', 'C']; - tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true)); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true)); TabBarSelectionState selection = TabBarSelection.of(tester.element(find.text('A'))); expect(selection, isNotNull); expect(find.text('A'), findsOneWidget); @@ -100,26 +99,26 @@ void main() { expect(find.text('C'), findsOneWidget); expect(selection.value, equals('C')); - tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true)); - tester.tap(find.text('B')); - tester.pump(); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true)); + await tester.tap(find.text('B')); + await tester.pump(); expect(selection.value, equals('B')); - tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true)); - tester.tap(find.text('C')); - tester.pump(); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true)); + await tester.tap(find.text('C')); + await tester.pump(); expect(selection.value, equals('C')); - tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true)); - tester.tap(find.text('A')); - tester.pump(); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true)); + await tester.tap(find.text('A')); + await tester.pump(); expect(selection.value, equals('A')); }); - testWidgets('Scrollable TabBar tap centers selected tab', (WidgetTester tester) { + testWidgets('Scrollable TabBar tap centers selected tab', (WidgetTester tester) async { List tabs = ['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL']; Key tabBarKey = new Key('TabBar'); - tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey)); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey)); TabBarSelectionState selection = TabBarSelection.of(tester.element(find.text('AAAAAA'))); expect(selection, isNotNull); expect(selection.value, equals('AAAAAA')); @@ -128,35 +127,35 @@ void main() { // The center of the FFFFFF item is to the right of the TabBar's center expect(tester.getCenter(find.text('FFFFFF')).x, greaterThan(401.0)); - tester.tap(find.text('FFFFFF')); - tester.pump(); - tester.pump(const Duration(seconds: 1)); // finish the scroll animation + await tester.tap(find.text('FFFFFF')); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); // finish the scroll animation expect(selection.value, equals('FFFFFF')); // The center of the FFFFFF item is now at the TabBar's center expect(tester.getCenter(find.text('FFFFFF')).x, closeTo(400.0, 1.0)); }); - testWidgets('TabBar can be scrolled independent of the selection', (WidgetTester tester) { + testWidgets('TabBar can be scrolled independent of the selection', (WidgetTester tester) async { List tabs = ['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL']; Key tabBarKey = new Key('TabBar'); - tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey)); + await tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey)); TabBarSelectionState selection = TabBarSelection.of(tester.element(find.text('AAAAAA'))); expect(selection, isNotNull); expect(selection.value, equals('AAAAAA')); // Fling-scroll the TabBar to the left expect(tester.getCenter(find.text('HHHHHH')).x, lessThan(700.0)); - tester.fling(find.byKey(tabBarKey), const Offset(-20.0, 0.0), 1000.0); - tester.pump(); - tester.pump(const Duration(seconds: 1)); // finish the scroll animation + await tester.fling(find.byKey(tabBarKey), const Offset(-20.0, 0.0), 1000.0); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); // finish the scroll animation expect(tester.getCenter(find.text('HHHHHH')).x, lessThan(500.0)); // Scrolling the TabBar doesn't change the selection expect(selection.value, equals('AAAAAA')); }); - testWidgets('TabView maintains state', (WidgetTester tester) { + testWidgets('TabView maintains state', (WidgetTester tester) async { List tabs = ['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE']; String value = tabs[0]; @@ -185,29 +184,29 @@ void main() { return tester.state(find.widgetWithText(StateMarker, name)); } - tester.pumpWidget(builder()); - TestGesture gesture = tester.startGesture(tester.getCenter(find.text(tabs[0]))); - gesture.moveBy(new Offset(-600.0, 0.0)); - tester.pump(); + await tester.pumpWidget(builder()); + TestGesture gesture = await tester.startGesture(tester.getCenter(find.text(tabs[0]))); + await gesture.moveBy(new Offset(-600.0, 0.0)); + await tester.pump(); expect(value, equals(tabs[0])); findStateMarkerState(tabs[1]).marker = 'marked'; - gesture.up(); - tester.pump(); - tester.pump(const Duration(seconds: 1)); + await gesture.up(); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); expect(value, equals(tabs[1])); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); expect(findStateMarkerState(tabs[1]).marker, equals('marked')); // Move to the third tab. - gesture = tester.startGesture(tester.getCenter(find.text(tabs[1]))); - gesture.moveBy(new Offset(-600.0, 0.0)); - gesture.up(); - tester.pump(); + gesture = await tester.startGesture(tester.getCenter(find.text(tabs[1]))); + await gesture.moveBy(new Offset(-600.0, 0.0)); + await gesture.up(); + await tester.pump(); expect(findStateMarkerState(tabs[1]).marker, equals('marked')); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(value, equals(tabs[2])); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // The state is now gone. @@ -215,17 +214,17 @@ void main() { // Move back to the second tab. - gesture = tester.startGesture(tester.getCenter(find.text(tabs[2]))); - gesture.moveBy(new Offset(600.0, 0.0)); - tester.pump(); + gesture = await tester.startGesture(tester.getCenter(find.text(tabs[2]))); + await gesture.moveBy(new Offset(600.0, 0.0)); + await tester.pump(); StateMarkerState markerState = findStateMarkerState(tabs[1]); expect(markerState.marker, isNull); markerState.marker = 'marked'; - gesture.up(); - tester.pump(); - tester.pump(const Duration(seconds: 1)); + await gesture.up(); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); expect(value, equals(tabs[1])); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); expect(findStateMarkerState(tabs[1]).marker, equals('marked')); }); } diff --git a/packages/flutter/test/material/time_picker_test.dart b/packages/flutter/test/material/time_picker_test.dart index d2bb477ab6..6488566e4a 100644 --- a/packages/flutter/test/material/time_picker_test.dart +++ b/packages/flutter/test/material/time_picker_test.dart @@ -4,14 +4,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('tap-select an hour', (WidgetTester tester) { + testWidgets('tap-select an hour', (WidgetTester tester) async { Key _timePickerKey = new UniqueKey(); TimeOfDay _selectedTime = const TimeOfDay(hour: 7, minute: 0); - tester.pumpWidget( + await tester.pumpWidget( new StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return new Material( @@ -38,30 +37,30 @@ void main() { Point center = tester.getCenter(find.byKey(_timePickerKey)); Point hour0 = new Point(center.x, center.y - 50.0); // 12:00 AM - tester.tapAt(hour0); + await tester.tapAt(hour0); expect(_selectedTime.hour, equals(0)); Point hour3 = new Point(center.x + 50.0, center.y); - tester.tapAt(hour3); + await tester.tapAt(hour3); expect(_selectedTime.hour, equals(3)); Point hour6 = new Point(center.x, center.y + 50.0); - tester.tapAt(hour6); + await tester.tapAt(hour6); expect(_selectedTime.hour, equals(6)); Point hour9 = new Point(center.x - 50.0, center.y); - tester.tapAt(hour9); + await tester.tapAt(hour9); expect(_selectedTime.hour, equals(9)); - tester.pump(const Duration(seconds: 1)); // Finish gesture animation. - tester.pump(const Duration(seconds: 1)); // Finish settling animation. + await tester.pump(const Duration(seconds: 1)); // Finish gesture animation. + await tester.pump(const Duration(seconds: 1)); // Finish settling animation. }); - testWidgets('drag-select an hour', (WidgetTester tester) { + testWidgets('drag-select an hour', (WidgetTester tester) async { Key _timePickerKey = new UniqueKey(); TimeOfDay _selectedTime = const TimeOfDay(hour: 7, minute: 0); - tester.pumpWidget( + await tester.pumpWidget( new StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return new Material( @@ -91,32 +90,34 @@ void main() { Point hour6 = new Point(center.x, center.y + 50.0); Point hour9 = new Point(center.x - 50.0, center.y); - tester.startGesture(hour3) - ..moveBy(hour0 - hour3) - ..up(); + TestGesture gesture; + + gesture = await tester.startGesture(hour3); + await gesture.moveBy(hour0 - hour3); + await gesture.up(); expect(_selectedTime.hour, equals(0)); - tester.pump(const Duration(seconds: 1)); // Finish gesture animation. - tester.pump(const Duration(seconds: 1)); // Finish settling animation. + await tester.pump(const Duration(seconds: 1)); // Finish gesture animation. + await tester.pump(const Duration(seconds: 1)); // Finish settling animation. - tester.startGesture(hour0) - ..moveBy(hour3 - hour0) - ..up(); + gesture = await tester.startGesture(hour0); + await gesture.moveBy(hour3 - hour0); + await gesture.up(); expect(_selectedTime.hour, equals(3)); - tester.pump(const Duration(seconds: 1)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); - tester.startGesture(hour3) - ..moveBy(hour6 - hour3) - ..up(); + gesture = await tester.startGesture(hour3); + await gesture.moveBy(hour6 - hour3); + await gesture.up(); expect(_selectedTime.hour, equals(6)); - tester.pump(const Duration(seconds: 1)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); - tester.startGesture(hour6) - ..moveBy(hour9 - hour6) - ..up(); + gesture = await tester.startGesture(hour6); + await gesture.moveBy(hour9 - hour6); + await gesture.up(); expect(_selectedTime.hour, equals(9)); - tester.pump(const Duration(seconds: 1)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); }); } diff --git a/packages/flutter/test/material/tooltip_test.dart b/packages/flutter/test/material/tooltip_test.dart index 56a087539c..1e7936c6ae 100644 --- a/packages/flutter/test/material/tooltip_test.dart +++ b/packages/flutter/test/material/tooltip_test.dart @@ -6,7 +6,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import '../widget/test_semantics.dart'; @@ -26,9 +25,9 @@ import '../widget/test_semantics.dart'; // production code. void main() { - testWidgets('Does tooltip end up in the right place - center', (WidgetTester tester) { + testWidgets('Does tooltip end up in the right place - center', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Overlay( initialEntries: [ new OverlayEntry( @@ -62,7 +61,7 @@ void main() { ) ); (key.currentState as dynamic).showTooltip(); // before using "as dynamic" in your code, see note top of file - tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) + await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) /********************* 800x600 screen * o * y=0 @@ -77,9 +76,9 @@ void main() { expect(tip.localToGlobal(tip.size.topLeft(Point.origin)), equals(const Point(284.0, 20.0))); }); - testWidgets('Does tooltip end up in the right place - top left', (WidgetTester tester) { + testWidgets('Does tooltip end up in the right place - top left', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Overlay( initialEntries: [ new OverlayEntry( @@ -113,7 +112,7 @@ void main() { ) ); (key.currentState as dynamic).showTooltip(); // before using "as dynamic" in your code, see note top of file - tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) + await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) /********************* 800x600 screen *o * y=0 @@ -129,9 +128,9 @@ void main() { expect(tip.localToGlobal(tip.size.topLeft(Point.origin)), equals(const Point(10.0, 20.0))); }); - testWidgets('Does tooltip end up in the right place - center prefer above fits', (WidgetTester tester) { + testWidgets('Does tooltip end up in the right place - center prefer above fits', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Overlay( initialEntries: [ new OverlayEntry( @@ -165,7 +164,7 @@ void main() { ) ); (key.currentState as dynamic).showTooltip(); // before using "as dynamic" in your code, see note top of file - tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) + await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) /********************* 800x600 screen * ___ * }-100.0 margin @@ -183,9 +182,9 @@ void main() { expect(tip.localToGlobal(tip.size.bottomRight(Point.origin)).y, equals(200.0)); }); - testWidgets('Does tooltip end up in the right place - center prefer above does not fit', (WidgetTester tester) { + testWidgets('Does tooltip end up in the right place - center prefer above does not fit', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Overlay( initialEntries: [ new OverlayEntry( @@ -219,7 +218,7 @@ void main() { ) ); (key.currentState as dynamic).showTooltip(); // before using "as dynamic" in your code, see note top of file - tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) + await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) // we try to put it here but it doesn't fit: /********************* 800x600 screen @@ -248,9 +247,9 @@ void main() { expect(tip.localToGlobal(tip.size.bottomRight(Point.origin)).y, equals(499.0)); }); - testWidgets('Does tooltip end up in the right place - center prefer below fits', (WidgetTester tester) { + testWidgets('Does tooltip end up in the right place - center prefer below fits', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Overlay( initialEntries: [ new OverlayEntry( @@ -284,7 +283,7 @@ void main() { ) ); (key.currentState as dynamic).showTooltip(); // before using "as dynamic" in your code, see note top of file - tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) + await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) /********************* 800x600 screen * * @@ -301,9 +300,9 @@ void main() { expect(tip.localToGlobal(tip.size.bottomRight(Point.origin)).y, equals(500.0)); }); - testWidgets('Does tooltip end up in the right place - way off to the right', (WidgetTester tester) { + testWidgets('Does tooltip end up in the right place - way off to the right', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Overlay( initialEntries: [ new OverlayEntry( @@ -337,7 +336,7 @@ void main() { ) ); (key.currentState as dynamic).showTooltip(); // before using "as dynamic" in your code, see note top of file - tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) + await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) /********************* 800x600 screen * * @@ -356,9 +355,9 @@ void main() { expect(tip.localToGlobal(tip.size.bottomRight(Point.origin)).y, equals(320.0)); }); - testWidgets('Does tooltip end up in the right place - near the edge', (WidgetTester tester) { + testWidgets('Does tooltip end up in the right place - near the edge', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Overlay( initialEntries: [ new OverlayEntry( @@ -392,7 +391,7 @@ void main() { ) ); (key.currentState as dynamic).showTooltip(); // before using "as dynamic" in your code, see note top of file - tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) + await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) /********************* 800x600 screen * * @@ -411,10 +410,10 @@ void main() { expect(tip.localToGlobal(tip.size.bottomRight(Point.origin)).y, equals(320.0)); }); - testWidgets('Does tooltip contribute semantics', (WidgetTester tester) { + testWidgets('Does tooltip contribute semantics', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Overlay( initialEntries: [ new OverlayEntry( @@ -460,7 +459,7 @@ void main() { // before using "as dynamic" in your code, see note top of file (key.currentState as dynamic).showTooltip(); // this triggers a rebuild of the semantics because the tree changes - tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) + await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) expect(client.updates.length, equals(2)); expect(client.updates[0].id, equals(0)); expect(client.updates[0].flags.canBeTapped, isFalse); diff --git a/packages/flutter/test/rendering/independent_layout_test.dart b/packages/flutter/test/rendering/independent_layout_test.dart index 3b2e6c7444..91e7837d46 100644 --- a/packages/flutter/test/rendering/independent_layout_test.dart +++ b/packages/flutter/test/rendering/independent_layout_test.dart @@ -29,6 +29,11 @@ class TestLayout { } void main() { + final ViewConfiguration testConfiguration = new ViewConfiguration( + size: const Size(800.0, 600.0), + devicePixelRatio: 1.0 + ); + test('onscreen layout does not affect offscreen', () { TestLayout onscreen = new TestLayout(); TestLayout offscreen = new TestLayout(); @@ -37,15 +42,15 @@ void main() { expect(offscreen.child.hasSize, isFalse); expect(offscreen.painted, isFalse); // Attach the offscreen to a custom render view and owner - RenderView renderView = new TestRenderView(); + RenderView renderView = new RenderView(configuration: testConfiguration); PipelineOwner pipelineOwner = new PipelineOwner(); renderView.attach(pipelineOwner); renderView.child = offscreen.root; renderView.scheduleInitialFrame(); // Lay out the onscreen in the default binding - layout(onscreen.root, phase: EnginePhase.layout); + layout(onscreen.root, phase: EnginePhase.paint); expect(onscreen.child.hasSize, isTrue); - expect(onscreen.painted, isFalse); + expect(onscreen.painted, isTrue); expect(onscreen.child.size, equals(const Size(800.0, 10.0))); // Make sure the offscreen didn't get laid out expect(offscreen.child.hasSize, isFalse); @@ -54,6 +59,9 @@ void main() { pipelineOwner.flushLayout(); expect(offscreen.child.hasSize, isTrue); expect(offscreen.painted, isFalse); + pipelineOwner.flushCompositingBits(); + pipelineOwner.flushPaint(); + expect(offscreen.painted, isTrue); }); test('offscreen layout does not affect onscreen', () { TestLayout onscreen = new TestLayout(); @@ -63,7 +71,7 @@ void main() { expect(offscreen.child.hasSize, isFalse); expect(offscreen.painted, isFalse); // Attach the offscreen to a custom render view and owner - RenderView renderView = new TestRenderView(); + RenderView renderView = new RenderView(configuration: testConfiguration); PipelineOwner pipelineOwner = new PipelineOwner(); renderView.attach(pipelineOwner); renderView.child = offscreen.root; @@ -72,13 +80,16 @@ void main() { pipelineOwner.flushLayout(); expect(offscreen.child.hasSize, isTrue); expect(offscreen.painted, isFalse); + pipelineOwner.flushCompositingBits(); + pipelineOwner.flushPaint(); + expect(offscreen.painted, isTrue); // Make sure the onscreen didn't get laid out expect(onscreen.child.hasSize, isFalse); expect(onscreen.painted, isFalse); // Now lay out the onscreen in the default binding - layout(onscreen.root, phase: EnginePhase.layout); + layout(onscreen.root, phase: EnginePhase.paint); expect(onscreen.child.hasSize, isTrue); - expect(onscreen.painted, isFalse); + expect(onscreen.painted, isTrue); expect(onscreen.child.size, equals(const Size(800.0, 10.0))); }); } diff --git a/packages/flutter/test/rendering/rendering_tester.dart b/packages/flutter/test/rendering/rendering_tester.dart index df732f38e6..15e60137d2 100644 --- a/packages/flutter/test/rendering/rendering_tester.dart +++ b/packages/flutter/test/rendering/rendering_tester.dart @@ -7,20 +7,6 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; -const Size _kTestViewSize = const Size(800.0, 600.0); - -class TestRenderView extends RenderView { - TestRenderView() { - configuration = new ViewConfiguration(size: _kTestViewSize); - } - - @override - void scheduleInitialFrame() { - scheduleInitialLayout(); - scheduleInitialPaint(new TransformLayer(transform: new Matrix4.identity())); - } -} - enum EnginePhase { layout, compositingBits, @@ -31,14 +17,6 @@ enum EnginePhase { } class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, ServicesBinding, RendererBinding, GestureBinding { - @override - void initRenderView() { - if (renderView == null) { - renderView = new TestRenderView(); - renderView.scheduleInitialFrame(); - } - } - EnginePhase phase = EnginePhase.composite; @override diff --git a/packages/flutter/test/rendering/viewport_test.dart b/packages/flutter/test/rendering/viewport_test.dart index 4ea92930e4..c3c9c518e9 100644 --- a/packages/flutter/test/rendering/viewport_test.dart +++ b/packages/flutter/test/rendering/viewport_test.dart @@ -31,7 +31,7 @@ void main() { result = new HitTestResult(); renderer.renderView.hitTest(result, position: new Point(15.0, 0.0)); - expect(result.path.first.target.runtimeType, equals(TestRenderView)); + expect(result.path.first.target.runtimeType, equals(RenderView)); result = new HitTestResult(); renderer.renderView.hitTest(result, position: new Point(15.0, 15.0)); diff --git a/packages/flutter/test/widget/align_test.dart b/packages/flutter/test/widget/align_test.dart index c8d46496af..d3871789a8 100644 --- a/packages/flutter/test/widget/align_test.dart +++ b/packages/flutter/test/widget/align_test.dart @@ -5,18 +5,17 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Align smoke test', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Align smoke test', (WidgetTester tester) async { + await tester.pumpWidget( new Align( child: new Container(), alignment: const FractionalOffset(0.75, 0.75) ) ); - tester.pumpWidget( + await tester.pumpWidget( new Align( child: new Container(), alignment: const FractionalOffset(0.5, 0.5) @@ -24,9 +23,9 @@ void main() { ); }); - testWidgets('Shrink wraps in finite space', (WidgetTester tester) { + testWidgets('Shrink wraps in finite space', (WidgetTester tester) async { GlobalKey alignKey = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new ScrollableViewport( child: new Align( key: alignKey, diff --git a/packages/flutter/test/widget/animated_container_test.dart b/packages/flutter/test/widget/animated_container_test.dart index 2eeb9094ea..3e12f453d7 100644 --- a/packages/flutter/test/widget/animated_container_test.dart +++ b/packages/flutter/test/widget/animated_container_test.dart @@ -5,10 +5,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('AnimatedContainer control test', (WidgetTester tester) { + testWidgets('AnimatedContainer control test', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); BoxDecoration decorationA = new BoxDecoration( @@ -21,7 +20,7 @@ void main() { BoxDecoration actualDecoration; - tester.pumpWidget( + await tester.pumpWidget( new AnimatedContainer( key: key, duration: const Duration(milliseconds: 200), @@ -33,7 +32,7 @@ void main() { actualDecoration = box.decoration; expect(actualDecoration.backgroundColor, equals(decorationA.backgroundColor)); - tester.pumpWidget( + await tester.pumpWidget( new AnimatedContainer( key: key, duration: const Duration(milliseconds: 200), @@ -45,14 +44,14 @@ void main() { actualDecoration = box.decoration; expect(actualDecoration.backgroundColor, equals(decorationA.backgroundColor)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); actualDecoration = box.decoration; expect(actualDecoration.backgroundColor, equals(decorationB.backgroundColor)); }); - testWidgets('AnimatedContainer overanimate test', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('AnimatedContainer overanimate test', (WidgetTester tester) async { + await tester.pumpWidget( new AnimatedContainer( duration: const Duration(milliseconds: 200), decoration: new BoxDecoration( @@ -61,9 +60,9 @@ void main() { ) ); expect(tester.binding.transientCallbackCount, 0); - tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); expect(tester.binding.transientCallbackCount, 0); - tester.pumpWidget( + await tester.pumpWidget( new AnimatedContainer( duration: const Duration(milliseconds: 200), decoration: new BoxDecoration( @@ -72,9 +71,9 @@ void main() { ) ); expect(tester.binding.transientCallbackCount, 0); - tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); expect(tester.binding.transientCallbackCount, 0); - tester.pumpWidget( + await tester.pumpWidget( new AnimatedContainer( duration: const Duration(milliseconds: 200), decoration: new BoxDecoration( @@ -83,9 +82,9 @@ void main() { ) ); expect(tester.binding.transientCallbackCount, 1); // this is the only time an animation should have started! - tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); expect(tester.binding.transientCallbackCount, 0); - tester.pumpWidget( + await tester.pumpWidget( new AnimatedContainer( duration: const Duration(milliseconds: 200), decoration: new BoxDecoration( @@ -96,8 +95,8 @@ void main() { expect(tester.binding.transientCallbackCount, 0); }); - testWidgets('Animation rerun', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Animation rerun', (WidgetTester tester) async { + await tester.pumpWidget( new Center( child: new AnimatedContainer( duration: const Duration(milliseconds: 200), @@ -108,16 +107,16 @@ void main() { ) ); - tester.pump(); - tester.pump(new Duration(milliseconds: 100)); + await tester.pump(); + await tester.pump(new Duration(milliseconds: 100)); RenderBox text = tester.renderObject(find.text('X')); expect(text.size.width, equals(100.0)); expect(text.size.height, equals(100.0)); - tester.pump(new Duration(milliseconds: 1000)); + await tester.pump(new Duration(milliseconds: 1000)); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new AnimatedContainer( duration: const Duration(milliseconds: 200), @@ -127,8 +126,8 @@ void main() { ) ) ); - tester.pump(); - tester.pump(new Duration(milliseconds: 100)); + await tester.pump(); + await tester.pump(new Duration(milliseconds: 100)); text = tester.renderObject(find.text('X')); expect(text.size.width, greaterThan(110.0)); @@ -136,12 +135,12 @@ void main() { expect(text.size.height, greaterThan(110.0)); expect(text.size.height, lessThan(190.0)); - tester.pump(new Duration(milliseconds: 1000)); + await tester.pump(new Duration(milliseconds: 1000)); expect(text.size.width, equals(200.0)); expect(text.size.height, equals(200.0)); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new AnimatedContainer( duration: const Duration(milliseconds: 200), @@ -151,14 +150,14 @@ void main() { ) ) ); - tester.pump(); - tester.pump(new Duration(milliseconds: 100)); + await tester.pump(); + await tester.pump(new Duration(milliseconds: 100)); expect(text.size.width, equals(200.0)); expect(text.size.height, greaterThan(110.0)); expect(text.size.height, lessThan(190.0)); - tester.pump(new Duration(milliseconds: 1000)); + await tester.pump(new Duration(milliseconds: 1000)); expect(text.size.width, equals(200.0)); expect(text.size.height, equals(100.0)); diff --git a/packages/flutter/test/widget/animated_positioned_test.dart b/packages/flutter/test/widget/animated_positioned_test.dart index 0534998bb2..1b986b63fa 100644 --- a/packages/flutter/test/widget/animated_positioned_test.dart +++ b/packages/flutter/test/widget/animated_positioned_test.dart @@ -5,15 +5,14 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('AnimatedPositioned - basics', (WidgetTester tester) { + testWidgets('AnimatedPositioned - basics', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); RenderBox box; - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new AnimatedPositioned( @@ -31,12 +30,12 @@ void main() { box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0 + 70.0 / 2.0, 30.0 + 110.0 / 2.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0 + 70.0 / 2.0, 30.0 + 110.0 / 2.0))); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new AnimatedPositioned( @@ -54,24 +53,24 @@ void main() { box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0 + 70.0 / 2.0, 30.0 + 110.0 / 2.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0 - (50.0 - 37.0) / 2.0 + (70.0 - (70.0 - 59.0) / 2.0) / 2.0, 30.0 + (31.0 - 30.0) / 2.0 + (110.0 - (110.0 - 71.0) / 2.0) / 2.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(37.0 + 59.0 / 2.0, 31.0 + 71.0 / 2.0))); }); - testWidgets('AnimatedPositioned - interrupted animation', (WidgetTester tester) { + testWidgets('AnimatedPositioned - interrupted animation', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); RenderBox box; - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new AnimatedPositioned( @@ -89,12 +88,12 @@ void main() { box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0))); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new AnimatedPositioned( @@ -112,12 +111,12 @@ void main() { box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(100.0, 100.0))); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new AnimatedPositioned( @@ -135,23 +134,23 @@ void main() { box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(100.0, 100.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(150.0, 150.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(200.0, 200.0))); }); - testWidgets('AnimatedPositioned - switching variables', (WidgetTester tester) { + testWidgets('AnimatedPositioned - switching variables', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); RenderBox box; - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new AnimatedPositioned( @@ -169,12 +168,12 @@ void main() { box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0))); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new AnimatedPositioned( @@ -192,12 +191,12 @@ void main() { box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(350.0, 50.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(350.0, 100.0))); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); box = key.currentContext.findRenderObject(); expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(350.0, 150.0))); diff --git a/packages/flutter/test/widget/aspect_ratio_test.dart b/packages/flutter/test/widget/aspect_ratio_test.dart index c7e2a8baec..2dc6acde73 100644 --- a/packages/flutter/test/widget/aspect_ratio_test.dart +++ b/packages/flutter/test/widget/aspect_ratio_test.dart @@ -5,11 +5,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; -Size _getSize(WidgetTester tester, BoxConstraints constraints, double aspectRatio) { +Future _getSize(WidgetTester tester, BoxConstraints constraints, double aspectRatio) async { Key childKey = new UniqueKey(); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new ConstrainedBox( constraints: constraints, @@ -27,14 +26,14 @@ Size _getSize(WidgetTester tester, BoxConstraints constraints, double aspectRati } void main() { - testWidgets('Aspect ratio control test', (WidgetTester tester) { - expect(_getSize(tester, new BoxConstraints.loose(new Size(500.0, 500.0)), 2.0), equals(new Size(500.0, 250.0))); - expect(_getSize(tester, new BoxConstraints.loose(new Size(500.0, 500.0)), 0.5), equals(new Size(250.0, 500.0))); + testWidgets('Aspect ratio control test', (WidgetTester tester) async { + expect(await _getSize(tester, new BoxConstraints.loose(new Size(500.0, 500.0)), 2.0), equals(new Size(500.0, 250.0))); + expect(await _getSize(tester, new BoxConstraints.loose(new Size(500.0, 500.0)), 0.5), equals(new Size(250.0, 500.0))); }); - testWidgets('Aspect ratio infinite width', (WidgetTester tester) { + testWidgets('Aspect ratio infinite width', (WidgetTester tester) async { Key childKey = new UniqueKey(); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new Viewport( mainAxis: Axis.horizontal, diff --git a/packages/flutter/test/widget/asset_vendor_test.dart b/packages/flutter/test/widget/asset_vendor_test.dart index 835692df53..834f9e4572 100644 --- a/packages/flutter/test/widget/asset_vendor_test.dart +++ b/packages/flutter/test/widget/asset_vendor_test.dart @@ -10,7 +10,6 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:mojo/core.dart' as core; -import 'package:test/test.dart'; class TestImage extends ui.Image { TestImage(this.scale); @@ -127,95 +126,95 @@ TestImage getTestImage(WidgetTester tester, Key key) { return tester.renderObject/**/(find.byKey(key)).image; } -void pumpTreeToLayout(WidgetTester tester, Widget widget) { +Future pumpTreeToLayout(WidgetTester tester, Widget widget) { Duration pumpDuration = const Duration(milliseconds: 0); EnginePhase pumpPhase = EnginePhase.layout; - tester.pumpWidget(widget, pumpDuration, pumpPhase); + return tester.pumpWidget(widget, pumpDuration, pumpPhase); } void main() { String image = 'assets/image.png'; - testWidgets('Image for device pixel ratio 1.0', (WidgetTester tester) { + testWidgets('Image for device pixel ratio 1.0', (WidgetTester tester) async { const double ratio = 1.0; Key key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); expect(getRenderImage(tester, key).size, const Size(200.0, 200.0)); expect(getTestImage(tester, key).scale, 1.0); key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); expect(getRenderImage(tester, key).size, const Size(48.0, 48.0)); expect(getTestImage(tester, key).scale, 1.0); }); - testWidgets('Image for device pixel ratio 0.5', (WidgetTester tester) { + testWidgets('Image for device pixel ratio 0.5', (WidgetTester tester) async { const double ratio = 0.5; Key key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); expect(getRenderImage(tester, key).size, const Size(200.0, 200.0)); expect(getTestImage(tester, key).scale, 1.0); key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); expect(getRenderImage(tester, key).size, const Size(48.0, 48.0)); expect(getTestImage(tester, key).scale, 1.0); }); - testWidgets('Image for device pixel ratio 1.5', (WidgetTester tester) { + testWidgets('Image for device pixel ratio 1.5', (WidgetTester tester) async { const double ratio = 1.5; Key key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); expect(getRenderImage(tester, key).size, const Size(200.0, 200.0)); expect(getTestImage(tester, key).scale, 1.5); key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); expect(getRenderImage(tester, key).size, const Size(48.0, 48.0)); expect(getTestImage(tester, key).scale, 1.5); }); - testWidgets('Image for device pixel ratio 1.75', (WidgetTester tester) { + testWidgets('Image for device pixel ratio 1.75', (WidgetTester tester) async { const double ratio = 1.75; Key key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); expect(getRenderImage(tester, key).size, const Size(200.0, 200.0)); expect(getTestImage(tester, key).scale, 1.5); key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); expect(getRenderImage(tester, key).size, const Size(48.0, 48.0)); expect(getTestImage(tester, key).scale, 1.5); }); - testWidgets('Image for device pixel ratio 2.3', (WidgetTester tester) { + testWidgets('Image for device pixel ratio 2.3', (WidgetTester tester) async { const double ratio = 2.3; Key key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); expect(getRenderImage(tester, key).size, const Size(200.0, 200.0)); expect(getTestImage(tester, key).scale, 2.0); key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); expect(getRenderImage(tester, key).size, const Size(48.0, 48.0)); expect(getTestImage(tester, key).scale, 2.0); }); - testWidgets('Image for device pixel ratio 3.7', (WidgetTester tester) { + testWidgets('Image for device pixel ratio 3.7', (WidgetTester tester) async { const double ratio = 3.7; Key key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); expect(getRenderImage(tester, key).size, const Size(200.0, 200.0)); expect(getTestImage(tester, key).scale, 4.0); key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); expect(getRenderImage(tester, key).size, const Size(48.0, 48.0)); expect(getTestImage(tester, key).scale, 4.0); }); - testWidgets('Image for device pixel ratio 5.1', (WidgetTester tester) { + testWidgets('Image for device pixel ratio 5.1', (WidgetTester tester) async { const double ratio = 5.1; Key key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false)); expect(getRenderImage(tester, key).size, const Size(200.0, 200.0)); expect(getTestImage(tester, key).scale, 4.0); key = new GlobalKey(); - pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); + await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true)); expect(getRenderImage(tester, key).size, const Size(48.0, 48.0)); expect(getTestImage(tester, key).scale, 4.0); }); diff --git a/packages/flutter/test/widget/block_test.dart b/packages/flutter/test/widget/block_test.dart index 33ceada685..2fbbf01a83 100644 --- a/packages/flutter/test/widget/block_test.dart +++ b/packages/flutter/test/widget/block_test.dart @@ -4,13 +4,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; final Key blockKey = new Key('test'); void main() { - testWidgets('Cannot scroll a non-overflowing block', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Cannot scroll a non-overflowing block', (WidgetTester tester) async { + await tester.pumpWidget( new Block( key: blockKey, children: [ @@ -24,18 +23,18 @@ void main() { Point middleOfContainer = tester.getCenter(find.text('Hello')); Point target = tester.getCenter(find.byKey(blockKey)); - TestGesture gesture = tester.startGesture(target); - gesture.moveBy(const Offset(0.0, -10.0)); + TestGesture gesture = await tester.startGesture(target); + await gesture.moveBy(const Offset(0.0, -10.0)); - tester.pump(const Duration(milliseconds: 1)); + await tester.pump(const Duration(milliseconds: 1)); expect(tester.getCenter(find.text('Hello')) == middleOfContainer, isTrue); - gesture.up(); + await gesture.up(); }); - testWidgets('Can scroll an overflowing block', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Can scroll an overflowing block', (WidgetTester tester) async { + await tester.pumpWidget( new Block( key: blockKey, children: [ @@ -52,17 +51,17 @@ void main() { expect(middleOfContainer.y, equals(1000.0)); Point target = tester.getCenter(find.byKey(blockKey)); - TestGesture gesture = tester.startGesture(target); - gesture.moveBy(const Offset(0.0, -10.0)); + TestGesture gesture = await tester.startGesture(target); + await gesture.moveBy(const Offset(0.0, -10.0)); - tester.pump(); // redo layout + await tester.pump(); // redo layout expect(tester.getCenter(find.text('Hello')), isNot(equals(middleOfContainer))); - gesture.up(); + await gesture.up(); }); - testWidgets('Scroll anchor', (WidgetTester tester) { + testWidgets('Scroll anchor', (WidgetTester tester) async { int first = 0; int second = 0; @@ -93,16 +92,16 @@ void main() { ); } - tester.pumpWidget(buildBlock(ViewportAnchor.end)); + await tester.pumpWidget(buildBlock(ViewportAnchor.end)); Point target = const Point(200.0, 200.0); - tester.tapAt(target); + await tester.tapAt(target); expect(first, equals(0)); expect(second, equals(1)); - tester.pumpWidget(buildBlock(ViewportAnchor.start)); + await tester.pumpWidget(buildBlock(ViewportAnchor.start)); - tester.tapAt(target); + await tester.tapAt(target); expect(first, equals(1)); expect(second, equals(1)); }); diff --git a/packages/flutter/test/widget/bottom_sheet_rebuild_test.dart b/packages/flutter/test/widget/bottom_sheet_rebuild_test.dart index 02d87ba37a..036df9b32d 100644 --- a/packages/flutter/test/widget/bottom_sheet_rebuild_test.dart +++ b/packages/flutter/test/widget/bottom_sheet_rebuild_test.dart @@ -4,15 +4,14 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Verify that a BottomSheet can be rebuilt with ScaffoldFeatureController.setState()', (WidgetTester tester) { + testWidgets('Verify that a BottomSheet can be rebuilt with ScaffoldFeatureController.setState()', (WidgetTester tester) async { final GlobalKey scaffoldKey = new GlobalKey(); PersistentBottomSheetController bottomSheet; int buildCount = 0; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Scaffold( key: scaffoldKey, body: new Center(child: new Text('body')) @@ -28,11 +27,11 @@ void main() { ); }); - tester.pump(); + await tester.pump(); expect(buildCount, equals(1)); bottomSheet.setState((){ }); - tester.pump(); + await tester.pump(); expect(buildCount, equals(2)); }); diff --git a/packages/flutter/test/widget/bottom_sheet_test.dart b/packages/flutter/test/widget/bottom_sheet_test.dart index 96a35c1593..2585f7a7cc 100644 --- a/packages/flutter/test/widget/bottom_sheet_test.dart +++ b/packages/flutter/test/widget/bottom_sheet_test.dart @@ -5,14 +5,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Verify that a tap dismisses a modal BottomSheet', (WidgetTester tester) { + testWidgets('Verify that a tap dismisses a modal BottomSheet', (WidgetTester tester) async { BuildContext savedContext; bool showBottomSheetThenCalled = false; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Builder( builder: (BuildContext context) { savedContext = context; @@ -21,48 +20,48 @@ void main() { ) )); - tester.pump(); + await tester.pump(); expect(find.text('BottomSheet'), findsNothing); showModalBottomSheet/**/( context: savedContext, builder: (BuildContext context) => new Text('BottomSheet') ).then((Null result) { - expect(result, isNull); + expectSync(result, isNull); showBottomSheetThenCalled = true; }); - tester.pump(); // bottom sheet show animation starts - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(); // bottom sheet show animation starts + await tester.pump(new Duration(seconds: 1)); // animation done expect(find.text('BottomSheet'), findsOneWidget); expect(showBottomSheetThenCalled, isFalse); // Tap on the the bottom sheet itself to dismiss it - tester.tap(find.text('BottomSheet')); - tester.pump(); // bottom sheet dismiss animation starts + await tester.tap(find.text('BottomSheet')); + await tester.pump(); // bottom sheet dismiss animation starts expect(showBottomSheetThenCalled, isTrue); - tester.pump(new Duration(seconds: 1)); // last frame of animation (sheet is entirely off-screen, but still present) - tester.pump(new Duration(seconds: 1)); // frame after the animation (sheet has been removed) + await tester.pump(new Duration(seconds: 1)); // last frame of animation (sheet is entirely off-screen, but still present) + await tester.pump(new Duration(seconds: 1)); // frame after the animation (sheet has been removed) expect(find.text('BottomSheet'), findsNothing); showModalBottomSheet/**/(context: savedContext, builder: (BuildContext context) => new Text('BottomSheet')); - tester.pump(); // bottom sheet show animation starts - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(); // bottom sheet show animation starts + await tester.pump(new Duration(seconds: 1)); // animation done expect(find.text('BottomSheet'), findsOneWidget); // Tap above the the bottom sheet to dismiss it - tester.tapAt(new Point(20.0, 20.0)); - tester.pump(); // bottom sheet dismiss animation starts - tester.pump(new Duration(seconds: 1)); // animation done - tester.pump(new Duration(seconds: 1)); // rebuild frame + await tester.tapAt(new Point(20.0, 20.0)); + await tester.pump(); // bottom sheet dismiss animation starts + await tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(new Duration(seconds: 1)); // rebuild frame expect(find.text('BottomSheet'), findsNothing); }); - testWidgets('Verify that a downwards fling dismisses a persistent BottomSheet', (WidgetTester tester) { + testWidgets('Verify that a downwards fling dismisses a persistent BottomSheet', (WidgetTester tester) async { GlobalKey scaffoldKey = new GlobalKey(); bool showBottomSheetThenCalled = false; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Scaffold( key: scaffoldKey, body: new Center(child: new Text('body')) @@ -84,28 +83,28 @@ void main() { expect(showBottomSheetThenCalled, isFalse); expect(find.text('BottomSheet'), findsNothing); - tester.pump(); // bottom sheet show animation starts + await tester.pump(); // bottom sheet show animation starts expect(showBottomSheetThenCalled, isFalse); expect(find.text('BottomSheet'), findsOneWidget); - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(new Duration(seconds: 1)); // animation done expect(showBottomSheetThenCalled, isFalse); expect(find.text('BottomSheet'), findsOneWidget); - tester.fling(find.text('BottomSheet'), const Offset(0.0, 20.0), 1000.0); - tester.pump(); // drain the microtask queue (Future completion callback) + await tester.fling(find.text('BottomSheet'), const Offset(0.0, 20.0), 1000.0); + await tester.pump(); // drain the microtask queue (Future completion callback) expect(showBottomSheetThenCalled, isTrue); expect(find.text('BottomSheet'), findsOneWidget); - tester.pump(); // bottom sheet dismiss animation starts + await tester.pump(); // bottom sheet dismiss animation starts expect(showBottomSheetThenCalled, isTrue); expect(find.text('BottomSheet'), findsOneWidget); - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(new Duration(seconds: 1)); // animation done expect(showBottomSheetThenCalled, isTrue); expect(find.text('BottomSheet'), findsNothing); diff --git a/packages/flutter/test/widget/box_decoration_test.dart b/packages/flutter/test/widget/box_decoration_test.dart index 8588f58208..c4818a43f1 100644 --- a/packages/flutter/test/widget/box_decoration_test.dart +++ b/packages/flutter/test/widget/box_decoration_test.dart @@ -5,11 +5,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Circles can have uniform borders', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Circles can have uniform borders', (WidgetTester tester) async { + await tester.pumpWidget( new Container( padding: new EdgeInsets.all(50.0), decoration: new BoxDecoration( @@ -21,9 +20,9 @@ void main() { ); }); - testWidgets('Bordered Container insets its child', (WidgetTester tester) { + testWidgets('Bordered Container insets its child', (WidgetTester tester) async { Key key = new Key('outerContainer'); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new Container( key: key, diff --git a/packages/flutter/test/widget/build_scope_test.dart b/packages/flutter/test/widget/build_scope_test.dart index d799413dd4..e9a2640879 100644 --- a/packages/flutter/test/widget/build_scope_test.dart +++ b/packages/flutter/test/widget/build_scope_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; import 'test_widgets.dart'; @@ -78,14 +77,14 @@ class BadDisposeWidgetState extends State { } void main() { - testWidgets('Legal times for setState', (WidgetTester tester) { + testWidgets('Legal times for setState', (WidgetTester tester) async { GlobalKey flipKey = new GlobalKey(); expect(ProbeWidgetState.buildCount, equals(0)); - tester.pumpWidget(new ProbeWidget()); + await tester.pumpWidget(new ProbeWidget()); expect(ProbeWidgetState.buildCount, equals(1)); - tester.pumpWidget(new ProbeWidget()); + await tester.pumpWidget(new ProbeWidget()); expect(ProbeWidgetState.buildCount, equals(2)); - tester.pumpWidget(new FlipWidget( + await tester.pumpWidget(new FlipWidget( key: flipKey, left: new Container(), right: new ProbeWidget() @@ -93,26 +92,26 @@ void main() { expect(ProbeWidgetState.buildCount, equals(2)); FlipWidgetState flipState1 = flipKey.currentState; flipState1.flip(); - tester.pump(); + await tester.pump(); expect(ProbeWidgetState.buildCount, equals(3)); FlipWidgetState flipState2 = flipKey.currentState; flipState2.flip(); - tester.pump(); + await tester.pump(); expect(ProbeWidgetState.buildCount, equals(3)); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); expect(ProbeWidgetState.buildCount, equals(3)); }); - testWidgets('Setting parent state during build is forbidden', (WidgetTester tester) { - tester.pumpWidget(new BadWidgetParent()); + testWidgets('Setting parent state during build is forbidden', (WidgetTester tester) async { + await tester.pumpWidget(new BadWidgetParent()); expect(tester.takeException(), isNotNull); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); }); - testWidgets('Setting state during dispose is forbidden', (WidgetTester tester) { - tester.pumpWidget(new BadDisposeWidget()); + testWidgets('Setting state during dispose is forbidden', (WidgetTester tester) async { + await tester.pumpWidget(new BadDisposeWidget()); expect(tester.takeException(), isNull); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); expect(tester.takeException(), isNotNull); }); } diff --git a/packages/flutter/test/widget/buttons_test.dart b/packages/flutter/test/widget/buttons_test.dart index eea80aeab5..0bc071ee46 100644 --- a/packages/flutter/test/widget/buttons_test.dart +++ b/packages/flutter/test/widget/buttons_test.dart @@ -5,14 +5,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import 'test_semantics.dart'; void main() { - testWidgets('Does FlatButton contribute semantics', (WidgetTester tester) { + testWidgets('Does FlatButton contribute semantics', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); - tester.pumpWidget( + await tester.pumpWidget( new Material( child: new Center( child: new FlatButton( diff --git a/packages/flutter/test/widget/center_test.dart b/packages/flutter/test/widget/center_test.dart index 0baeaca5c0..ea347cd027 100644 --- a/packages/flutter/test/widget/center_test.dart +++ b/packages/flutter/test/widget/center_test.dart @@ -6,7 +6,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; void main() { - testWidgets('Can be placed in an infinite box', (WidgetTester tester) { - tester.pumpWidget(new Block(children: [new Center()])); + testWidgets('Can be placed in an infinite box', (WidgetTester tester) async { + await tester.pumpWidget(new Block(children: [new Center()])); }); } diff --git a/packages/flutter/test/widget/clip_test.dart b/packages/flutter/test/widget/clip_test.dart index a1c6ca2ab3..96a13f0f90 100644 --- a/packages/flutter/test/widget/clip_test.dart +++ b/packages/flutter/test/widget/clip_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; final List log = []; @@ -20,8 +19,8 @@ class PathClipper extends CustomClipper { } void main() { - testWidgets('ClipPath', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('ClipPath', (WidgetTester tester) async { + await tester.pumpWidget( new ClipPath( clipper: new PathClipper(), child: new GestureDetector( @@ -33,17 +32,17 @@ void main() { ); expect(log, equals(['getClip'])); - tester.tapAt(new Point(10.0, 10.0)); + await tester.tapAt(new Point(10.0, 10.0)); expect(log, equals(['getClip'])); log.clear(); - tester.tapAt(new Point(100.0, 100.0)); + await tester.tapAt(new Point(100.0, 100.0)); expect(log, equals(['tap'])); log.clear(); }); - testWidgets('ClipOval', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('ClipOval', (WidgetTester tester) async { + await tester.pumpWidget( new ClipOval( child: new GestureDetector( behavior: HitTestBehavior.opaque, @@ -54,11 +53,11 @@ void main() { ); expect(log, equals([])); - tester.tapAt(new Point(10.0, 10.0)); + await tester.tapAt(new Point(10.0, 10.0)); expect(log, equals([])); log.clear(); - tester.tapAt(new Point(400.0, 300.0)); + await tester.tapAt(new Point(400.0, 300.0)); expect(log, equals(['tap'])); log.clear(); }); diff --git a/packages/flutter/test/widget/coordinates_test.dart b/packages/flutter/test/widget/coordinates_test.dart index 0c9245b46b..18756c0c4f 100644 --- a/packages/flutter/test/widget/coordinates_test.dart +++ b/packages/flutter/test/widget/coordinates_test.dart @@ -5,14 +5,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Comparing coordinates', (WidgetTester tester) { + testWidgets('Comparing coordinates', (WidgetTester tester) async { Key keyA = new GlobalKey(); Key keyB = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( diff --git a/packages/flutter/test/widget/custom_multi_child_layout_test.dart b/packages/flutter/test/widget/custom_multi_child_layout_test.dart index 84e85558d0..1eacc22548 100644 --- a/packages/flutter/test/widget/custom_multi_child_layout_test.dart +++ b/packages/flutter/test/widget/custom_multi_child_layout_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class TestMultiChildLayoutDelegate extends MultiChildLayoutDelegate { BoxConstraints getSizeConstraints; @@ -75,9 +74,9 @@ class PreferredSizeDelegate extends MultiChildLayoutDelegate { } void main() { - testWidgets('Control test for CustomMultiChildLayout', (WidgetTester tester) { + testWidgets('Control test for CustomMultiChildLayout', (WidgetTester tester) async { TestMultiChildLayoutDelegate delegate = new TestMultiChildLayoutDelegate(); - tester.pumpWidget(buildFrame(delegate)); + await tester.pumpWidget(buildFrame(delegate)); expect(delegate.getSizeConstraints.minWidth, 0.0); expect(delegate.getSizeConstraints.maxWidth, 800.0); @@ -93,9 +92,9 @@ void main() { expect(delegate.performLayoutIsChild, false); }); - testWidgets('Test MultiChildDelegate shouldRelayout method', (WidgetTester tester) { + testWidgets('Test MultiChildDelegate shouldRelayout method', (WidgetTester tester) async { TestMultiChildLayoutDelegate delegate = new TestMultiChildLayoutDelegate(); - tester.pumpWidget(buildFrame(delegate)); + await tester.pumpWidget(buildFrame(delegate)); // Layout happened because the delegate was set. expect(delegate.performLayoutSize, isNotNull); // i.e. layout happened @@ -104,21 +103,21 @@ void main() { // Layout did not happen because shouldRelayout() returned false. delegate = new TestMultiChildLayoutDelegate(); delegate.shouldRelayoutValue = false; - tester.pumpWidget(buildFrame(delegate)); + await tester.pumpWidget(buildFrame(delegate)); expect(delegate.shouldRelayoutCalled, isTrue); expect(delegate.performLayoutSize, isNull); // Layout happened because shouldRelayout() returned true. delegate = new TestMultiChildLayoutDelegate(); delegate.shouldRelayoutValue = true; - tester.pumpWidget(buildFrame(delegate)); + await tester.pumpWidget(buildFrame(delegate)); expect(delegate.shouldRelayoutCalled, isTrue); expect(delegate.performLayoutSize, isNotNull); }); - testWidgets('Nested CustomMultiChildLayouts', (WidgetTester tester) { + testWidgets('Nested CustomMultiChildLayouts', (WidgetTester tester) async { TestMultiChildLayoutDelegate delegate = new TestMultiChildLayoutDelegate(); - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new CustomMultiChildLayout( children: [ new LayoutId( @@ -139,9 +138,9 @@ void main() { }); - testWidgets('Loose constraints', (WidgetTester tester) { + testWidgets('Loose constraints', (WidgetTester tester) async { Key key = new UniqueKey(); - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new CustomMultiChildLayout( key: key, delegate: new PreferredSizeDelegate(preferredSize: new Size(300.0, 200.0)) @@ -152,7 +151,7 @@ void main() { expect(box.size.width, equals(300.0)); expect(box.size.height, equals(200.0)); - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new CustomMultiChildLayout( key: key, delegate: new PreferredSizeDelegate(preferredSize: new Size(350.0, 250.0)) diff --git a/packages/flutter/test/widget/custom_one_child_layout_test.dart b/packages/flutter/test/widget/custom_one_child_layout_test.dart index 80ca6341d0..2f2ad60aab 100644 --- a/packages/flutter/test/widget/custom_one_child_layout_test.dart +++ b/packages/flutter/test/widget/custom_one_child_layout_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class TestSingleChildLayoutDelegate extends SingleChildLayoutDelegate { BoxConstraints constraintsFromGetSize; @@ -56,9 +55,9 @@ Widget buildFrame(SingleChildLayoutDelegate delegate) { } void main() { - testWidgets('Control test for CustomSingleChildLayout', (WidgetTester tester) { + testWidgets('Control test for CustomSingleChildLayout', (WidgetTester tester) async { TestSingleChildLayoutDelegate delegate = new TestSingleChildLayoutDelegate(); - tester.pumpWidget(buildFrame(delegate)); + await tester.pumpWidget(buildFrame(delegate)); expect(delegate.constraintsFromGetSize.minWidth, 0.0); expect(delegate.constraintsFromGetSize.maxWidth, 800.0); @@ -77,9 +76,9 @@ void main() { expect(delegate.childSizeFromGetPositionForChild.height, 400.0); }); - testWidgets('Test SingleChildDelegate shouldRelayout method', (WidgetTester tester) { + testWidgets('Test SingleChildDelegate shouldRelayout method', (WidgetTester tester) async { TestSingleChildLayoutDelegate delegate = new TestSingleChildLayoutDelegate(); - tester.pumpWidget(buildFrame(delegate)); + await tester.pumpWidget(buildFrame(delegate)); // Layout happened because the delegate was set. expect(delegate.constraintsFromGetConstraintsForChild, isNotNull); // i.e. layout happened @@ -88,14 +87,14 @@ void main() { // Layout did not happen because shouldRelayout() returned false. delegate = new TestSingleChildLayoutDelegate(); delegate.shouldRelayoutValue = false; - tester.pumpWidget(buildFrame(delegate)); + await tester.pumpWidget(buildFrame(delegate)); expect(delegate.shouldRelayoutCalled, isTrue); expect(delegate.constraintsFromGetConstraintsForChild, isNull); // Layout happened because shouldRelayout() returned true. delegate = new TestSingleChildLayoutDelegate(); delegate.shouldRelayoutValue = true; - tester.pumpWidget(buildFrame(delegate)); + await tester.pumpWidget(buildFrame(delegate)); expect(delegate.shouldRelayoutCalled, isTrue); expect(delegate.constraintsFromGetConstraintsForChild, isNotNull); }); diff --git a/packages/flutter/test/widget/custom_paint_test.dart b/packages/flutter/test/widget/custom_paint_test.dart index 2fc26a9c51..b435d4058b 100644 --- a/packages/flutter/test/widget/custom_paint_test.dart +++ b/packages/flutter/test/widget/custom_paint_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class TestCustomPainter extends CustomPainter { TestCustomPainter({ this.log, this.name }); @@ -22,9 +21,9 @@ class TestCustomPainter extends CustomPainter { } void main() { - testWidgets('Control test for custom painting', (WidgetTester tester) { + testWidgets('Control test for custom painting', (WidgetTester tester) async { List log = []; - tester.pumpWidget(new CustomPaint( + await tester.pumpWidget(new CustomPaint( painter: new TestCustomPainter( log: log, name: 'background' diff --git a/packages/flutter/test/widget/date_picker_test_disabled.dart b/packages/flutter/test/widget/date_picker_test_disabled.dart index bb0bac140a..9e46d9bb88 100644 --- a/packages/flutter/test/widget/date_picker_test_disabled.dart +++ b/packages/flutter/test/widget/date_picker_test_disabled.dart @@ -4,10 +4,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Can select a day', (WidgetTester tester) { + testWidgets('Can select a day', (WidgetTester tester) async { DateTime currentValue; Widget widget = new Material( @@ -25,15 +24,15 @@ void main() { ) ); - tester.pumpWidget(widget); + await tester.pumpWidget(widget); expect(currentValue, isNull); - tester.tap(find.text('2015')); - tester.pumpWidget(widget); - tester.tap(find.text('2014')); - tester.pumpWidget(widget); + await tester.tap(find.text('2015')); + await tester.pumpWidget(widget); + await tester.tap(find.text('2014')); + await tester.pumpWidget(widget); expect(currentValue, equals(new DateTime(2014, 6, 9))); - tester.tap(find.text('30')); + await tester.tap(find.text('30')); expect(currentValue, equals(new DateTime(2013, 1, 30))); }); } diff --git a/packages/flutter/test/widget/dismissable_test.dart b/packages/flutter/test/widget/dismissable_test.dart index a414333294..c11a20a91c 100644 --- a/packages/flutter/test/widget/dismissable_test.dart +++ b/packages/flutter/test/widget/dismissable_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; const double itemExtent = 100.0; Axis scrollDirection = Axis.vertical; @@ -52,7 +51,7 @@ Widget widgetBuilder() { ); } -void dismissElement(WidgetTester tester, Finder finder, { DismissDirection gestureDirection }) { +Future dismissElement(WidgetTester tester, Finder finder, { DismissDirection gestureDirection }) async { assert(tester.any(finder)); assert(gestureDirection != DismissDirection.horizontal); assert(gestureDirection != DismissDirection.vertical); @@ -86,25 +85,25 @@ void dismissElement(WidgetTester tester, Finder finder, { DismissDirection gestu fail("unsupported gestureDirection"); } - TestGesture gesture = tester.startGesture(downLocation, pointer: 5); - gesture.moveTo(upLocation); - gesture.up(); + TestGesture gesture = await tester.startGesture(downLocation, pointer: 5); + await gesture.moveTo(upLocation); + await gesture.up(); } -void dismissItem(WidgetTester tester, int item, { DismissDirection gestureDirection }) { +Future dismissItem(WidgetTester tester, int item, { DismissDirection gestureDirection }) async { assert(gestureDirection != DismissDirection.horizontal); assert(gestureDirection != DismissDirection.vertical); Finder itemFinder = find.text(item.toString()); expect(itemFinder, findsOneWidget); - dismissElement(tester, itemFinder, gestureDirection: gestureDirection); + await dismissElement(tester, itemFinder, gestureDirection: gestureDirection); - tester.pumpWidget(widgetBuilder()); // start the slide - tester.pumpWidget(widgetBuilder(), const Duration(seconds: 1)); // finish the slide and start shrinking... - tester.pumpWidget(widgetBuilder()); // first frame of shrinking animation - tester.pumpWidget(widgetBuilder(), const Duration(seconds: 1)); // finish the shrinking and call the callback... - tester.pumpWidget(widgetBuilder()); // rebuild after the callback removes the entry + await tester.pumpWidget(widgetBuilder()); // start the slide + await tester.pumpWidget(widgetBuilder(), const Duration(seconds: 1)); // finish the slide and start shrinking... + await tester.pumpWidget(widgetBuilder()); // first frame of shrinking animation + await tester.pumpWidget(widgetBuilder(), const Duration(seconds: 1)); // finish the shrinking and call the callback... + await tester.pumpWidget(widgetBuilder()); // rebuild after the callback removes the entry } class Test1215DismissableWidget extends StatelessWidget { @@ -130,104 +129,104 @@ void main() { background = null; }); - testWidgets('Horizontal drag triggers dismiss scrollDirection=vertical', (WidgetTester tester) { + testWidgets('Horizontal drag triggers dismiss scrollDirection=vertical', (WidgetTester tester) async { scrollDirection = Axis.vertical; dismissDirection = DismissDirection.horizontal; - tester.pumpWidget(widgetBuilder()); + await tester.pumpWidget(widgetBuilder()); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.startToEnd); + await dismissItem(tester, 0, gestureDirection: DismissDirection.startToEnd); expect(find.text('0'), findsNothing); expect(dismissedItems, equals([0])); expect(reportedDismissDirection, DismissDirection.startToEnd); - dismissItem(tester, 1, gestureDirection: DismissDirection.endToStart); + await dismissItem(tester, 1, gestureDirection: DismissDirection.endToStart); expect(find.text('1'), findsNothing); expect(dismissedItems, equals([0, 1])); expect(reportedDismissDirection, DismissDirection.endToStart); }); - testWidgets('Vertical drag triggers dismiss scrollDirection=horizontal', (WidgetTester tester) { + testWidgets('Vertical drag triggers dismiss scrollDirection=horizontal', (WidgetTester tester) async { scrollDirection = Axis.horizontal; dismissDirection = DismissDirection.vertical; - tester.pumpWidget(widgetBuilder()); + await tester.pumpWidget(widgetBuilder()); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.up); + await dismissItem(tester, 0, gestureDirection: DismissDirection.up); expect(find.text('0'), findsNothing); expect(dismissedItems, equals([0])); expect(reportedDismissDirection, DismissDirection.up); - dismissItem(tester, 1, gestureDirection: DismissDirection.down); + await dismissItem(tester, 1, gestureDirection: DismissDirection.down); expect(find.text('1'), findsNothing); expect(dismissedItems, equals([0, 1])); expect(reportedDismissDirection, DismissDirection.down); }); - testWidgets('drag-left with DismissDirection.left triggers dismiss', (WidgetTester tester) { + testWidgets('drag-left with DismissDirection.left triggers dismiss', (WidgetTester tester) async { scrollDirection = Axis.vertical; dismissDirection = DismissDirection.endToStart; - tester.pumpWidget(widgetBuilder()); + await tester.pumpWidget(widgetBuilder()); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.startToEnd); + await dismissItem(tester, 0, gestureDirection: DismissDirection.startToEnd); expect(find.text('0'), findsOneWidget); expect(dismissedItems, isEmpty); - dismissItem(tester, 1, gestureDirection: DismissDirection.startToEnd); + await dismissItem(tester, 1, gestureDirection: DismissDirection.startToEnd); - dismissItem(tester, 0, gestureDirection: DismissDirection.endToStart); + await dismissItem(tester, 0, gestureDirection: DismissDirection.endToStart); expect(find.text('0'), findsNothing); expect(dismissedItems, equals([0])); - dismissItem(tester, 1, gestureDirection: DismissDirection.endToStart); + await dismissItem(tester, 1, gestureDirection: DismissDirection.endToStart); }); - testWidgets('drag-right with DismissDirection.right triggers dismiss', (WidgetTester tester) { + testWidgets('drag-right with DismissDirection.right triggers dismiss', (WidgetTester tester) async { scrollDirection = Axis.vertical; dismissDirection = DismissDirection.startToEnd; - tester.pumpWidget(widgetBuilder()); + await tester.pumpWidget(widgetBuilder()); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.endToStart); + await dismissItem(tester, 0, gestureDirection: DismissDirection.endToStart); expect(find.text('0'), findsOneWidget); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.startToEnd); + await dismissItem(tester, 0, gestureDirection: DismissDirection.startToEnd); expect(find.text('0'), findsNothing); expect(dismissedItems, equals([0])); }); - testWidgets('drag-up with DismissDirection.up triggers dismiss', (WidgetTester tester) { + testWidgets('drag-up with DismissDirection.up triggers dismiss', (WidgetTester tester) async { scrollDirection = Axis.horizontal; dismissDirection = DismissDirection.up; - tester.pumpWidget(widgetBuilder()); + await tester.pumpWidget(widgetBuilder()); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.down); + await dismissItem(tester, 0, gestureDirection: DismissDirection.down); expect(find.text('0'), findsOneWidget); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.up); + await dismissItem(tester, 0, gestureDirection: DismissDirection.up); expect(find.text('0'), findsNothing); expect(dismissedItems, equals([0])); }); - testWidgets('drag-down with DismissDirection.down triggers dismiss', (WidgetTester tester) { + testWidgets('drag-down with DismissDirection.down triggers dismiss', (WidgetTester tester) async { scrollDirection = Axis.horizontal; dismissDirection = DismissDirection.down; - tester.pumpWidget(widgetBuilder()); + await tester.pumpWidget(widgetBuilder()); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.up); + await dismissItem(tester, 0, gestureDirection: DismissDirection.up); expect(find.text('0'), findsOneWidget); expect(dismissedItems, isEmpty); - dismissItem(tester, 0, gestureDirection: DismissDirection.down); + await dismissItem(tester, 0, gestureDirection: DismissDirection.down); expect(find.text('0'), findsNothing); expect(dismissedItems, equals([0])); }); @@ -238,23 +237,23 @@ void main() { // now since we migrated to the new repo. The bug was fixed by // https://github.com/flutter/engine/pull/1134 at the time, and later made // irrelevant by fn3, but just in case... - testWidgets('Verify that drag-move events do not assert', (WidgetTester tester) { + testWidgets('Verify that drag-move events do not assert', (WidgetTester tester) async { scrollDirection = Axis.horizontal; dismissDirection = DismissDirection.down; - tester.pumpWidget(widgetBuilder()); + await tester.pumpWidget(widgetBuilder()); Point location = tester.getTopLeft(find.text('0')); Offset offset = new Offset(0.0, 5.0); - TestGesture gesture = tester.startGesture(location, pointer: 5); - gesture.moveBy(offset); - tester.pumpWidget(widgetBuilder()); - gesture.moveBy(offset); - tester.pumpWidget(widgetBuilder()); - gesture.moveBy(offset); - tester.pumpWidget(widgetBuilder()); - gesture.moveBy(offset); - tester.pumpWidget(widgetBuilder()); - gesture.up(); + TestGesture gesture = await tester.startGesture(location, pointer: 5); + await gesture.moveBy(offset); + await tester.pumpWidget(widgetBuilder()); + await gesture.moveBy(offset); + await tester.pumpWidget(widgetBuilder()); + await gesture.moveBy(offset); + await tester.pumpWidget(widgetBuilder()); + await gesture.moveBy(offset); + await tester.pumpWidget(widgetBuilder()); + await gesture.up(); }); // This one is for a case where dssmissing a widget above a previously @@ -263,8 +262,8 @@ void main() { // died in the migration to the new repo). Don't copy this test; it doesn't // actually remove the dismissed widget, which is a violation of the // Dismissable contract. This is not an example of good practice. - testWidgets('dismissing bottom then top (smoketest)', (WidgetTester tester) { - tester.pumpWidget(new Center( + testWidgets('dismissing bottom then top (smoketest)', (WidgetTester tester) async { + await tester.pumpWidget(new Center( child: new Container( width: 100.0, height: 1000.0, @@ -278,30 +277,30 @@ void main() { )); expect(find.text('1'), findsOneWidget); expect(find.text('2'), findsOneWidget); - dismissElement(tester, find.text('2'), gestureDirection: DismissDirection.startToEnd); - tester.pump(); // start the slide away - tester.pump(new Duration(seconds: 1)); // finish the slide away + await dismissElement(tester, find.text('2'), gestureDirection: DismissDirection.startToEnd); + await tester.pump(); // start the slide away + await tester.pump(new Duration(seconds: 1)); // finish the slide away expect(find.text('1'), findsOneWidget); expect(find.text('2'), findsNothing); - dismissElement(tester, find.text('1'), gestureDirection: DismissDirection.startToEnd); - tester.pump(); // start the slide away - tester.pump(new Duration(seconds: 1)); // finish the slide away (at which point the child is no longer included in the tree) + await dismissElement(tester, find.text('1'), gestureDirection: DismissDirection.startToEnd); + await tester.pump(); // start the slide away + await tester.pump(new Duration(seconds: 1)); // finish the slide away (at which point the child is no longer included in the tree) expect(find.text('1'), findsNothing); expect(find.text('2'), findsNothing); }); - testWidgets('Dismissable starts from the full size when collapsing', (WidgetTester tester) { + testWidgets('Dismissable starts from the full size when collapsing', (WidgetTester tester) async { scrollDirection = Axis.vertical; dismissDirection = DismissDirection.horizontal; background = new Text('background'); - tester.pumpWidget(widgetBuilder()); + await tester.pumpWidget(widgetBuilder()); expect(dismissedItems, isEmpty); Finder itemFinder = find.text('0'); expect(itemFinder, findsOneWidget); - dismissElement(tester, itemFinder, gestureDirection: DismissDirection.startToEnd); - tester.pump(); + await dismissElement(tester, itemFinder, gestureDirection: DismissDirection.startToEnd); + await tester.pump(); expect(find.text('background'), findsNWidgets(5)); RenderBox backgroundBox = tester.firstRenderObject(find.text('background')); diff --git a/packages/flutter/test/widget/draggable_test.dart b/packages/flutter/test/widget/draggable_test.dart index 75c038396b..5d48c21a4d 100644 --- a/packages/flutter/test/widget/draggable_test.dart +++ b/packages/flutter/test/widget/draggable_test.dart @@ -4,13 +4,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Drag and drop - control test', (WidgetTester tester) { + testWidgets('Drag and drop - control test', (WidgetTester tester) async { List accepted = []; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new Draggable( @@ -36,8 +35,8 @@ void main() { expect(find.text('Target'), findsOneWidget); Point firstLocation = tester.getCenter(find.text('Source')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); expect(accepted, isEmpty); expect(find.text('Source'), findsOneWidget); @@ -45,16 +44,16 @@ void main() { expect(find.text('Target'), findsOneWidget); Point secondLocation = tester.getCenter(find.text('Target')); - gesture.moveTo(secondLocation); - tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); expect(accepted, isEmpty); expect(find.text('Source'), findsOneWidget); expect(find.text('Dragging'), findsOneWidget); expect(find.text('Target'), findsOneWidget); - gesture.up(); - tester.pump(); + await gesture.up(); + await tester.pump(); expect(accepted, equals([1])); expect(find.text('Source'), findsOneWidget); @@ -62,11 +61,11 @@ void main() { expect(find.text('Target'), findsOneWidget); }); - testWidgets('Drag and drop - dragging over button', (WidgetTester tester) { + testWidgets('Drag and drop - dragging over button', (WidgetTester tester) async { List events = []; Point firstLocation, secondLocation; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new Draggable( @@ -108,55 +107,55 @@ void main() { // taps (we check both to make sure the test is consistent) expect(events, isEmpty); - tester.tap(find.text('Button')); + await tester.tap(find.text('Button')); expect(events, equals(['tap'])); events.clear(); expect(events, isEmpty); - tester.tap(find.text('Target')); + await tester.tap(find.text('Target')); expect(events, equals(['tap'])); events.clear(); // drag and drop firstLocation = tester.getCenter(find.text('Source')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); secondLocation = tester.getCenter(find.text('Target')); - gesture.moveTo(secondLocation); - tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); expect(events, isEmpty); - gesture.up(); - tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop'])); events.clear(); // drag and tap and drop firstLocation = tester.getCenter(find.text('Source')); - gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); + gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); secondLocation = tester.getCenter(find.text('Target')); - gesture.moveTo(secondLocation); - tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); expect(events, isEmpty); - tester.tap(find.text('Button')); - tester.tap(find.text('Target')); - gesture.up(); - tester.pump(); + await tester.tap(find.text('Button')); + await tester.tap(find.text('Target')); + await gesture.up(); + await tester.pump(); expect(events, equals(['tap', 'tap', 'drop'])); events.clear(); }); - testWidgets('Drag and drop - tapping button', (WidgetTester tester) { + testWidgets('Drag and drop - tapping button', (WidgetTester tester) async { List events = []; Point firstLocation, secondLocation; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new Draggable( @@ -187,30 +186,30 @@ void main() { expect(find.text('Target'), findsOneWidget); expect(events, isEmpty); - tester.tap(find.text('Button')); + await tester.tap(find.text('Button')); expect(events, equals(['tap'])); events.clear(); firstLocation = tester.getCenter(find.text('Button')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); secondLocation = tester.getCenter(find.text('Target')); - gesture.moveTo(secondLocation); - tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); expect(events, isEmpty); - gesture.up(); - tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop'])); events.clear(); }); - testWidgets('Drag and drop - long press draggable, short press', (WidgetTester tester) { + testWidgets('Drag and drop - long press draggable, short press', (WidgetTester tester) async { List events = []; Point firstLocation, secondLocation; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new LongPressDraggable( @@ -235,28 +234,28 @@ void main() { expect(find.text('Target'), findsOneWidget); expect(events, isEmpty); - tester.tap(find.text('Source')); + await tester.tap(find.text('Source')); expect(events, isEmpty); firstLocation = tester.getCenter(find.text('Source')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); secondLocation = tester.getCenter(find.text('Target')); - gesture.moveTo(secondLocation); - tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); expect(events, isEmpty); - gesture.up(); - tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, isEmpty); }); - testWidgets('Drag and drop - long press draggable, long press', (WidgetTester tester) { + testWidgets('Drag and drop - long press draggable, long press', (WidgetTester tester) async { List events = []; Point firstLocation, secondLocation; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new Draggable( @@ -281,30 +280,30 @@ void main() { expect(find.text('Target'), findsOneWidget); expect(events, isEmpty); - tester.tap(find.text('Source')); + await tester.tap(find.text('Source')); expect(events, isEmpty); firstLocation = tester.getCenter(find.text('Source')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); - tester.pump(const Duration(seconds: 20)); + await tester.pump(const Duration(seconds: 20)); secondLocation = tester.getCenter(find.text('Target')); - gesture.moveTo(secondLocation); - tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); expect(events, isEmpty); - gesture.up(); - tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop'])); }); - testWidgets('Drag and drop - horizontal and vertical draggables in vertical block', (WidgetTester tester) { + testWidgets('Drag and drop - horizontal and vertical draggables in vertical block', (WidgetTester tester) async { List events = []; Point firstLocation, secondLocation, thirdLocation; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Block( children: [ new DragTarget( @@ -343,12 +342,12 @@ void main() { expect(events, isEmpty); firstLocation = tester.getCenter(find.text('V')); secondLocation = tester.getCenter(find.text('Target')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); - gesture.moveTo(secondLocation); - tester.pump(); - gesture.up(); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop 2'])); expect(tester.getCenter(find.text('Target')).y, greaterThan(0.0)); events.clear(); @@ -358,14 +357,14 @@ void main() { firstLocation = tester.getTopLeft(find.text('H')); secondLocation = tester.getTopRight(find.text('H')); thirdLocation = tester.getCenter(find.text('Target')); - gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); - gesture.moveTo(secondLocation); - tester.pump(); - gesture.moveTo(thirdLocation); - tester.pump(); - gesture.up(); - tester.pump(); + gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); + await gesture.moveTo(thirdLocation); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop 1'])); expect(tester.getCenter(find.text('Target')).y, greaterThan(0.0)); events.clear(); @@ -376,14 +375,14 @@ void main() { firstLocation = tester.getTopLeft(find.text('V')); secondLocation = tester.getTopRight(find.text('V')); thirdLocation = tester.getCenter(find.text('Target')); - gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); - gesture.moveTo(secondLocation); - tester.pump(); - gesture.moveTo(thirdLocation); - tester.pump(); - gesture.up(); - tester.pump(); + gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); + await gesture.moveTo(thirdLocation); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop 2'])); expect(tester.getCenter(find.text('Target')).y, greaterThan(0.0)); events.clear(); @@ -393,22 +392,22 @@ void main() { expect(events, isEmpty); firstLocation = tester.getCenter(find.text('H')); secondLocation = tester.getCenter(find.text('Target')); - gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); - gesture.moveTo(secondLocation); - tester.pump(); // scrolls off screen! - gesture.up(); - tester.pump(); + gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); // scrolls off screen! + await gesture.up(); + await tester.pump(); expect(events, equals([])); expect(tester.getCenter(find.text('Target')).y, lessThan(0.0)); events.clear(); }); - testWidgets('Drag and drop - horizontal and vertical draggables in horizontal block', (WidgetTester tester) { + testWidgets('Drag and drop - horizontal and vertical draggables in horizontal block', (WidgetTester tester) async { List events = []; Point firstLocation, secondLocation, thirdLocation; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Block( scrollDirection: Axis.horizontal, children: [ @@ -448,12 +447,12 @@ void main() { expect(events, isEmpty); firstLocation = tester.getCenter(find.text('H')); secondLocation = tester.getCenter(find.text('Target')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); - gesture.moveTo(secondLocation); - tester.pump(); - gesture.up(); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop 1'])); expect(tester.getCenter(find.text('Target')).x, greaterThan(0.0)); events.clear(); @@ -463,14 +462,14 @@ void main() { firstLocation = tester.getTopLeft(find.text('V')); secondLocation = tester.getBottomLeft(find.text('V')); thirdLocation = tester.getCenter(find.text('Target')); - gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); - gesture.moveTo(secondLocation); - tester.pump(); - gesture.moveTo(thirdLocation); - tester.pump(); - gesture.up(); - tester.pump(); + gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); + await gesture.moveTo(thirdLocation); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop 2'])); expect(tester.getCenter(find.text('Target')).x, greaterThan(0.0)); events.clear(); @@ -481,14 +480,14 @@ void main() { firstLocation = tester.getTopLeft(find.text('H')); secondLocation = tester.getBottomLeft(find.text('H')); thirdLocation = tester.getCenter(find.text('Target')); - gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); - gesture.moveTo(secondLocation); - tester.pump(); - gesture.moveTo(thirdLocation); - tester.pump(); - gesture.up(); - tester.pump(); + gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); + await gesture.moveTo(thirdLocation); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(events, equals(['drop 1'])); expect(tester.getCenter(find.text('Target')).x, greaterThan(0.0)); events.clear(); @@ -498,22 +497,22 @@ void main() { expect(events, isEmpty); firstLocation = tester.getCenter(find.text('V')); secondLocation = tester.getCenter(find.text('Target')); - gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); - gesture.moveTo(secondLocation); - tester.pump(); // scrolls off screen! - gesture.up(); - tester.pump(); + gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); // scrolls off screen! + await gesture.up(); + await tester.pump(); expect(events, equals([])); expect(tester.getCenter(find.text('Target')).x, lessThan(0.0)); events.clear(); }); - testWidgets('Drag and drop - onDraggableDropped not called if dropped on accepting target', (WidgetTester tester) { + testWidgets('Drag and drop - onDraggableDropped not called if dropped on accepting target', (WidgetTester tester) async { List accepted = []; bool onDraggableCanceledCalled = false; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new Draggable( @@ -543,8 +542,8 @@ void main() { expect(onDraggableCanceledCalled, isFalse); Point firstLocation = tester.getCenter(find.text('Source')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); expect(accepted, isEmpty); expect(find.text('Source'), findsOneWidget); @@ -553,8 +552,8 @@ void main() { expect(onDraggableCanceledCalled, isFalse); Point secondLocation = tester.getCenter(find.text('Target')); - gesture.moveTo(secondLocation); - tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); expect(accepted, isEmpty); expect(find.text('Source'), findsOneWidget); @@ -562,8 +561,8 @@ void main() { expect(find.text('Target'), findsOneWidget); expect(onDraggableCanceledCalled, isFalse); - gesture.up(); - tester.pump(); + await gesture.up(); + await tester.pump(); expect(accepted, equals([1])); expect(find.text('Source'), findsOneWidget); @@ -572,13 +571,13 @@ void main() { expect(onDraggableCanceledCalled, isFalse); }); - testWidgets('Drag and drop - onDraggableDropped called if dropped on non-accepting target', (WidgetTester tester) { + testWidgets('Drag and drop - onDraggableDropped called if dropped on non-accepting target', (WidgetTester tester) async { List accepted = []; bool onDraggableCanceledCalled = false; Velocity onDraggableCanceledVelocity; Offset onDraggableCanceledOffset; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new Draggable( @@ -611,8 +610,8 @@ void main() { expect(onDraggableCanceledCalled, isFalse); Point firstLocation = tester.getTopLeft(find.text('Source')); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); - tester.pump(); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); + await tester.pump(); expect(accepted, isEmpty); expect(find.text('Source'), findsOneWidget); @@ -621,8 +620,8 @@ void main() { expect(onDraggableCanceledCalled, isFalse); Point secondLocation = tester.getCenter(find.text('Target')); - gesture.moveTo(secondLocation); - tester.pump(); + await gesture.moveTo(secondLocation); + await tester.pump(); expect(accepted, isEmpty); expect(find.text('Source'), findsOneWidget); @@ -630,8 +629,8 @@ void main() { expect(find.text('Target'), findsOneWidget); expect(onDraggableCanceledCalled, isFalse); - gesture.up(); - tester.pump(); + await gesture.up(); + await tester.pump(); expect(accepted, isEmpty); expect(find.text('Source'), findsOneWidget); @@ -642,13 +641,13 @@ void main() { expect(onDraggableCanceledOffset, equals(new Offset(secondLocation.x, secondLocation.y))); }); - testWidgets('Drag and drop - onDraggableDropped called if dropped on non-accepting target with correct velocity', (WidgetTester tester) { + testWidgets('Drag and drop - onDraggableDropped called if dropped on non-accepting target with correct velocity', (WidgetTester tester) async { List accepted = []; bool onDraggableCanceledCalled = false; Velocity onDraggableCanceledVelocity; Offset onDraggableCanceledOffset; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column(children: [ new Draggable( data: 1, @@ -679,8 +678,8 @@ void main() { expect(onDraggableCanceledCalled, isFalse); Point flingStart = tester.getTopLeft(find.text('Source')); - tester.flingFrom(flingStart, new Offset(0.0, 100.0), 1000.0); - tester.pump(); + await tester.flingFrom(flingStart, new Offset(0.0, 100.0), 1000.0); + await tester.pump(); expect(accepted, isEmpty); expect(find.text('Source'), findsOneWidget); @@ -692,11 +691,11 @@ void main() { expect(onDraggableCanceledOffset, equals(new Offset(flingStart.x, flingStart.y) + new Offset(0.0, 100.0))); }); - testWidgets('Drag and drop - allow pass thru of unaccepted data test', (WidgetTester tester) { + testWidgets('Drag and drop - allow pass thru of unaccepted data test', (WidgetTester tester) async { List acceptedInts = []; List acceptedDoubles = []; - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new Draggable( @@ -757,25 +756,24 @@ void main() { Point targetLocation = tester.getCenter(find.text('Target1')); // Drag the double draggable. - TestGesture doubleGesture = - tester.startGesture(doubleLocation, pointer: 7); - tester.pump(); + TestGesture doubleGesture = await tester.startGesture(doubleLocation, pointer: 7); + await tester.pump(); expect(acceptedInts, isEmpty); expect(acceptedDoubles, isEmpty); expect(find.text('IntDragging'), findsNothing); expect(find.text('DoubleDragging'), findsOneWidget); - doubleGesture.moveTo(targetLocation); - tester.pump(); + await doubleGesture.moveTo(targetLocation); + await tester.pump(); expect(acceptedInts, isEmpty); expect(acceptedDoubles, isEmpty); expect(find.text('IntDragging'), findsNothing); expect(find.text('DoubleDragging'), findsOneWidget); - doubleGesture.up(); - tester.pump(); + await doubleGesture.up(); + await tester.pump(); expect(acceptedInts, isEmpty); expect(acceptedDoubles, equals([1.0])); @@ -785,24 +783,24 @@ void main() { acceptedDoubles.clear(); // Drag the int draggable. - TestGesture intGesture = tester.startGesture(intLocation, pointer: 7); - tester.pump(); + TestGesture intGesture = await tester.startGesture(intLocation, pointer: 7); + await tester.pump(); expect(acceptedInts, isEmpty); expect(acceptedDoubles, isEmpty); expect(find.text('IntDragging'), findsOneWidget); expect(find.text('DoubleDragging'), findsNothing); - intGesture.moveTo(targetLocation); - tester.pump(); + await intGesture.moveTo(targetLocation); + await tester.pump(); expect(acceptedInts, isEmpty); expect(acceptedDoubles, isEmpty); expect(find.text('IntDragging'), findsOneWidget); expect(find.text('DoubleDragging'), findsNothing); - intGesture.up(); - tester.pump(); + await intGesture.up(); + await tester.pump(); expect(acceptedInts, equals([1])); expect(acceptedDoubles, isEmpty); @@ -810,11 +808,11 @@ void main() { expect(find.text('DoubleDragging'), findsNothing); }); - testWidgets('Drag and drop - allow pass thru of unaccepted data twice test', (WidgetTester tester) { + testWidgets('Drag and drop - allow pass thru of unaccepted data twice test', (WidgetTester tester) async { List acceptedDragTargetDatas = []; List acceptedExtendedDragTargetDatas = []; DragTargetData dragTargetData = new DragTargetData(); - tester.pumpWidget(new MaterialApp( + await tester.pumpWidget(new MaterialApp( home: new Column( children: [ new Draggable( @@ -859,18 +857,18 @@ void main() { Point targetLocation = tester.getCenter(find.text('Target1')); for (int i = 0; i < 2; i += 1) { - TestGesture gesture = tester.startGesture(dragTargetLocation); - tester.pump(); - gesture.moveTo(targetLocation); - tester.pump(); - gesture.up(); - tester.pump(); + TestGesture gesture = await tester.startGesture(dragTargetLocation); + await tester.pump(); + await gesture.moveTo(targetLocation); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(acceptedDragTargetDatas, equals([dragTargetData])); expect(acceptedExtendedDragTargetDatas, isEmpty); acceptedDragTargetDatas.clear(); - tester.pump(); + await tester.pump(); } }); } diff --git a/packages/flutter/test/widget/drawer_test.dart b/packages/flutter/test/widget/drawer_test.dart index 5d81319e8b..3258f0e583 100644 --- a/packages/flutter/test/widget/drawer_test.dart +++ b/packages/flutter/test/widget/drawer_test.dart @@ -5,14 +5,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Drawer control test', (WidgetTester tester) { + testWidgets('Drawer control test', (WidgetTester tester) async { GlobalKey scaffoldKey = new GlobalKey(); BuildContext savedContext; - tester.pumpWidget( + await tester.pumpWidget( new MaterialApp( home: new Builder( builder: (BuildContext context) { @@ -26,23 +25,23 @@ void main() { ) ) ); - tester.pump(); // no effect + await tester.pump(); // no effect expect(find.text('drawer'), findsNothing); scaffoldKey.currentState.openDrawer(); - tester.pump(); // drawer should be starting to animate in + await tester.pump(); // drawer should be starting to animate in expect(find.text('drawer'), findsOneWidget); - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(new Duration(seconds: 1)); // animation done expect(find.text('drawer'), findsOneWidget); Navigator.pop(savedContext); - tester.pump(); // drawer should be starting to animate away + await tester.pump(); // drawer should be starting to animate away expect(find.text('drawer'), findsOneWidget); - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(new Duration(seconds: 1)); // animation done expect(find.text('drawer'), findsNothing); }); - testWidgets('Drawer tap test', (WidgetTester tester) { + testWidgets('Drawer tap test', (WidgetTester tester) async { GlobalKey scaffoldKey = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new MaterialApp( home: new Scaffold( key: scaffoldKey, @@ -51,30 +50,30 @@ void main() { ) ) ); - tester.pump(); // no effect + await tester.pump(); // no effect expect(find.text('drawer'), findsNothing); scaffoldKey.currentState.openDrawer(); - tester.pump(); // drawer should be starting to animate in + await tester.pump(); // drawer should be starting to animate in expect(find.text('drawer'), findsOneWidget); - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(new Duration(seconds: 1)); // animation done expect(find.text('drawer'), findsOneWidget); - tester.tap(find.text('drawer')); - tester.pump(); // nothing should have happened + await tester.tap(find.text('drawer')); + await tester.pump(); // nothing should have happened expect(find.text('drawer'), findsOneWidget); - tester.pump(new Duration(seconds: 1)); // ditto + await tester.pump(new Duration(seconds: 1)); // ditto expect(find.text('drawer'), findsOneWidget); - tester.tapAt(const Point(750.0, 100.0)); // on the mask - tester.pump(); - tester.pump(new Duration(milliseconds: 10)); + await tester.tapAt(const Point(750.0, 100.0)); // on the mask + await tester.pump(); + await tester.pump(new Duration(milliseconds: 10)); // drawer should be starting to animate away expect(find.text('drawer'), findsOneWidget); - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(new Duration(seconds: 1)); // animation done expect(find.text('drawer'), findsNothing); }); - testWidgets('Drawer drag cancel resume', (WidgetTester tester) { + testWidgets('Drawer drag cancel resume', (WidgetTester tester) async { GlobalKey scaffoldKey = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new MaterialApp( home: new Scaffold( key: scaffoldKey, @@ -97,32 +96,32 @@ void main() { ); expect(find.text('drawer'), findsNothing); scaffoldKey.currentState.openDrawer(); - tester.pump(); // drawer should be starting to animate in + await tester.pump(); // drawer should be starting to animate in expect(find.text('drawer'), findsOneWidget); - tester.pump(new Duration(seconds: 1)); // animation done + await tester.pump(new Duration(seconds: 1)); // animation done expect(find.text('drawer'), findsOneWidget); - tester.tapAt(const Point(750.0, 100.0)); // on the mask - tester.pump(); - tester.pump(new Duration(milliseconds: 10)); + await tester.tapAt(const Point(750.0, 100.0)); // on the mask + await tester.pump(); + await tester.pump(new Duration(milliseconds: 10)); // drawer should be starting to animate away RenderBox textBox = tester.renderObject(find.text('drawer')); double textLeft = textBox.localToGlobal(Point.origin).x; expect(textLeft, lessThan(0.0)); - TestGesture gesture = tester.startGesture(new Point(100.0, 100.0)); + TestGesture gesture = await tester.startGesture(new Point(100.0, 100.0)); // drawer should be stopped. - tester.pump(); - tester.pump(new Duration(milliseconds: 10)); + await tester.pump(); + await tester.pump(new Duration(milliseconds: 10)); expect(textBox.localToGlobal(Point.origin).x, equals(textLeft)); - gesture.moveBy(new Offset(0.0, -50.0)); + await gesture.moveBy(new Offset(0.0, -50.0)); // drawer should be returning to visible - tester.pump(); - tester.pump(new Duration(seconds: 1)); + await tester.pump(); + await tester.pump(new Duration(seconds: 1)); expect(textBox.localToGlobal(Point.origin).x, equals(0.0)); - gesture.up(); + await gesture.up(); }); } diff --git a/packages/flutter/test/widget/duplicate_key_test.dart b/packages/flutter/test/widget/duplicate_key_test.dart index a433ae4930..9af3f2696b 100644 --- a/packages/flutter/test/widget/duplicate_key_test.dart +++ b/packages/flutter/test/widget/duplicate_key_test.dart @@ -54,14 +54,14 @@ Widget builder() { } void main() { - testWidgets('duplicate key smoke test', (WidgetTester tester) { - tester.pumpWidget(builder()); + testWidgets('duplicate key smoke test', (WidgetTester tester) async { + await tester.pumpWidget(builder()); StatefulLeafState leaf = tester.firstState(find.byType(StatefulLeaf)); leaf.test(); - tester.pump(); + await tester.pump(); Item lastItem = items[1]; items.remove(lastItem); items.insert(0, lastItem); - tester.pumpWidget(builder()); // this marks the app dirty and rebuilds it + await tester.pumpWidget(builder()); // this marks the app dirty and rebuilds it }); } diff --git a/packages/flutter/test/widget/flex_test.dart b/packages/flutter/test/widget/flex_test.dart index 806673109b..98ccd43097 100644 --- a/packages/flutter/test/widget/flex_test.dart +++ b/packages/flutter/test/widget/flex_test.dart @@ -5,12 +5,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Can hit test flex children of stacks', (WidgetTester tester) { + testWidgets('Can hit test flex children of stacks', (WidgetTester tester) async { bool didReceiveTap = false; - tester.pumpWidget( + await tester.pumpWidget( new Container( decoration: const BoxDecoration( backgroundColor: const Color(0xFF00FF00) @@ -45,15 +44,15 @@ void main() { ) ); - tester.tap(find.text('X')); + await tester.tap(find.text('X')); expect(didReceiveTap, isTrue); }); - testWidgets('Row and FlexJustifyContent.collapse', (WidgetTester tester) { + testWidgets('Row and FlexJustifyContent.collapse', (WidgetTester tester) async { final Key flexKey = new Key('flexKey'); // Row without mainAxisAlignment: FlexJustifyContent.collapse - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new Row( children: [ new Container(width: 10.0, height: 100.0), @@ -67,7 +66,7 @@ void main() { expect(renderBox.size.height, equals(100.0)); // Row with mainAxisAlignment: FlexJustifyContent.collapse - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new Row( children: [ new Container(width: 10.0, height: 100.0), @@ -82,11 +81,11 @@ void main() { expect(renderBox.size.height, equals(100.0)); }); - testWidgets('Column and FlexJustifyContent.collapse', (WidgetTester tester) { + testWidgets('Column and FlexJustifyContent.collapse', (WidgetTester tester) async { final Key flexKey = new Key('flexKey'); // Column without mainAxisAlignment: FlexJustifyContent.collapse - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new Column( children: [ new Container(width: 100.0, height: 100.0), @@ -100,7 +99,7 @@ void main() { expect(renderBox.size.height, equals(600.0)); // Column with mainAxisAlignment: FlexJustifyContent.collapse - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new Column( children: [ new Container(width: 100.0, height: 100.0), @@ -115,10 +114,10 @@ void main() { expect(renderBox.size.height, equals(250.0)); }); - testWidgets('Can layout at zero size', (WidgetTester tester) { + testWidgets('Can layout at zero size', (WidgetTester tester) async { final Key childKey = new Key('childKey'); - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new Container( width: 0.0, height: 0.0, @@ -139,7 +138,7 @@ void main() { expect(renderBox.size.width, equals(0.0)); expect(renderBox.size.height, equals(100.0)); - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new Container( width: 0.0, height: 0.0, diff --git a/packages/flutter/test/widget/flow_test.dart b/packages/flutter/test/widget/flow_test.dart index 45c8ac3b8d..38d533cbe5 100644 --- a/packages/flutter/test/widget/flow_test.dart +++ b/packages/flutter/test/widget/flow_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class TestFlowDelegate extends FlowDelegate { TestFlowDelegate({ @@ -32,7 +31,7 @@ class TestFlowDelegate extends FlowDelegate { } void main() { - testWidgets('Flow control test', (WidgetTester tester) { + testWidgets('Flow control test', (WidgetTester tester) async { AnimationController startOffset = new AnimationController.unbounded(); List log = []; @@ -52,7 +51,7 @@ void main() { ); } - tester.pumpWidget( + await tester.pumpWidget( new Flow( delegate: new TestFlowDelegate(startOffset: startOffset), children: [ @@ -67,22 +66,22 @@ void main() { ) ); - tester.tap(find.text('0')); + await tester.tap(find.text('0')); expect(log, equals([0])); - tester.tap(find.text('1')); + await tester.tap(find.text('1')); expect(log, equals([0, 1])); - tester.tap(find.text('2')); + await tester.tap(find.text('2')); expect(log, equals([0, 1, 2])); log.clear(); - tester.tapAt(new Point(20.0, 90.0)); + await tester.tapAt(new Point(20.0, 90.0)); expect(log, equals([1])); startOffset.value = 50.0; - tester.pump(); + await tester.pump(); log.clear(); - tester.tapAt(new Point(20.0, 90.0)); + await tester.tapAt(new Point(20.0, 90.0)); expect(log, equals([0])); }); } diff --git a/packages/flutter/test/widget/focus_test.dart b/packages/flutter/test/widget/focus_test.dart index 55e8959bb1..f64987f808 100644 --- a/packages/flutter/test/widget/focus_test.dart +++ b/packages/flutter/test/widget/focus_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class TestFocusable extends StatelessWidget { TestFocusable({ @@ -29,11 +28,11 @@ class TestFocusable extends StatelessWidget { } void main() { - testWidgets('Can have multiple focused children and they update accordingly', (WidgetTester tester) { + testWidgets('Can have multiple focused children and they update accordingly', (WidgetTester tester) async { GlobalKey keyFocus = new GlobalKey(); GlobalKey keyA = new GlobalKey(); GlobalKey keyB = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Focus( key: keyFocus, child: new Column( @@ -56,36 +55,36 @@ void main() { expect(find.text('A FOCUSED'), findsOneWidget); expect(find.text('b'), findsOneWidget); expect(find.text('B FOCUSED'), findsNothing); - tester.tap(find.text('A FOCUSED')); - tester.pump(); + await tester.tap(find.text('A FOCUSED')); + await tester.pump(); expect(find.text('a'), findsNothing); expect(find.text('A FOCUSED'), findsOneWidget); expect(find.text('b'), findsOneWidget); expect(find.text('B FOCUSED'), findsNothing); - tester.tap(find.text('A FOCUSED')); - tester.pump(); + await tester.tap(find.text('A FOCUSED')); + await tester.pump(); expect(find.text('a'), findsNothing); expect(find.text('A FOCUSED'), findsOneWidget); expect(find.text('b'), findsOneWidget); expect(find.text('B FOCUSED'), findsNothing); - tester.tap(find.text('b')); - tester.pump(); + await tester.tap(find.text('b')); + await tester.pump(); expect(find.text('a'), findsOneWidget); expect(find.text('A FOCUSED'), findsNothing); expect(find.text('b'), findsNothing); expect(find.text('B FOCUSED'), findsOneWidget); - tester.tap(find.text('a')); - tester.pump(); + await tester.tap(find.text('a')); + await tester.pump(); expect(find.text('a'), findsNothing); expect(find.text('A FOCUSED'), findsOneWidget); expect(find.text('b'), findsOneWidget); expect(find.text('B FOCUSED'), findsNothing); }); - testWidgets('Can blur', (WidgetTester tester) { + testWidgets('Can blur', (WidgetTester tester) async { GlobalKey keyFocus = new GlobalKey(); GlobalKey keyA = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Focus( key: keyFocus, child: new TestFocusable( @@ -101,23 +100,23 @@ void main() { expect(find.text('A FOCUSED'), findsNothing); Focus.moveTo(keyA); - tester.pump(); + await tester.pump(); expect(find.text('a'), findsNothing); expect(find.text('A FOCUSED'), findsOneWidget); Focus.clear(keyA.currentContext); - tester.pump(); + await tester.pump(); expect(find.text('a'), findsOneWidget); expect(find.text('A FOCUSED'), findsNothing); }); - testWidgets('Can move focus to scope', (WidgetTester tester) { + testWidgets('Can move focus to scope', (WidgetTester tester) async { GlobalKey keyParentFocus = new GlobalKey(); GlobalKey keyChildFocus = new GlobalKey(); GlobalKey keyA = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Focus( key: keyParentFocus, child: new Row( @@ -137,14 +136,14 @@ void main() { expect(find.text('A FOCUSED'), findsNothing); Focus.moveTo(keyA); - tester.pump(); + await tester.pump(); expect(find.text('a'), findsNothing); expect(find.text('A FOCUSED'), findsOneWidget); Focus.moveScopeTo(keyChildFocus, context: keyA.currentContext); - tester.pumpWidget( + await tester.pumpWidget( new Focus( key: keyParentFocus, child: new Row( @@ -170,7 +169,7 @@ void main() { expect(find.text('a'), findsOneWidget); expect(find.text('A FOCUSED'), findsNothing); - tester.pumpWidget( + await tester.pumpWidget( new Focus( key: keyParentFocus, child: new Row( @@ -190,7 +189,7 @@ void main() { expect(find.text('a'), findsOneWidget); expect(find.text('A FOCUSED'), findsNothing); - tester.pump(); + await tester.pump(); expect(find.text('a'), findsNothing); expect(find.text('A FOCUSED'), findsOneWidget); diff --git a/packages/flutter/test/widget/form_test.dart b/packages/flutter/test/widget/form_test.dart index b391330d31..58254a5184 100644 --- a/packages/flutter/test/widget/form_test.dart +++ b/packages/flutter/test/widget/form_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:sky_services/editing/editing.mojom.dart' as mojom; -import 'package:test/test.dart'; class MockKeyboard implements mojom.Keyboard { mojom.KeyboardClient client; @@ -41,7 +40,7 @@ void main() { ..composingExtent = testValue.length); } - testWidgets('Setter callback is called', (WidgetTester tester) { + testWidgets('Setter callback is called', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); String fieldValue; @@ -60,21 +59,21 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); - void checkText(String testValue) { + Future checkText(String testValue) { enterText(testValue); // Check that the FormField's setter was called. expect(fieldValue, equals(testValue)); - tester.pumpWidget(builder()); + return tester.pumpWidget(builder()); } - checkText('Test'); - checkText(''); + await checkText('Test'); + await checkText(''); }); - testWidgets('Validator sets the error text', (WidgetTester tester) { + testWidgets('Validator sets the error text', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); String errorText(String input) => input + '/error'; @@ -93,21 +92,22 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); - void checkErrorText(String testValue) { + Future checkErrorText(String testValue) async { enterText(testValue); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // Check for a new Text widget with our error text. expect(find.text(errorText(testValue)), findsOneWidget); + return null; } - checkErrorText('Test'); - checkErrorText(''); + await checkErrorText('Test'); + await checkErrorText(''); }); - testWidgets('Multiple Inputs communicate', (WidgetTester tester) { + testWidgets('Multiple Inputs communicate', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); GlobalKey focusKey = new GlobalKey(); // Input 1's text value. @@ -142,21 +142,22 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); Focus.moveTo(inputKey); - tester.pump(); + await tester.pump(); - void checkErrorText(String testValue) { + Future checkErrorText(String testValue) async { enterText(testValue); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); expect(fieldValue, equals(testValue)); // Check for a new Text widget with our error text. expect(find.text(errorText(testValue)), findsOneWidget); + return null; } - checkErrorText('Test'); - checkErrorText(''); + await checkErrorText('Test'); + await checkErrorText(''); }); } diff --git a/packages/flutter/test/widget/fractionally_sized_box_test.dart b/packages/flutter/test/widget/fractionally_sized_box_test.dart index a733f7e566..747a9f529c 100644 --- a/packages/flutter/test/widget/fractionally_sized_box_test.dart +++ b/packages/flutter/test/widget/fractionally_sized_box_test.dart @@ -5,12 +5,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('FractionallySizedBox', (WidgetTester tester) { + testWidgets('FractionallySizedBox', (WidgetTester tester) async { GlobalKey inner = new GlobalKey(); - tester.pumpWidget(new OverflowBox( + await tester.pumpWidget(new OverflowBox( minWidth: 0.0, maxWidth: 100.0, minHeight: 0.0, diff --git a/packages/flutter/test/widget/gesture_detector_test.dart b/packages/flutter/test/widget/gesture_detector_test.dart index e5ea58fd1b..182af1e479 100644 --- a/packages/flutter/test/widget/gesture_detector_test.dart +++ b/packages/flutter/test/widget/gesture_detector_test.dart @@ -4,10 +4,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Uncontested scrolls start immediately', (WidgetTester tester) { + testWidgets('Uncontested scrolls start immediately', (WidgetTester tester) async { bool didStartDrag = false; double updatedDragDelta; bool didEndDrag = false; @@ -29,35 +28,35 @@ void main() { ) ); - tester.pumpWidget(widget); + await tester.pumpWidget(widget); expect(didStartDrag, isFalse); expect(updatedDragDelta, isNull); expect(didEndDrag, isFalse); Point firstLocation = new Point(10.0, 10.0); - TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); + TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7); expect(didStartDrag, isTrue); didStartDrag = false; expect(updatedDragDelta, isNull); expect(didEndDrag, isFalse); Point secondLocation = new Point(10.0, 9.0); - gesture.moveTo(secondLocation); + await gesture.moveTo(secondLocation); expect(didStartDrag, isFalse); expect(updatedDragDelta, -1.0); updatedDragDelta = null; expect(didEndDrag, isFalse); - gesture.up(); + await gesture.up(); expect(didStartDrag, isFalse); expect(updatedDragDelta, isNull); expect(didEndDrag, isTrue); didEndDrag = false; - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); }); - testWidgets('Match two scroll gestures in succession', (WidgetTester tester) { + testWidgets('Match two scroll gestures in succession', (WidgetTester tester) async { int gestureCount = 0; double dragDistance = 0.0; @@ -75,28 +74,28 @@ void main() { ) ) ); - tester.pumpWidget(widget); + await tester.pumpWidget(widget); - TestGesture gesture = tester.startGesture(downLocation, pointer: 7); - gesture.moveTo(upLocation); - gesture.up(); + TestGesture gesture = await tester.startGesture(downLocation, pointer: 7); + await gesture.moveTo(upLocation); + await gesture.up(); - gesture = tester.startGesture(downLocation, pointer: 7); - gesture.moveTo(upLocation); - gesture.up(); + gesture = await tester.startGesture(downLocation, pointer: 7); + await gesture.moveTo(upLocation); + await gesture.up(); expect(gestureCount, 2); expect(dragDistance, 20.0); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); }); - testWidgets('Pan doesn\'t crash', (WidgetTester tester) { + testWidgets('Pan doesn\'t crash', (WidgetTester tester) async { bool didStartPan = false; Offset panDelta; bool didEndPan = false; - tester.pumpWidget( + await tester.pumpWidget( new GestureDetector( onPanStart: (_) { didStartPan = true; @@ -119,7 +118,7 @@ void main() { expect(panDelta, isNull); expect(didEndPan, isFalse); - tester.scrollAt(new Point(10.0, 10.0), new Offset(20.0, 30.0)); + await tester.scrollAt(new Point(10.0, 10.0), new Offset(20.0, 30.0)); expect(didStartPan, isTrue); expect(panDelta.dx, 20.0); @@ -127,12 +126,12 @@ void main() { expect(didEndPan, isTrue); }); - testWidgets('Translucent', (WidgetTester tester) { + testWidgets('Translucent', (WidgetTester tester) async { bool didReceivePointerDown; bool didTap; - void pumpWidgetTree(HitTestBehavior behavior) { - tester.pumpWidget( + Future pumpWidgetTree(HitTestBehavior behavior) { + return tester.pumpWidget( new Stack( children: [ new Listener( @@ -164,29 +163,29 @@ void main() { didReceivePointerDown = false; didTap = false; - pumpWidgetTree(null); - tester.tapAt(new Point(10.0, 10.0)); + await pumpWidgetTree(null); + await tester.tapAt(new Point(10.0, 10.0)); expect(didReceivePointerDown, isTrue); expect(didTap, isTrue); didReceivePointerDown = false; didTap = false; - pumpWidgetTree(HitTestBehavior.deferToChild); - tester.tapAt(new Point(10.0, 10.0)); + await pumpWidgetTree(HitTestBehavior.deferToChild); + await tester.tapAt(new Point(10.0, 10.0)); expect(didReceivePointerDown, isTrue); expect(didTap, isFalse); didReceivePointerDown = false; didTap = false; - pumpWidgetTree(HitTestBehavior.opaque); - tester.tapAt(new Point(10.0, 10.0)); + await pumpWidgetTree(HitTestBehavior.opaque); + await tester.tapAt(new Point(10.0, 10.0)); expect(didReceivePointerDown, isFalse); expect(didTap, isTrue); didReceivePointerDown = false; didTap = false; - pumpWidgetTree(HitTestBehavior.translucent); - tester.tapAt(new Point(10.0, 10.0)); + await pumpWidgetTree(HitTestBehavior.translucent); + await tester.tapAt(new Point(10.0, 10.0)); expect(didReceivePointerDown, isTrue); expect(didTap, isTrue); diff --git a/packages/flutter/test/widget/heroes_test.dart b/packages/flutter/test/widget/heroes_test.dart index 650104ec57..639be2de8e 100644 --- a/packages/flutter/test/widget/heroes_test.dart +++ b/packages/flutter/test/widget/heroes_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; Key firstKey = new Key('first'); Key secondKey = new Key('second'); @@ -42,9 +41,9 @@ class ThreeRoute extends MaterialPageRoute { } void main() { - testWidgets('Heroes animate', (WidgetTester tester) { + testWidgets('Heroes animate', (WidgetTester tester) async { - tester.pumpWidget(new MaterialApp(routes: routes)); + await tester.pumpWidget(new MaterialApp(routes: routes)); // the initial setup. @@ -52,8 +51,8 @@ void main() { expect(find.byKey(firstKey), isInCard); expect(find.byKey(secondKey), findsNothing); - tester.tap(find.text('two')); - tester.pump(); // begin navigation + await tester.tap(find.text('two')); + await tester.pump(); // begin navigation // at this stage, the second route is off-stage, so that we can form the // hero party. @@ -63,7 +62,7 @@ void main() { expect(find.byKey(secondKey), isOffStage); expect(find.byKey(secondKey), isInCard); - tester.pump(); + await tester.pump(); // at this stage, the heroes have just gone on their journey, we are // seeing them at t=16ms. The original page no longer contains the hero. @@ -72,7 +71,7 @@ void main() { expect(find.byKey(secondKey), isOnStage); expect(find.byKey(secondKey), isNotInCard); - tester.pump(); + await tester.pump(); // t=32ms for the journey. Surely they are still at it. @@ -80,7 +79,7 @@ void main() { expect(find.byKey(secondKey), isOnStage); expect(find.byKey(secondKey), isNotInCard); - tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); // t=1.032s for the journey. The journey has ended (it ends this frame, in // fact). The hero should now be in the new page, on-stage. @@ -89,7 +88,7 @@ void main() { expect(find.byKey(secondKey), isOnStage); expect(find.byKey(secondKey), isInCard); - tester.pump(); + await tester.pump(); // Should not change anything. @@ -99,8 +98,8 @@ void main() { // Now move on to view 3 - tester.tap(find.text('three')); - tester.pump(); // begin navigation + await tester.tap(find.text('three')); + await tester.pump(); // begin navigation // at this stage, the second route is off-stage, so that we can form the // hero party. @@ -110,7 +109,7 @@ void main() { expect(find.byKey(thirdKey), isOffStage); expect(find.byKey(thirdKey), isInCard); - tester.pump(); + await tester.pump(); // at this stage, the heroes have just gone on their journey, we are // seeing them at t=16ms. The original page no longer contains the hero. @@ -119,7 +118,7 @@ void main() { expect(find.byKey(thirdKey), isOnStage); expect(find.byKey(thirdKey), isNotInCard); - tester.pump(); + await tester.pump(); // t=32ms for the journey. Surely they are still at it. @@ -127,7 +126,7 @@ void main() { expect(find.byKey(thirdKey), isOnStage); expect(find.byKey(thirdKey), isNotInCard); - tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); // t=1.032s for the journey. The journey has ended (it ends this frame, in // fact). The hero should now be in the new page, on-stage. @@ -136,7 +135,7 @@ void main() { expect(find.byKey(thirdKey), isOnStage); expect(find.byKey(thirdKey), isInCard); - tester.pump(); + await tester.pump(); // Should not change anything. diff --git a/packages/flutter/test/widget/hyperlink_test.dart b/packages/flutter/test/widget/hyperlink_test.dart index a2739cd1d5..b5f0467cda 100644 --- a/packages/flutter/test/widget/hyperlink_test.dart +++ b/packages/flutter/test/widget/hyperlink_test.dart @@ -5,10 +5,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Can tap a hyperlink', (WidgetTester tester) { + testWidgets('Can tap a hyperlink', (WidgetTester tester) async { bool didTapLeft = false; TapGestureRecognizer tapLeft = new TapGestureRecognizer() ..onTap = () { @@ -23,7 +22,7 @@ void main() { Key textKey = new Key('text'); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new RichText( key: textKey, @@ -49,21 +48,21 @@ void main() { expect(didTapLeft, isFalse); expect(didTapRight, isFalse); - tester.tapAt(box.localToGlobal(Point.origin) + new Offset(2.0, 2.0)); + await tester.tapAt(box.localToGlobal(Point.origin) + new Offset(2.0, 2.0)); expect(didTapLeft, isTrue); expect(didTapRight, isFalse); didTapLeft = false; - tester.tapAt(box.localToGlobal(Point.origin) + new Offset(30.0, 2.0)); + await tester.tapAt(box.localToGlobal(Point.origin) + new Offset(30.0, 2.0)); expect(didTapLeft, isTrue); expect(didTapRight, isFalse); didTapLeft = false; - tester.tapAt(box.localToGlobal(new Point(box.size.width, 0.0)) + new Offset(-2.0, 2.0)); + await tester.tapAt(box.localToGlobal(new Point(box.size.width, 0.0)) + new Offset(-2.0, 2.0)); expect(didTapLeft, isFalse); expect(didTapRight, isTrue); diff --git a/packages/flutter/test/widget/icon_test.dart b/packages/flutter/test/widget/icon_test.dart index 2806b52c37..2718a21e7d 100644 --- a/packages/flutter/test/widget/icon_test.dart +++ b/packages/flutter/test/widget/icon_test.dart @@ -4,11 +4,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Can set opacity for an Icon', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Can set opacity for an Icon', (WidgetTester tester) async { + await tester.pumpWidget( new IconTheme( data: new IconThemeData( color: Colors.green[500], diff --git a/packages/flutter/test/widget/image_test.dart b/packages/flutter/test/widget/image_test.dart index 0bba17cf1c..56844638f5 100644 --- a/packages/flutter/test/widget/image_test.dart +++ b/packages/flutter/test/widget/image_test.dart @@ -10,12 +10,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/services.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Verify NetworkImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', (WidgetTester tester) { + testWidgets('Verify NetworkImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', (WidgetTester tester) async { final String testUrl = 'https://foo.bar/baz1.png'; - tester.pumpWidget( + await tester.pumpWidget( new NetworkImage( scale: 1.0, src: testUrl @@ -26,9 +25,9 @@ void main() { expect(find.byKey(new ObjectKey(imageResource)), findsOneWidget); }); - testWidgets('Verify NetworkImage doesn\'t set an ObjectKey on its ImageResource if it has a key', (WidgetTester tester) { + testWidgets('Verify NetworkImage doesn\'t set an ObjectKey on its ImageResource if it has a key', (WidgetTester tester) async { final String testUrl = 'https://foo.bar/baz2.png'; - tester.pumpWidget( + await tester.pumpWidget( new NetworkImage( key: new GlobalKey(), scale: 1.0, @@ -40,17 +39,17 @@ void main() { expect(find.byKey(new ObjectKey(imageResource)), findsNothing); }); - testWidgets('Verify AsyncImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', (WidgetTester tester) { + testWidgets('Verify AsyncImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', (WidgetTester tester) async { ImageProvider imageProvider = new TestImageProvider(); - tester.pumpWidget(new AsyncImage(provider: imageProvider)); + await tester.pumpWidget(new AsyncImage(provider: imageProvider)); ImageResource imageResource = imageCache.loadProvider(imageProvider); expect(find.byKey(new ObjectKey(imageResource)), findsOneWidget); }); - testWidgets('Verify AsyncImage doesn\'t set an ObjectKey on its ImageResource if it has a key', (WidgetTester tester) { + testWidgets('Verify AsyncImage doesn\'t set an ObjectKey on its ImageResource if it has a key', (WidgetTester tester) async { ImageProvider imageProvider = new TestImageProvider(); - tester.pumpWidget( + await tester.pumpWidget( new AsyncImage( key: new GlobalKey(), provider: imageProvider @@ -61,10 +60,10 @@ void main() { expect(find.byKey(new ObjectKey(imageResource)), findsNothing); }); - testWidgets('Verify AssetImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', (WidgetTester tester) { + testWidgets('Verify AssetImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', (WidgetTester tester) async { final String name = 'foo'; final AssetBundle assetBundle = new TestAssetBundle(); - tester.pumpWidget( + await tester.pumpWidget( new AssetImage( name: name, bundle: assetBundle @@ -75,10 +74,10 @@ void main() { expect(find.byKey(new ObjectKey(imageResource)), findsOneWidget); }); - testWidgets('Verify AssetImage doesn\'t set an ObjectKey on its ImageResource if it has a key', (WidgetTester tester) { + testWidgets('Verify AssetImage doesn\'t set an ObjectKey on its ImageResource if it has a key', (WidgetTester tester) async { final String name = 'foo'; final AssetBundle assetBundle = new TestAssetBundle(); - tester.pumpWidget( + await tester.pumpWidget( new AssetImage( key: new GlobalKey(), name: name, @@ -90,10 +89,10 @@ void main() { expect(find.byKey(new ObjectKey(imageResource)), findsNothing); }); - testWidgets('Verify AsyncImage resets its RenderImage when changing providers if it doesn\'t have a key', (WidgetTester tester) { + testWidgets('Verify AsyncImage resets its RenderImage when changing providers if it doesn\'t have a key', (WidgetTester tester) async { final GlobalKey key = new GlobalKey(); TestImageProvider imageProvider1 = new TestImageProvider(); - tester.pumpWidget( + await tester.pumpWidget( new Container( key: key, child: new AsyncImage( @@ -107,14 +106,14 @@ void main() { expect(renderImage.image, isNull); imageProvider1.complete(); - tester.flushMicrotasks(); // resolve the future from the image provider - tester.pump(null, EnginePhase.layout); + await tester.idle(); // resolve the future from the image provider + await tester.pump(null, EnginePhase.layout); renderImage = key.currentContext.findRenderObject(); expect(renderImage.image, isNotNull); TestImageProvider imageProvider2 = new TestImageProvider(); - tester.pumpWidget( + await tester.pumpWidget( new Container( key: key, child: new AsyncImage( @@ -130,10 +129,10 @@ void main() { }); - testWidgets('Verify AsyncImage doesn\'t reset its RenderImage when changing providers if it has a key', (WidgetTester tester) { + testWidgets('Verify AsyncImage doesn\'t reset its RenderImage when changing providers if it has a key', (WidgetTester tester) async { final GlobalKey key = new GlobalKey(); TestImageProvider imageProvider1 = new TestImageProvider(); - tester.pumpWidget( + await tester.pumpWidget( new AsyncImage( key: key, provider: imageProvider1 @@ -145,14 +144,14 @@ void main() { expect(renderImage.image, isNull); imageProvider1.complete(); - tester.flushMicrotasks(); // resolve the future from the image provider - tester.pump(null, EnginePhase.layout); + await tester.idle(); // resolve the future from the image provider + await tester.pump(null, EnginePhase.layout); renderImage = key.currentContext.findRenderObject(); expect(renderImage.image, isNotNull); TestImageProvider imageProvider2 = new TestImageProvider(); - tester.pumpWidget( + await tester.pumpWidget( new AsyncImage( key: key, provider: imageProvider2 diff --git a/packages/flutter/test/widget/independent_widget_layout_test.dart b/packages/flutter/test/widget/independent_widget_layout_test.dart index 258dca5443..a41d7d0e68 100644 --- a/packages/flutter/test/widget/independent_widget_layout_test.dart +++ b/packages/flutter/test/widget/independent_widget_layout_test.dart @@ -5,21 +5,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import 'package:test/test.dart'; const Size _kTestViewSize = const Size(800.0, 600.0); class OffscreenRenderView extends RenderView { - OffscreenRenderView() { - configuration = new ViewConfiguration(size: _kTestViewSize); - } - - @override - void scheduleInitialFrame() { - scheduleInitialLayout(); - scheduleInitialPaint(new TransformLayer(transform: new Matrix4.identity())); - // Don't call SchedulerBinding.instance.ensureVisualUpdate() - } + OffscreenRenderView() : super(configuration: new ViewConfiguration(size: _kTestViewSize)); @override void compositeFrame() { @@ -109,7 +99,7 @@ class TriggerableState extends State { } void main() { - testWidgets('no crosstalk between widget build owners', (WidgetTester tester) { + testWidgets('no crosstalk between widget build owners', (WidgetTester tester) async { Trigger trigger1 = new Trigger(); Counter counter1 = new Counter(); Trigger trigger2 = new Trigger(); @@ -119,7 +109,7 @@ void main() { expect(counter1.count, equals(0)); expect(counter2.count, equals(0)); // Lay out the "onscreen" in the default test binding - tester.pumpWidget(new TriggerableWidget(trigger: trigger1, counter: counter1)); + await tester.pumpWidget(new TriggerableWidget(trigger: trigger1, counter: counter1)); // Only the "onscreen" widget should have built expect(counter1.count, equals(1)); expect(counter2.count, equals(0)); @@ -135,7 +125,7 @@ void main() { expect(counter1.count, equals(1)); expect(counter2.count, equals(1)); // Pump the "onscreen" layout - tester.pump(); + await tester.pump(); // Only the "onscreen" widget should have rebuilt expect(counter1.count, equals(2)); expect(counter2.count, equals(1)); @@ -153,7 +143,7 @@ void main() { expect(counter1.count, equals(2)); expect(counter2.count, equals(3)); // Pump the "onscreen" layout - tester.pump(); + await tester.pump(); // Now both widgets should have rebuilt expect(counter1.count, equals(3)); expect(counter2.count, equals(3)); diff --git a/packages/flutter/test/widget/inherited_test.dart b/packages/flutter/test/widget/inherited_test.dart index fc06580a64..c27b9fa207 100644 --- a/packages/flutter/test/widget/inherited_test.dart +++ b/packages/flutter/test/widget/inherited_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; import 'test_widgets.dart'; @@ -31,7 +30,7 @@ class ValueInherited extends InheritedWidget { } void main() { - testWidgets('Inherited notifies dependents', (WidgetTester tester) { + testWidgets('Inherited notifies dependents', (WidgetTester tester) async { List log = []; Builder builder = new Builder( @@ -42,22 +41,22 @@ void main() { ); TestInherited first = new TestInherited(child: builder); - tester.pumpWidget(first); + await tester.pumpWidget(first); expect(log, equals([first])); TestInherited second = new TestInherited(child: builder, shouldNotify: false); - tester.pumpWidget(second); + await tester.pumpWidget(second); expect(log, equals([first])); TestInherited third = new TestInherited(child: builder, shouldNotify: true); - tester.pumpWidget(third); + await tester.pumpWidget(third); expect(log, equals([first, third])); }); - testWidgets('Update inherited when reparenting state', (WidgetTester tester) { + testWidgets('Update inherited when reparenting state', (WidgetTester tester) async { GlobalKey globalKey = new GlobalKey(); List log = []; @@ -77,20 +76,20 @@ void main() { } TestInherited first = build(); - tester.pumpWidget(first); + await tester.pumpWidget(first); expect(log, equals([first])); TestInherited second = build(); - tester.pumpWidget(second); + await tester.pumpWidget(second); expect(log, equals([first, second])); }); - testWidgets('Update inherited when removing node', (WidgetTester tester) { + testWidgets('Update inherited when removing node', (WidgetTester tester) async { final List log = []; - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new ValueInherited( value: 1, @@ -140,31 +139,31 @@ void main() { expect(log, equals(['a: 3'])); log.clear(); - tester.pump(); + await tester.pump(); expect(log, equals([])); log.clear(); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(log, equals(['b: 2'])); log.clear(); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(log, equals(['a: 3'])); log.clear(); }); - testWidgets('Update inherited when removing node and child has global key', (WidgetTester tester) { + testWidgets('Update inherited when removing node and child has global key', (WidgetTester tester) async { final List log = []; Key key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new ValueInherited( value: 1, @@ -216,25 +215,25 @@ void main() { expect(log, equals(['a: 3'])); log.clear(); - tester.pump(); + await tester.pump(); expect(log, equals([])); log.clear(); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(log, equals(['b: 2'])); log.clear(); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(log, equals(['a: 3'])); log.clear(); }); - testWidgets('Update inherited when removing node and child has global key with constant child', (WidgetTester tester) { + testWidgets('Update inherited when removing node and child has global key with constant child', (WidgetTester tester) async { final List log = []; Key key = new GlobalKey(); @@ -247,7 +246,7 @@ void main() { } ); - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new ValueInherited( value: 1, @@ -287,25 +286,25 @@ void main() { expect(log, equals([3])); log.clear(); - tester.pump(); + await tester.pump(); expect(log, equals([])); log.clear(); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(log, equals([2])); log.clear(); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(log, equals([3])); log.clear(); }); - testWidgets('Update inherited when removing node and child has global key with constant child, minimised', (WidgetTester tester) { + testWidgets('Update inherited when removing node and child has global key with constant child, minimised', (WidgetTester tester) async { final List log = []; @@ -318,7 +317,7 @@ void main() { } ); - tester.pumpWidget( + await tester.pumpWidget( new ValueInherited( value: 2, child: new FlipWidget( @@ -334,25 +333,25 @@ void main() { expect(log, equals([3])); log.clear(); - tester.pump(); + await tester.pump(); expect(log, equals([])); log.clear(); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(log, equals([2])); log.clear(); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(log, equals([3])); log.clear(); }); - testWidgets('Inherited widget notifies descendants when descendant previously failed to find a match', (WidgetTester tester) { + testWidgets('Inherited widget notifies descendants when descendant previously failed to find a match', (WidgetTester tester) async { int inheritedValue = -1; final Widget inner = new Container( @@ -366,13 +365,13 @@ void main() { ) ); - tester.pumpWidget( + await tester.pumpWidget( inner ); expect(inheritedValue, isNull); inheritedValue = -2; - tester.pumpWidget( + await tester.pumpWidget( new ValueInherited( value: 3, child: inner @@ -381,7 +380,7 @@ void main() { expect(inheritedValue, equals(3)); }); - testWidgets('Inherited widget doesn\'t notify descendants when descendant did not previously fail to find a match and had no dependencies', (WidgetTester tester) { + testWidgets('Inherited widget doesn\'t notify descendants when descendant did not previously fail to find a match and had no dependencies', (WidgetTester tester) async { int buildCount = 0; final Widget inner = new Container( @@ -394,12 +393,12 @@ void main() { ) ); - tester.pumpWidget( + await tester.pumpWidget( inner ); expect(buildCount, equals(1)); - tester.pumpWidget( + await tester.pumpWidget( new ValueInherited( value: 3, child: inner @@ -408,7 +407,7 @@ void main() { expect(buildCount, equals(1)); }); - testWidgets('Inherited widget does notify descendants when descendant did not previously fail to find a match but did have other dependencies', (WidgetTester tester) { + testWidgets('Inherited widget does notify descendants when descendant did not previously fail to find a match but did have other dependencies', (WidgetTester tester) async { int buildCount = 0; final Widget inner = new Container( @@ -425,12 +424,12 @@ void main() { ) ); - tester.pumpWidget( + await tester.pumpWidget( inner ); expect(buildCount, equals(1)); - tester.pumpWidget( + await tester.pumpWidget( new ValueInherited( value: 3, child: inner diff --git a/packages/flutter/test/widget/init_state_test.dart b/packages/flutter/test/widget/init_state_test.dart index 6d05506c28..96c5d29063 100644 --- a/packages/flutter/test/widget/init_state_test.dart +++ b/packages/flutter/test/widget/init_state_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; List ancestors = []; @@ -28,8 +27,8 @@ class TestWidgetState extends State { } void main() { - testWidgets('initState() is called when we are in the tree', (WidgetTester tester) { - tester.pumpWidget(new Container(child: new TestWidget())); + testWidgets('initState() is called when we are in the tree', (WidgetTester tester) async { + await tester.pumpWidget(new Container(child: new TestWidget())); expect(ancestors, equals(['Container', 'RenderObjectToWidgetAdapter'])); }); } diff --git a/packages/flutter/test/widget/input_test.dart b/packages/flutter/test/widget/input_test.dart index 1a68202004..b72dd3a1af 100644 --- a/packages/flutter/test/widget/input_test.dart +++ b/packages/flutter/test/widget/input_test.dart @@ -6,7 +6,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:sky_services/editing/editing.mojom.dart' as mojom; -import 'package:test/test.dart'; class MockKeyboard implements mojom.Keyboard { mojom.KeyboardClient client; @@ -55,7 +54,7 @@ void main() { ..composingExtent = testValue.length); } - testWidgets('Editable text has consistent size', (WidgetTester tester) { + testWidgets('Editable text has consistent size', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); InputValue inputValue = InputValue.empty; @@ -72,32 +71,32 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); RenderBox findInputBox() => tester.renderObject(find.byKey(inputKey)); RenderBox inputBox = findInputBox(); Size emptyInputSize = inputBox.size; - void checkText(String testValue) { + Future checkText(String testValue) { enterText(testValue); // Check that the onChanged event handler fired. expect(inputValue.text, equals(testValue)); - tester.pumpWidget(builder()); + return tester.pumpWidget(builder()); } - checkText(' '); + await checkText(' '); expect(findInputBox(), equals(inputBox)); expect(inputBox.size, equals(emptyInputSize)); - checkText('Test'); + await checkText('Test'); expect(findInputBox(), equals(inputBox)); expect(inputBox.size, equals(emptyInputSize)); }); - testWidgets('Cursor blinks', (WidgetTester tester) { + testWidgets('Cursor blinks', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); Widget builder() { @@ -111,36 +110,36 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); RawInputLineState editableText = tester.state(find.byType(RawInputLine)); // Check that the cursor visibility toggles after each blink interval. - void checkCursorToggle() { + Future checkCursorToggle() async { bool initialShowCursor = editableText.cursorCurrentlyVisible; - tester.pump(editableText.cursorBlinkInterval); + await tester.pump(editableText.cursorBlinkInterval); expect(editableText.cursorCurrentlyVisible, equals(!initialShowCursor)); - tester.pump(editableText.cursorBlinkInterval); + await tester.pump(editableText.cursorBlinkInterval); expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor)); - tester.pump(editableText.cursorBlinkInterval ~/ 10); + await tester.pump(editableText.cursorBlinkInterval ~/ 10); expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor)); - tester.pump(editableText.cursorBlinkInterval); + await tester.pump(editableText.cursorBlinkInterval); expect(editableText.cursorCurrentlyVisible, equals(!initialShowCursor)); - tester.pump(editableText.cursorBlinkInterval); + await tester.pump(editableText.cursorBlinkInterval); expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor)); } - checkCursorToggle(); + await checkCursorToggle(); // Try the test again with a nonempty EditableText. mockKeyboard.client.updateEditingState(new mojom.EditingState() ..text = 'X' ..selectionBase = 1 ..selectionExtent = 1); - checkCursorToggle(); + await checkCursorToggle(); }); - testWidgets('hideText control test', (WidgetTester tester) { + testWidgets('hideText control test', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); Widget builder() { @@ -155,7 +154,7 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); const String testValue = 'ABC'; mockKeyboard.client.updateEditingState(new mojom.EditingState() @@ -163,7 +162,7 @@ void main() { ..selectionBase = testValue.length ..selectionExtent = testValue.length); - tester.pump(); + await tester.pump(); }); // Returns the first RenderEditableLine. @@ -192,7 +191,7 @@ void main() { return endpoints[0].point; } - testWidgets('Can long press to select', (WidgetTester tester) { + testWidgets('Can long press to select', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); InputValue inputValue = InputValue.empty; @@ -216,29 +215,29 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); String testValue = 'abc def ghi'; enterText(testValue); expect(inputValue.text, testValue); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); expect(inputValue.selection.isCollapsed, true); // Long press the 'e' to select 'def'. Point ePos = textOffsetToPosition(tester, testValue.indexOf('e')); - TestGesture gesture = tester.startGesture(ePos, pointer: 7); - tester.pump(const Duration(seconds: 2)); - gesture.up(); - tester.pump(); + TestGesture gesture = await tester.startGesture(ePos, pointer: 7); + await tester.pump(const Duration(seconds: 2)); + await gesture.up(); + await tester.pump(); // 'def' is selected. expect(inputValue.selection.baseOffset, testValue.indexOf('d')); expect(inputValue.selection.extentOffset, testValue.indexOf('f')+1); }); - testWidgets('Can drag handles to change selection', (WidgetTester tester) { + testWidgets('Can drag handles to change selection', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); InputValue inputValue = InputValue.empty; @@ -262,19 +261,19 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); String testValue = 'abc def ghi'; enterText(testValue); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // Long press the 'e' to select 'def'. Point ePos = textOffsetToPosition(tester, testValue.indexOf('e')); - TestGesture gesture = tester.startGesture(ePos, pointer: 7); - tester.pump(const Duration(seconds: 2)); - gesture.up(); - tester.pump(); + TestGesture gesture = await tester.startGesture(ePos, pointer: 7); + await tester.pump(const Duration(seconds: 2)); + await gesture.up(); + await tester.pump(); TextSelection selection = inputValue.selection; @@ -288,12 +287,12 @@ void main() { // of the handle. Point handlePos = endpoints[1].point + new Offset(1.0, 1.0); Point newHandlePos = textOffsetToPosition(tester, selection.extentOffset+2); - gesture = tester.startGesture(handlePos, pointer: 7); - tester.pump(); - gesture.moveTo(newHandlePos); - tester.pump(); - gesture.up(); - tester.pump(); + gesture = await tester.startGesture(handlePos, pointer: 7); + await tester.pump(); + await gesture.moveTo(newHandlePos); + await tester.pump(); + await gesture.up(); + await tester.pump(); expect(inputValue.selection.baseOffset, selection.baseOffset); expect(inputValue.selection.extentOffset, selection.extentOffset+2); @@ -301,18 +300,18 @@ void main() { // Drag the left handle 2 letters to the left. handlePos = endpoints[0].point + new Offset(-1.0, 1.0); newHandlePos = textOffsetToPosition(tester, selection.baseOffset-2); - gesture = tester.startGesture(handlePos, pointer: 7); - tester.pump(); - gesture.moveTo(newHandlePos); - tester.pump(); - gesture.up(); - tester.pumpWidget(builder()); + gesture = await tester.startGesture(handlePos, pointer: 7); + await tester.pump(); + await gesture.moveTo(newHandlePos); + await tester.pump(); + await gesture.up(); + await tester.pumpWidget(builder()); expect(inputValue.selection.baseOffset, selection.baseOffset-2); expect(inputValue.selection.extentOffset, selection.extentOffset+2); }); - testWidgets('Can use selection toolbar', (WidgetTester tester) { + testWidgets('Can use selection toolbar', (WidgetTester tester) async { GlobalKey inputKey = new GlobalKey(); InputValue inputValue = InputValue.empty; @@ -336,43 +335,43 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); String testValue = 'abc def ghi'; enterText(testValue); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // Tap the selection handle to bring up the "paste / select all" menu. - tester.tapAt(textOffsetToPosition(tester, testValue.indexOf('e'))); - tester.pumpWidget(builder()); + await tester.tapAt(textOffsetToPosition(tester, testValue.indexOf('e'))); + await tester.pumpWidget(builder()); RenderEditableLine renderLine = findRenderEditableLine(tester); List endpoints = renderLine.getEndpointsForSelection( inputValue.selection); - tester.tapAt(endpoints[0].point + new Offset(1.0, 1.0)); - tester.pumpWidget(builder()); + await tester.tapAt(endpoints[0].point + new Offset(1.0, 1.0)); + await tester.pumpWidget(builder()); // SELECT ALL should select all the text. - tester.tap(find.text('SELECT ALL')); - tester.pumpWidget(builder()); + await tester.tap(find.text('SELECT ALL')); + await tester.pumpWidget(builder()); expect(inputValue.selection.baseOffset, 0); expect(inputValue.selection.extentOffset, testValue.length); // COPY should reset the selection. - tester.tap(find.text('COPY')); - tester.pumpWidget(builder()); + await tester.tap(find.text('COPY')); + await tester.pumpWidget(builder()); expect(inputValue.selection.isCollapsed, true); // Tap again to bring back the menu. - tester.tapAt(textOffsetToPosition(tester, testValue.indexOf('e'))); - tester.pumpWidget(builder()); + await tester.tapAt(textOffsetToPosition(tester, testValue.indexOf('e'))); + await tester.pumpWidget(builder()); renderLine = findRenderEditableLine(tester); endpoints = renderLine.getEndpointsForSelection(inputValue.selection); - tester.tapAt(endpoints[0].point + new Offset(1.0, 1.0)); - tester.pumpWidget(builder()); + await tester.tapAt(endpoints[0].point + new Offset(1.0, 1.0)); + await tester.pumpWidget(builder()); // PASTE right before the 'e'. - tester.tap(find.text('PASTE')); - tester.pumpWidget(builder()); + await tester.tap(find.text('PASTE')); + await tester.pumpWidget(builder()); expect(inputValue.text, 'abc d${testValue}ef ghi'); }); } diff --git a/packages/flutter/test/widget/layout_builder_test.dart b/packages/flutter/test/widget/layout_builder_test.dart index 300b9c4cb8..01042bbfb6 100644 --- a/packages/flutter/test/widget/layout_builder_test.dart +++ b/packages/flutter/test/widget/layout_builder_test.dart @@ -5,14 +5,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('LayoutBuilder parent size', (WidgetTester tester) { + testWidgets('LayoutBuilder parent size', (WidgetTester tester) async { Size layoutBuilderSize; Key childKey = new UniqueKey(); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new SizedBox( width: 100.0, @@ -36,14 +35,14 @@ void main() { expect(box.size, equals(const Size(50.0, 100.0))); }); - testWidgets('LayoutBuilder stateful child', (WidgetTester tester) { + testWidgets('LayoutBuilder stateful child', (WidgetTester tester) async { Size layoutBuilderSize; StateSetter setState; Key childKey = new UniqueKey(); double childWidth = 10.0; double childHeight = 20.0; - tester.pumpWidget( + await tester.pumpWidget( new LayoutBuilder( builder: (BuildContext context, Size size) { layoutBuilderSize = size; @@ -69,19 +68,19 @@ void main() { childWidth = 100.0; childHeight = 200.0; }); - tester.pump(); + await tester.pump(); box = tester.renderObject(find.byKey(childKey)); expect(box.size, equals(const Size(100.0, 200.0))); }); - testWidgets('LayoutBuilder stateful parent', (WidgetTester tester) { + testWidgets('LayoutBuilder stateful parent', (WidgetTester tester) async { Size layoutBuilderSize; StateSetter setState; Key childKey = new UniqueKey(); double childWidth = 10.0; double childHeight = 20.0; - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new StatefulBuilder( builder: (BuildContext context, StateSetter setter) { @@ -113,7 +112,7 @@ void main() { childWidth = 100.0; childHeight = 200.0; }); - tester.pump(); + await tester.pump(); box = tester.renderObject(find.byKey(childKey)); expect(box.size, equals(const Size(100.0, 200.0))); }); diff --git a/packages/flutter/test/widget/lazy_block_test.dart b/packages/flutter/test/widget/lazy_block_test.dart index fc79b5cb61..5d87e150c3 100644 --- a/packages/flutter/test/widget/lazy_block_test.dart +++ b/packages/flutter/test/widget/lazy_block_test.dart @@ -6,8 +6,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; void main() { - testWidgets('Block inside LazyBlock', (WidgetTester tester) { - tester.pumpWidget(new LazyBlock( + testWidgets('Block inside LazyBlock', (WidgetTester tester) async { + await tester.pumpWidget(new LazyBlock( delegate: new LazyBlockChildren( children: [ new Block( diff --git a/packages/flutter/test/widget/lazy_block_viewport_test.dart b/packages/flutter/test/widget/lazy_block_viewport_test.dart index 22576fc8e9..aefd7c027b 100644 --- a/packages/flutter/test/widget/lazy_block_viewport_test.dart +++ b/packages/flutter/test/widget/lazy_block_viewport_test.dart @@ -5,12 +5,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -import 'package:test/test.dart'; import 'test_widgets.dart'; void main() { - testWidgets('LazyBlockViewport mount/dismount smoke test', (WidgetTester tester) { + testWidgets('LazyBlockViewport mount/dismount smoke test', (WidgetTester tester) async { List callbackTracker = []; // the root view is 800x600 in the test environment @@ -33,7 +32,7 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); FlipWidgetState testWidget = tester.state(find.byType(FlipWidget)); @@ -41,18 +40,18 @@ void main() { callbackTracker.clear(); testWidget.flip(); - tester.pump(); + await tester.pump(); expect(callbackTracker, equals([])); callbackTracker.clear(); testWidget.flip(); - tester.pump(); + await tester.pump(); expect(callbackTracker, equals([0, 1, 2, 3, 4, 5])); }); - testWidgets('LazyBlockViewport vertical', (WidgetTester tester) { + testWidgets('LazyBlockViewport vertical', (WidgetTester tester) async { List callbackTracker = []; // the root view is 800x600 in the test environment @@ -81,7 +80,7 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // 0 is built to find its height expect(callbackTracker, equals([0, 1, 2, 3, 4])); @@ -89,20 +88,20 @@ void main() { offset = 400.0; // now only 3 should fit, numbered 2-4. - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // We build all the children to find their new size. expect(callbackTracker, equals([0, 1, 2, 3, 4])); callbackTracker.clear(); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // 0 isn't built because they're not visible. expect(callbackTracker, equals([1, 2, 3, 4])); callbackTracker.clear(); }); - testWidgets('LazyBlockViewport horizontal', (WidgetTester tester) { + testWidgets('LazyBlockViewport horizontal', (WidgetTester tester) async { List callbackTracker = []; // the root view is 800x600 in the test environment @@ -132,7 +131,7 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // 0 is built to find its width expect(callbackTracker, equals([0, 1, 2, 3, 4, 5])); @@ -141,20 +140,20 @@ void main() { offset = 400.0; // now only 4 should fit, numbered 2-5. - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // We build all the children to find their new size. expect(callbackTracker, equals([0, 1, 2, 3, 4, 5])); callbackTracker.clear(); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); // 0 isn't built because they're not visible. expect(callbackTracker, equals([1, 2, 3, 4, 5])); callbackTracker.clear(); }); - testWidgets('LazyBlockViewport reinvoke builders', (WidgetTester tester) { + testWidgets('LazyBlockViewport reinvoke builders', (WidgetTester tester) async { List callbackTracker = []; List text = []; @@ -180,24 +179,24 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); expect(callbackTracker, equals([0, 1, 2])); callbackTracker.clear(); - tester.allWidgets.forEach(collectText); + await tester.allWidgets.forEach(collectText); expect(text, equals(['0', '1', '2'])); text.clear(); - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); expect(callbackTracker, equals([0, 1, 2])); callbackTracker.clear(); - tester.allWidgets.forEach(collectText); + await tester.allWidgets.forEach(collectText); expect(text, equals(['0', '1', '2'])); text.clear(); }); - testWidgets('LazyBlockViewport reinvoke builders', (WidgetTester tester) { + testWidgets('LazyBlockViewport reinvoke builders', (WidgetTester tester) async { StateSetter setState; ThemeData themeData = new ThemeData.light(); @@ -217,7 +216,7 @@ void main() { delegate: new LazyBlockBuilder(builder: itemBuilder) ); - tester.pumpWidget( + await tester.pumpWidget( new StatefulBuilder( builder: (BuildContext context, StateSetter setter) { setState = setter; @@ -234,14 +233,14 @@ void main() { themeData = new ThemeData(primarySwatch: Colors.green); }); - tester.pump(); + await tester.pump(); widget = tester.firstWidget(find.byType(DecoratedBox)); decoraton = widget.decoration; expect(decoraton.backgroundColor, equals(Colors.green[500])); }); - testWidgets('LazyBlockViewport padding', (WidgetTester tester) { + testWidgets('LazyBlockViewport padding', (WidgetTester tester) async { IndexedWidgetBuilder itemBuilder = (BuildContext context, int i) { return new Container( key: new ValueKey(i), @@ -254,7 +253,7 @@ void main() { ); }; - tester.pumpWidget( + await tester.pumpWidget( new LazyBlockViewport( padding: new EdgeInsets.fromLTRB(7.0, 3.0, 5.0, 11.0), delegate: new LazyBlockBuilder(builder: itemBuilder) @@ -267,7 +266,7 @@ void main() { expect(firstBox.size.width, equals(800.0 - 12.0)); }); - testWidgets('Underflow extents', (WidgetTester tester) { + testWidgets('Underflow extents', (WidgetTester tester) async { double lastContentExtent; double lastContainerExtent; double lastMinScrollOffset; @@ -277,7 +276,7 @@ void main() { lastMinScrollOffset = minScrollOffset; } - tester.pumpWidget(new LazyBlockViewport( + await tester.pumpWidget(new LazyBlockViewport( onExtentsChanged: handleExtendsChanged, delegate: new LazyBlockChildren( children: [ diff --git a/packages/flutter/test/widget/listener_test.dart b/packages/flutter/test/widget/listener_test.dart index 64784e47b0..cc1cc930da 100644 --- a/packages/flutter/test/widget/listener_test.dart +++ b/packages/flutter/test/widget/listener_test.dart @@ -4,13 +4,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Events bubble up the tree', (WidgetTester tester) { + testWidgets('Events bubble up the tree', (WidgetTester tester) async { List log = new List(); - tester.pumpWidget( + await tester.pumpWidget( new Listener( onPointerDown: (_) { log.add('top'); @@ -32,7 +31,7 @@ void main() { ) ); - tester.tap(find.text('X')); + await tester.tap(find.text('X')); expect(log, equals([ 'bottom', diff --git a/packages/flutter/test/widget/media_query_test.dart b/packages/flutter/test/widget/media_query_test.dart index d230572cb8..16bd426da5 100644 --- a/packages/flutter/test/widget/media_query_test.dart +++ b/packages/flutter/test/widget/media_query_test.dart @@ -6,13 +6,12 @@ import 'dart:ui' as ui; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('MediaQuery has a default', (WidgetTester tester) { + testWidgets('MediaQuery has a default', (WidgetTester tester) async { Size size; - tester.pumpWidget( + await tester.pumpWidget( new Builder( builder: (BuildContext context) { size = MediaQuery.of(context).size; diff --git a/packages/flutter/test/widget/modal_barrier_test.dart b/packages/flutter/test/widget/modal_barrier_test.dart index 9924236282..652d408915 100644 --- a/packages/flutter/test/widget/modal_barrier_test.dart +++ b/packages/flutter/test/widget/modal_barrier_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { bool tapped; @@ -25,7 +24,7 @@ void main() { ); }); - testWidgets('ModalBarrier prevents interactions with widgets behind it', (WidgetTester tester) { + testWidgets('ModalBarrier prevents interactions with widgets behind it', (WidgetTester tester) async { Widget subject = new Stack( children: [ tapTarget, @@ -33,14 +32,14 @@ void main() { ] ); - tester.pumpWidget(subject); - tester.tap(find.text('target')); - tester.pumpWidget(subject); + await tester.pumpWidget(subject); + await tester.tap(find.text('target')); + await tester.pumpWidget(subject); expect(tapped, isFalse, reason: 'because the tap is prevented by ModalBarrier'); }); - testWidgets('ModalBarrier does not prevent interactions with widgets in front of it', (WidgetTester tester) { + testWidgets('ModalBarrier does not prevent interactions with widgets in front of it', (WidgetTester tester) async { Widget subject = new Stack( children: [ new ModalBarrier(dismissable: false), @@ -48,33 +47,33 @@ void main() { ] ); - tester.pumpWidget(subject); - tester.tap(find.text('target')); - tester.pumpWidget(subject); + await tester.pumpWidget(subject); + await tester.tap(find.text('target')); + await tester.pumpWidget(subject); expect(tapped, isTrue, reason: 'because the tap is not prevented by ModalBarrier'); }); - testWidgets('ModalBarrier pops the Navigator when dismissed', (WidgetTester tester) { + testWidgets('ModalBarrier pops the Navigator when dismissed', (WidgetTester tester) async { final Map routes = { '/': (BuildContext context) => new FirstWidget(), '/modal': (BuildContext context) => new SecondWidget(), }; - tester.pumpWidget(new MaterialApp(routes: routes)); + await tester.pumpWidget(new MaterialApp(routes: routes)); // Initially the barrier is not visible expect(find.byKey(const ValueKey('barrier')), findsNothing); // Tapping on X routes to the barrier - tester.tap(find.text('X')); - tester.pump(); // begin transition - tester.pump(const Duration(seconds: 1)); // end transition + await tester.tap(find.text('X')); + await tester.pump(); // begin transition + await tester.pump(const Duration(seconds: 1)); // end transition // Tap on the barrier to dismiss it - tester.tap(find.byKey(const ValueKey('barrier'))); - tester.pump(); // begin transition - tester.pump(const Duration(seconds: 1)); // end transition + await tester.tap(find.byKey(const ValueKey('barrier'))); + await tester.pump(); // begin transition + await tester.pump(const Duration(seconds: 1)); // end transition expect(find.byKey(const ValueKey('barrier')), findsNothing, reason: 'because the barrier was dismissed'); diff --git a/packages/flutter/test/widget/multichild_test.dart b/packages/flutter/test/widget/multichild_test.dart index 717b439cf5..9fb992a770 100644 --- a/packages/flutter/test/widget/multichild_test.dart +++ b/packages/flutter/test/widget/multichild_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; import 'test_widgets.dart'; @@ -33,9 +32,9 @@ void checkTree(WidgetTester tester, List expectedDecorations) { } void main() { - testWidgets('MultiChildRenderObjectElement control test', (WidgetTester tester) { + testWidgets('MultiChildRenderObjectElement control test', (WidgetTester tester) async { - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationA), @@ -47,7 +46,7 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationA), @@ -58,7 +57,7 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationA), @@ -70,7 +69,7 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(key: new Key('b'), decoration: kBoxDecorationB), @@ -82,7 +81,7 @@ void main() { checkTree(tester, [kBoxDecorationB, kBoxDecorationC, kBoxDecorationA]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(key: new Key('a'), decoration: kBoxDecorationA), @@ -94,7 +93,7 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationC, kBoxDecorationB]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationC), @@ -104,7 +103,7 @@ void main() { checkTree(tester, [kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack() ); @@ -112,9 +111,9 @@ void main() { }); - testWidgets('MultiChildRenderObjectElement with stateless widgets', (WidgetTester tester) { + testWidgets('MultiChildRenderObjectElement with stateless widgets', (WidgetTester tester) async { - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationA), @@ -126,7 +125,7 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationA), @@ -140,7 +139,7 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationA), @@ -156,7 +155,7 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Container( @@ -174,7 +173,7 @@ void main() { checkTree(tester, [kBoxDecorationB, kBoxDecorationA, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Container( @@ -190,7 +189,7 @@ void main() { checkTree(tester, [kBoxDecorationB, kBoxDecorationA, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Container( @@ -207,7 +206,7 @@ void main() { checkTree(tester, [kBoxDecorationB, kBoxDecorationA]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Container( @@ -224,15 +223,15 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationB]); - tester.pumpWidget( + await tester.pumpWidget( new Stack() ); checkTree(tester, []); }); - testWidgets('MultiChildRenderObjectElement with stateful widgets', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('MultiChildRenderObjectElement with stateful widgets', (WidgetTester tester) async { + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationA), @@ -243,7 +242,7 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationB]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new FlipWidget( @@ -258,11 +257,11 @@ void main() { checkTree(tester, [kBoxDecorationA, kBoxDecorationC]); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); checkTree(tester, [kBoxDecorationB, kBoxDecorationC]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new FlipWidget( @@ -276,11 +275,11 @@ void main() { checkTree(tester, [kBoxDecorationB]); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); checkTree(tester, [kBoxDecorationA]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new FlipWidget( @@ -292,7 +291,7 @@ void main() { ) ); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(key: new Key('c'), decoration: kBoxDecorationC), @@ -308,11 +307,11 @@ void main() { checkTree(tester, [kBoxDecorationC, kBoxDecorationA]); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); checkTree(tester, [kBoxDecorationC, kBoxDecorationB]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new FlipWidget( diff --git a/packages/flutter/test/widget/navigator_test.dart b/packages/flutter/test/widget/navigator_test.dart index dcdc95466b..c068a094ff 100644 --- a/packages/flutter/test/widget/navigator_test.dart +++ b/packages/flutter/test/widget/navigator_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; class FirstWidget extends StatelessWidget { @override @@ -68,38 +67,38 @@ class ThirdWidget extends StatelessWidget { } void main() { - testWidgets('Can navigator navigate to and from a stateful widget', (WidgetTester tester) { + testWidgets('Can navigator navigate to and from a stateful widget', (WidgetTester tester) async { final Map routes = { '/': (BuildContext context) => new FirstWidget(), '/second': (BuildContext context) => new SecondWidget(), }; - tester.pumpWidget(new MaterialApp(routes: routes)); + await tester.pumpWidget(new MaterialApp(routes: routes)); expect(find.text('X'), findsOneWidget); expect(find.text('Y'), findsNothing); - tester.tap(find.text('X')); - tester.pump(const Duration(milliseconds: 10)); + await tester.tap(find.text('X')); + await tester.pump(const Duration(milliseconds: 10)); expect(find.text('X'), findsOneWidget); expect(find.text('Y'), findsOneWidget); - tester.pump(const Duration(milliseconds: 10)); - tester.pump(const Duration(milliseconds: 10)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(milliseconds: 10)); + await tester.pump(const Duration(milliseconds: 10)); + await tester.pump(const Duration(seconds: 1)); - tester.tap(find.text('Y')); - tester.pump(const Duration(milliseconds: 10)); - tester.pump(const Duration(milliseconds: 10)); - tester.pump(const Duration(milliseconds: 10)); - tester.pump(const Duration(seconds: 1)); + await tester.tap(find.text('Y')); + await tester.pump(const Duration(milliseconds: 10)); + await tester.pump(const Duration(milliseconds: 10)); + await tester.pump(const Duration(milliseconds: 10)); + await tester.pump(const Duration(seconds: 1)); expect(find.text('X'), findsOneWidget); expect(find.text('Y'), findsNothing); }); - testWidgets('Navigator.openTransaction fails gracefully when not found in context', (WidgetTester tester) { + testWidgets('Navigator.openTransaction fails gracefully when not found in context', (WidgetTester tester) async { Key targetKey = new Key('foo'); dynamic exception; Widget widget = new ThirdWidget( @@ -108,8 +107,8 @@ void main() { exception = e; } ); - tester.pumpWidget(widget); - tester.tap(find.byKey(targetKey)); + await tester.pumpWidget(widget); + await tester.tap(find.byKey(targetKey)); expect(exception, new isInstanceOf()); expect('$exception', startsWith('openTransaction called with a context')); }); diff --git a/packages/flutter/test/widget/overflow_box_test.dart b/packages/flutter/test/widget/overflow_box_test.dart index a75024c273..60e890aeb1 100644 --- a/packages/flutter/test/widget/overflow_box_test.dart +++ b/packages/flutter/test/widget/overflow_box_test.dart @@ -5,12 +5,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('OverflowBox control test', (WidgetTester tester) { + testWidgets('OverflowBox control test', (WidgetTester tester) async { GlobalKey inner = new GlobalKey(); - tester.pumpWidget(new Align( + await tester.pumpWidget(new Align( alignment: const FractionalOffset(1.0, 1.0), child: new SizedBox( width: 10.0, @@ -31,7 +30,7 @@ void main() { expect(box.size, equals(const Size(100.0, 50.0))); }); - testWidgets('OverflowBox implements debugFillDescription', (WidgetTester tester) { + testWidgets('OverflowBox implements debugFillDescription', (WidgetTester tester) async { List description = []; new OverflowBox( minWidth: 1.0, diff --git a/packages/flutter/test/widget/page_forward_transitions_test.dart b/packages/flutter/test/widget/page_forward_transitions_test.dart index ddbcce2be3..069cc6282b 100644 --- a/packages/flutter/test/widget/page_forward_transitions_test.dart +++ b/packages/flutter/test/widget/page_forward_transitions_test.dart @@ -2,9 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_test/flutter_test.dart' hide TypeMatcher; import 'package:flutter/material.dart'; -import 'package:test/test.dart' hide TypeMatcher; class TestTransition extends AnimatedWidget { TestTransition({ @@ -47,7 +46,7 @@ void main() { final Duration kTwoTenthsOfTheTransitionDuration = const Duration(milliseconds: 30); final Duration kFourTenthsOfTheTransitionDuration = const Duration(milliseconds: 60); - testWidgets('Check onstage/offstage handling around transitions', (WidgetTester tester) { + testWidgets('Check onstage/offstage handling around transitions', (WidgetTester tester) async { GlobalKey insideKey = new GlobalKey(); @@ -70,7 +69,7 @@ void main() { return result; } - tester.pumpWidget( + await tester.pumpWidget( new MaterialApp( onGenerateRoute: (RouteSettings settings) { switch (settings.name) { @@ -112,61 +111,61 @@ void main() { navigator.openTransaction((NavigatorTransaction transaction) => transaction.pushNamed('/2')); expect(state(), equals('BC')); // transition 1->2 is not yet built - tester.pump(); + await tester.pump(); expect(state(), equals('BCE')); // transition 1->2 is at 0.0 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('BCE')); // transition 1->2 is at 0.4 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('BDE')); // transition 1->2 is at 0.8 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('E')); // transition 1->2 is at 1.0 navigator.openTransaction((NavigatorTransaction transaction) => transaction.pop()); expect(state(), equals('E')); // transition 1<-2 is at 1.0, just reversed - tester.pump(); + await tester.pump(); expect(state(), equals('BDE')); // transition 1<-2 is at 1.0 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('BDE')); // transition 1<-2 is at 0.6 navigator.openTransaction((NavigatorTransaction transaction) => transaction.pushNamed('/3')); expect(state(), equals('BDE')); // transition 1<-2 is at 0.6 - tester.pump(); + await tester.pump(); expect(state(), equals('BDEF')); // transition 1<-2 is at 0.6, 1->3 is at 0.0 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('BCEF')); // transition 1<-2 is at 0.2, 1->3 is at 0.4 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('BDF')); // transition 1<-2 is done, 1->3 is at 0.8 navigator.openTransaction((NavigatorTransaction transaction) => transaction.pop()); expect(state(), equals('BDF')); // transition 1<-3 is at 0.8, just reversed - tester.pump(); + await tester.pump(); expect(state(), equals('BDF')); // transition 1<-3 is at 0.8 - tester.pump(kTwoTenthsOfTheTransitionDuration); // notice that dT=0.2 here, not 0.4 + await tester.pump(kTwoTenthsOfTheTransitionDuration); // notice that dT=0.2 here, not 0.4 expect(state(), equals('BDF')); // transition 1<-3 is at 0.6 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('BCF')); // transition 1<-3 is at 0.2 navigator.openTransaction((NavigatorTransaction transaction) => transaction.pushNamed('/4')); expect(state(), equals('BCF')); // transition 1<-3 is at 0.2, 1->4 is not yet built - tester.pump(); + await tester.pump(); expect(state(), equals('BCFG')); // transition 1<-3 is at 0.2, 1->4 is at 0.0 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('BCG')); // transition 1<-3 is done, 1->4 is at 0.4 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('BDG')); // transition 1->4 is at 0.8 - tester.pump(kFourTenthsOfTheTransitionDuration); + await tester.pump(kFourTenthsOfTheTransitionDuration); expect(state(), equals('G')); // transition 1->4 is done }); diff --git a/packages/flutter/test/widget/page_transitions_test.dart b/packages/flutter/test/widget/page_transitions_test.dart index 3f2b1d6cbb..9e16b9596d 100644 --- a/packages/flutter/test/widget/page_transitions_test.dart +++ b/packages/flutter/test/widget/page_transitions_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; class TestOverlayRoute extends OverlayRoute { @override @@ -13,7 +12,7 @@ class TestOverlayRoute extends OverlayRoute { } void main() { - testWidgets('Check onstage/offstage handling around transitions', (WidgetTester tester) { + testWidgets('Check onstage/offstage handling around transitions', (WidgetTester tester) async { GlobalKey containerKey1 = new GlobalKey(); GlobalKey containerKey2 = new GlobalKey(); final Map routes = { @@ -21,7 +20,7 @@ void main() { '/settings': (_) => new Container(key: containerKey2, child: new Text('Settings')), }; - tester.pumpWidget(new MaterialApp(routes: routes)); + await tester.pumpWidget(new MaterialApp(routes: routes)); expect(find.text('Home'), isOnStage); expect(find.text('Settings'), findsNothing); @@ -31,19 +30,19 @@ void main() { Navigator.pushNamed(containerKey1.currentContext, '/settings'); expect(Navigator.canPop(containerKey1.currentContext), isTrue); - tester.pump(); + await tester.pump(); expect(find.text('Home'), isOnStage); expect(find.text('Settings'), isOffStage); expect(find.text('Overlay'), findsNothing); - tester.pump(const Duration(milliseconds: 16)); + await tester.pump(const Duration(milliseconds: 16)); expect(find.text('Home'), isOnStage); expect(find.text('Settings'), isOnStage); expect(find.text('Overlay'), findsNothing); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(find.text('Home'), findsNothing); expect(find.text('Settings'), isOnStage); @@ -51,13 +50,13 @@ void main() { Navigator.push(containerKey2.currentContext, new TestOverlayRoute()); - tester.pump(); + await tester.pump(); expect(find.text('Home'), findsNothing); expect(find.text('Settings'), isOnStage); expect(find.text('Overlay'), isOnStage); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(find.text('Home'), findsNothing); expect(find.text('Settings'), isOnStage); @@ -65,13 +64,13 @@ void main() { expect(Navigator.canPop(containerKey2.currentContext), isTrue); Navigator.pop(containerKey2.currentContext); - tester.pump(); + await tester.pump(); expect(find.text('Home'), findsNothing); expect(find.text('Settings'), isOnStage); expect(find.text('Overlay'), findsNothing); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(find.text('Home'), findsNothing); expect(find.text('Settings'), isOnStage); @@ -79,13 +78,13 @@ void main() { expect(Navigator.canPop(containerKey2.currentContext), isTrue); Navigator.pop(containerKey2.currentContext); - tester.pump(); + await tester.pump(); expect(find.text('Home'), isOnStage); expect(find.text('Settings'), isOnStage); expect(find.text('Overlay'), findsNothing); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(find.text('Home'), isOnStage); expect(find.text('Settings'), findsNothing); diff --git a/packages/flutter/test/widget/pageable_list_test.dart b/packages/flutter/test/widget/pageable_list_test.dart index 1d80590892..b96ed6c18d 100644 --- a/packages/flutter/test/widget/pageable_list_test.dart +++ b/packages/flutter/test/widget/pageable_list_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; Size pageSize = new Size(600.0, 300.0); const List defaultPages = const [0, 1, 2, 3, 4, 5]; @@ -42,28 +41,30 @@ Widget buildFrame({ ); } -void page(WidgetTester tester, Offset offset) { - String itemText = currentPage != null ? currentPage.toString() : '0'; - tester.scroll(find.text(itemText), offset); - // One frame to start the animation, a second to complete it. - tester.pump(); - tester.pump(const Duration(seconds: 1)); +Future page(WidgetTester tester, Offset offset) { + return TestAsyncUtils.guard(() async { + String itemText = currentPage != null ? currentPage.toString() : '0'; + await tester.scroll(find.text(itemText), offset); + // One frame to start the animation, a second to complete it. + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); + }); } -void pageLeft(WidgetTester tester) { - page(tester, new Offset(-pageSize.width, 0.0)); +Future pageLeft(WidgetTester tester) { + return page(tester, new Offset(-pageSize.width, 0.0)); } -void pageRight(WidgetTester tester) { - page(tester, new Offset(pageSize.width, 0.0)); +Future pageRight(WidgetTester tester) { + return page(tester, new Offset(pageSize.width, 0.0)); } void main() { - testWidgets('PageableList with itemsWrap: false', (WidgetTester tester) { + testWidgets('PageableList with itemsWrap: false', (WidgetTester tester) async { currentPage = null; - tester.pumpWidget(buildFrame()); + await tester.pumpWidget(buildFrame()); expect(currentPage, isNull); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(1)); expect(find.text('0'), findsNothing); @@ -73,7 +74,7 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(0)); expect(find.text('0'), findsOneWidget); @@ -83,14 +84,14 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(0)); }); - testWidgets('PageableList with end scroll anchor', (WidgetTester tester) { + testWidgets('PageableList with end scroll anchor', (WidgetTester tester) async { currentPage = 5; - tester.pumpWidget(buildFrame(scrollAnchor: ViewportAnchor.end)); - pageRight(tester); + await tester.pumpWidget(buildFrame(scrollAnchor: ViewportAnchor.end)); + await pageRight(tester); expect(currentPage, equals(4)); expect(find.text('0'), findsNothing); @@ -100,7 +101,7 @@ void main() { expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsNothing); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(5)); expect(find.text('0'), findsNothing); @@ -110,7 +111,7 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsOneWidget); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(5)); expect(find.text('0'), findsNothing); @@ -121,22 +122,22 @@ void main() { expect(find.text('5'), findsOneWidget); }); - testWidgets('PageableList with itemsWrap: true', (WidgetTester tester) { + testWidgets('PageableList with itemsWrap: true', (WidgetTester tester) async { currentPage = null; - tester.pumpWidget(buildFrame(itemsWrap: true)); + await tester.pumpWidget(buildFrame(itemsWrap: true)); expect(currentPage, isNull); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(1)); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(0)); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(5)); }); - testWidgets('PageableList with end and itemsWrap: true', (WidgetTester tester) { + testWidgets('PageableList with end and itemsWrap: true', (WidgetTester tester) async { currentPage = 5; - tester.pumpWidget(buildFrame(itemsWrap: true, scrollAnchor: ViewportAnchor.end)); - pageRight(tester); + await tester.pumpWidget(buildFrame(itemsWrap: true, scrollAnchor: ViewportAnchor.end)); + await pageRight(tester); expect(currentPage, equals(4)); expect(find.text('0'), findsNothing); @@ -146,7 +147,7 @@ void main() { expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsNothing); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(5)); expect(find.text('0'), findsNothing); @@ -156,7 +157,7 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsOneWidget); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(0)); expect(find.text('0'), findsOneWidget); @@ -166,7 +167,7 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(1)); expect(find.text('0'), findsNothing); @@ -177,43 +178,43 @@ void main() { expect(find.text('5'), findsNothing); }); - testWidgets('PageableList with two items', (WidgetTester tester) { + testWidgets('PageableList with two items', (WidgetTester tester) async { currentPage = null; - tester.pumpWidget(buildFrame(itemsWrap: true, pages: [0, 1])); + await tester.pumpWidget(buildFrame(itemsWrap: true, pages: [0, 1])); expect(currentPage, isNull); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(1)); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(0)); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(1)); }); - testWidgets('PageableList with one item', (WidgetTester tester) { + testWidgets('PageableList with one item', (WidgetTester tester) async { currentPage = null; - tester.pumpWidget(buildFrame(itemsWrap: true, pages: [0])); + await tester.pumpWidget(buildFrame(itemsWrap: true, pages: [0])); expect(currentPage, isNull); - pageLeft(tester); + await pageLeft(tester); expect(currentPage, equals(0)); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(0)); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(0)); }); - testWidgets('PageableList with no items', (WidgetTester tester) { + testWidgets('PageableList with no items', (WidgetTester tester) async { currentPage = null; - tester.pumpWidget(buildFrame(itemsWrap: true, pages: [])); + await tester.pumpWidget(buildFrame(itemsWrap: true, pages: [])); expect(currentPage, isNull); }); - testWidgets('PageableList resize parent', (WidgetTester tester) { - tester.pumpWidget(new Container()); + testWidgets('PageableList resize parent', (WidgetTester tester) async { + await tester.pumpWidget(new Container()); currentPage = null; - tester.pumpWidget(buildFrame(itemsWrap: true)); + await tester.pumpWidget(buildFrame(itemsWrap: true)); expect(currentPage, isNull); - pageRight(tester); + await pageRight(tester); expect(currentPage, equals(5)); RenderBox box = globalKeys[5].currentContext.findRenderObject(); @@ -221,7 +222,7 @@ void main() { expect(box.size.height, equals(pageSize.height)); pageSize = new Size(pageSize.height, pageSize.width); - tester.pumpWidget(buildFrame(itemsWrap: true)); + await tester.pumpWidget(buildFrame(itemsWrap: true)); expect(find.text('0'), findsNothing); expect(find.text('1'), findsNothing); diff --git a/packages/flutter/test/widget/parent_data_test.dart b/packages/flutter/test/widget/parent_data_test.dart index 8006ecfa57..f4dd693271 100644 --- a/packages/flutter/test/widget/parent_data_test.dart +++ b/packages/flutter/test/widget/parent_data_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; import 'test_widgets.dart'; @@ -49,9 +48,9 @@ void checkTree(WidgetTester tester, List expectedParentData) { final TestParentData kNonPositioned = new TestParentData(); void main() { - testWidgets('ParentDataWidget control test', (WidgetTester tester) { + testWidgets('ParentDataWidget control test', (WidgetTester tester) async { - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new DecoratedBox(decoration: kBoxDecorationA), @@ -71,7 +70,7 @@ void main() { kNonPositioned, ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -99,7 +98,7 @@ void main() { DecoratedBox kDecoratedBoxB = new DecoratedBox(decoration: kBoxDecorationB); DecoratedBox kDecoratedBoxC = new DecoratedBox(decoration: kBoxDecorationC); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -123,7 +122,7 @@ void main() { kNonPositioned, ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -147,7 +146,7 @@ void main() { kNonPositioned, ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ kDecoratedBoxA, @@ -167,7 +166,7 @@ void main() { kNonPositioned, ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ kDecoratedBoxA, @@ -191,7 +190,7 @@ void main() { new TestParentData(top: 8.0), ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -207,13 +206,13 @@ void main() { ]); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); checkTree(tester, [ new TestParentData(right: 10.0), ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -229,21 +228,21 @@ void main() { ]); flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); checkTree(tester, [ new TestParentData(top: 7.0), ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack() ); checkTree(tester, []); }); - testWidgets('ParentDataWidget conflicting data', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('ParentDataWidget conflicting data', (WidgetTester tester) async { + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -260,11 +259,11 @@ void main() { ); expect(tester.takeException(), isNotNull); - tester.pumpWidget(new Stack()); + await tester.pumpWidget(new Stack()); checkTree(tester, []); - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new Flex( children: [ @@ -279,17 +278,17 @@ void main() { ); expect(tester.takeException(), isNotNull); - tester.pumpWidget( + await tester.pumpWidget( new Stack() ); checkTree(tester, []); }); - testWidgets('ParentDataWidget interacts with global keys', (WidgetTester tester) { + testWidgets('ParentDataWidget interacts with global keys', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -305,7 +304,7 @@ void main() { new TestParentData(top: 10.0, left: 10.0), ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -324,7 +323,7 @@ void main() { new TestParentData(top: 10.0, left: 10.0), ]); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( diff --git a/packages/flutter/test/widget/positioned_test.dart b/packages/flutter/test/widget/positioned_test.dart index f77c2574f2..311e673b9e 100644 --- a/packages/flutter/test/widget/positioned_test.dart +++ b/packages/flutter/test/widget/positioned_test.dart @@ -5,11 +5,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Can animate position data', (WidgetTester tester) { + testWidgets('Can animate position data', (WidgetTester tester) async { final RelativeRectTween rect = new RelativeRectTween( begin: new RelativeRect.fromRect( @@ -35,7 +34,7 @@ void main() { positions.add(boxParentData.offset); } - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new Container( height: 100.0, @@ -55,15 +54,15 @@ void main() { ); // t=0 recordMetrics(); controller.forward(); - tester.pump(); // t=0 again + await tester.pump(); // t=0 again recordMetrics(); - tester.pump(const Duration(seconds: 1)); // t=1 + await tester.pump(const Duration(seconds: 1)); // t=1 recordMetrics(); - tester.pump(const Duration(seconds: 1)); // t=2 + await tester.pump(const Duration(seconds: 1)); // t=2 recordMetrics(); - tester.pump(const Duration(seconds: 3)); // t=5 + await tester.pump(const Duration(seconds: 3)); // t=5 recordMetrics(); - tester.pump(const Duration(seconds: 5)); // t=10 + await tester.pump(const Duration(seconds: 5)); // t=10 recordMetrics(); expect(sizes, equals([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)])); diff --git a/packages/flutter/test/widget/raw_keyboard_listener_test.dart b/packages/flutter/test/widget/raw_keyboard_listener_test.dart index b40b8c0d1d..92a58c95f0 100644 --- a/packages/flutter/test/widget/raw_keyboard_listener_test.dart +++ b/packages/flutter/test/widget/raw_keyboard_listener_test.dart @@ -6,8 +6,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; void main() { - testWidgets('Can dispose without keyboard', (WidgetTester tester) { - tester.pumpWidget(new RawKeyboardListener(child: new Container())); - tester.pumpWidget(new Container()); + testWidgets('Can dispose without keyboard', (WidgetTester tester) async { + await tester.pumpWidget(new RawKeyboardListener(child: new Container())); + await tester.pumpWidget(new Container()); }); } diff --git a/packages/flutter/test/widget/remember_scroll_position_test.dart b/packages/flutter/test/widget/remember_scroll_position_test.dart index cb94bef514..93c2c26518 100644 --- a/packages/flutter/test/widget/remember_scroll_position_test.dart +++ b/packages/flutter/test/widget/remember_scroll_position_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; class ThePositiveNumbers extends StatelessWidget { @override @@ -22,9 +21,9 @@ class ThePositiveNumbers extends StatelessWidget { } void main() { - testWidgets('whether we remember our scroll position', (WidgetTester tester) { + testWidgets('whether we remember our scroll position', (WidgetTester tester) async { GlobalKey navigatorKey = new GlobalKey(); - tester.pumpWidget(new Navigator( + await tester.pumpWidget(new Navigator( key: navigatorKey, onGenerateRoute: (RouteSettings settings) { if (settings.name == '/') @@ -49,7 +48,7 @@ void main() { ScrollableState targetState = tester.state(find.byType(ScrollableLazyList)); targetState.scrollTo(1000.0); - tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); // we're 600 pixels high, each item is 100 pixels high, scroll position is // 1000, so we should have exactly 6 items, 10..15. @@ -69,8 +68,8 @@ void main() { navigatorKey.currentState.openTransaction( (NavigatorTransaction transaction) => transaction.pushNamed('/second') ); - tester.pump(); // navigating always takes two frames - tester.pump(new Duration(seconds: 1)); + await tester.pump(); // navigating always takes two frames + await tester.pump(new Duration(seconds: 1)); // same as the first list again expect(find.text('0'), findsOneWidget); @@ -86,8 +85,8 @@ void main() { navigatorKey.currentState.openTransaction( (NavigatorTransaction transaction) => transaction.pop() ); - tester.pump(); // navigating always takes two frames - tester.pump(new Duration(seconds: 1)); + await tester.pump(); // navigating always takes two frames + await tester.pump(new Duration(seconds: 1)); // we're 600 pixels high, each item is 100 pixels high, scroll position is // 1000, so we should have exactly 6 items, 10..15. diff --git a/packages/flutter/test/widget/render_object_widget_test.dart b/packages/flutter/test/widget/render_object_widget_test.dart index a89dc07b63..a8228af630 100644 --- a/packages/flutter/test/widget/render_object_widget_test.dart +++ b/packages/flutter/test/widget/render_object_widget_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; final BoxDecoration kBoxDecorationA = new BoxDecoration(); final BoxDecoration kBoxDecorationB = new BoxDecoration(); @@ -42,8 +41,8 @@ class TestOrientedBox extends SingleChildRenderObjectWidget { } void main() { - testWidgets('RenderObjectWidget smoke test', (WidgetTester tester) { - tester.pumpWidget(new DecoratedBox(decoration: kBoxDecorationA)); + testWidgets('RenderObjectWidget smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new DecoratedBox(decoration: kBoxDecorationA)); SingleChildRenderObjectElement element = tester.element(find.byElementType(SingleChildRenderObjectElement)); expect(element, isNotNull); @@ -52,7 +51,7 @@ void main() { expect(renderObject.decoration, equals(kBoxDecorationA)); expect(renderObject.position, equals(DecorationPosition.background)); - tester.pumpWidget(new DecoratedBox(decoration: kBoxDecorationB)); + await tester.pumpWidget(new DecoratedBox(decoration: kBoxDecorationB)); element = tester.element(find.byElementType(SingleChildRenderObjectElement)); expect(element, isNotNull); expect(element.renderObject is RenderDecoratedBox, isTrue); @@ -61,7 +60,7 @@ void main() { expect(renderObject.position, equals(DecorationPosition.background)); }); - testWidgets('RenderObjectWidget can add and remove children', (WidgetTester tester) { + testWidgets('RenderObjectWidget can add and remove children', (WidgetTester tester) async { void checkFullTree() { SingleChildRenderObjectElement element = @@ -90,7 +89,7 @@ void main() { expect(renderObject.child, isNull); } - tester.pumpWidget(new DecoratedBox( + await tester.pumpWidget(new DecoratedBox( decoration: kBoxDecorationA, child: new DecoratedBox( decoration: kBoxDecorationB @@ -99,7 +98,7 @@ void main() { checkFullTree(); - tester.pumpWidget(new DecoratedBox( + await tester.pumpWidget(new DecoratedBox( decoration: kBoxDecorationA, child: new TestWidget( child: new DecoratedBox( @@ -110,7 +109,7 @@ void main() { checkFullTree(); - tester.pumpWidget(new DecoratedBox( + await tester.pumpWidget(new DecoratedBox( decoration: kBoxDecorationA, child: new DecoratedBox( decoration: kBoxDecorationB @@ -119,13 +118,13 @@ void main() { checkFullTree(); - tester.pumpWidget(new DecoratedBox( + await tester.pumpWidget(new DecoratedBox( decoration: kBoxDecorationA )); childBareTree(); - tester.pumpWidget(new DecoratedBox( + await tester.pumpWidget(new DecoratedBox( decoration: kBoxDecorationA, child: new TestWidget( child: new TestWidget( @@ -138,16 +137,16 @@ void main() { checkFullTree(); - tester.pumpWidget(new DecoratedBox( + await tester.pumpWidget(new DecoratedBox( decoration: kBoxDecorationA )); childBareTree(); }); - testWidgets('Detached render tree is intact', (WidgetTester tester) { + testWidgets('Detached render tree is intact', (WidgetTester tester) async { - tester.pumpWidget(new DecoratedBox( + await tester.pumpWidget(new DecoratedBox( decoration: kBoxDecorationA, child: new DecoratedBox( decoration: kBoxDecorationB, @@ -169,7 +168,7 @@ void main() { expect(grandChild.decoration, equals(kBoxDecorationC)); expect(grandChild.child, isNull); - tester.pumpWidget(new DecoratedBox( + await tester.pumpWidget(new DecoratedBox( decoration: kBoxDecorationA )); @@ -187,11 +186,11 @@ void main() { expect(grandChild.child, isNull); }); - testWidgets('Can watch inherited widgets', (WidgetTester tester) { + testWidgets('Can watch inherited widgets', (WidgetTester tester) async { Key boxKey = new UniqueKey(); TestOrientedBox box = new TestOrientedBox(key: boxKey); - tester.pumpWidget(new MediaQuery( + await tester.pumpWidget(new MediaQuery( data: new MediaQueryData(size: const Size(400.0, 300.0)), child: box )); @@ -200,7 +199,7 @@ void main() { BoxDecoration decoration = renderBox.decoration; expect(decoration.backgroundColor, equals(new Color(0xFF00FF00))); - tester.pumpWidget(new MediaQuery( + await tester.pumpWidget(new MediaQuery( data: new MediaQueryData(size: const Size(300.0, 400.0)), child: box )); diff --git a/packages/flutter/test/widget/reparent_state_test.dart b/packages/flutter/test/widget/reparent_state_test.dart index 73cd4e8fee..c84d9a8a04 100644 --- a/packages/flutter/test/widget/reparent_state_test.dart +++ b/packages/flutter/test/widget/reparent_state_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class StateMarker extends StatefulWidget { StateMarker({ Key key, this.child }) : super(key: key); @@ -50,12 +49,12 @@ class DeactivateLoggerState extends State { } void main() { - testWidgets('can reparent state', (WidgetTester tester) { + testWidgets('can reparent state', (WidgetTester tester) async { GlobalKey left = new GlobalKey(); GlobalKey right = new GlobalKey(); StateMarker grandchild = new StateMarker(); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Container( @@ -81,7 +80,7 @@ void main() { grandchildState.marker = "grandchild"; StateMarker newGrandchild = new StateMarker(); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Container( @@ -107,7 +106,7 @@ void main() { expect(newGrandchildState, equals(grandchildState)); expect(newGrandchildState.marker, equals("grandchild")); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new Container( child: new StateMarker( @@ -123,12 +122,12 @@ void main() { expect(right.currentState, isNull); }); - testWidgets('can reparent state with multichild widgets', (WidgetTester tester) { + testWidgets('can reparent state with multichild widgets', (WidgetTester tester) async { GlobalKey left = new GlobalKey(); GlobalKey right = new GlobalKey(); StateMarker grandchild = new StateMarker(); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new StateMarker(key: left), @@ -150,7 +149,7 @@ void main() { grandchildState.marker = "grandchild"; StateMarker newGrandchild = new StateMarker(); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new StateMarker( @@ -172,7 +171,7 @@ void main() { expect(newGrandchildState, equals(grandchildState)); expect(newGrandchildState.marker, equals("grandchild")); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new Container( child: new StateMarker( @@ -188,15 +187,15 @@ void main() { expect(right.currentState, isNull); }); - testWidgets('can with scrollable list', (WidgetTester tester) { + testWidgets('can with scrollable list', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget(new StateMarker(key: key)); + await tester.pumpWidget(new StateMarker(key: key)); StateMarkerState keyState = key.currentState; keyState.marker = "marked"; - tester.pumpWidget(new ScrollableList( + await tester.pumpWidget(new ScrollableList( itemExtent: 100.0, children: [ new Container( @@ -210,16 +209,16 @@ void main() { expect(key.currentState, equals(keyState)); expect(keyState.marker, equals("marked")); - tester.pumpWidget(new StateMarker(key: key)); + await tester.pumpWidget(new StateMarker(key: key)); expect(key.currentState, equals(keyState)); expect(keyState.marker, equals("marked")); }); - testWidgets('Reparent during update children', (WidgetTester tester) { + testWidgets('Reparent during update children', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget(new Stack( + await tester.pumpWidget(new Stack( children: [ new StateMarker(key: key), new Container(width: 100.0, height: 100.0), @@ -229,7 +228,7 @@ void main() { StateMarkerState keyState = key.currentState; keyState.marker = "marked"; - tester.pumpWidget(new Stack( + await tester.pumpWidget(new Stack( children: [ new Container(width: 100.0, height: 100.0), new StateMarker(key: key), @@ -239,7 +238,7 @@ void main() { expect(key.currentState, equals(keyState)); expect(keyState.marker, equals("marked")); - tester.pumpWidget(new Stack( + await tester.pumpWidget(new Stack( children: [ new StateMarker(key: key), new Container(width: 100.0, height: 100.0), @@ -250,10 +249,10 @@ void main() { expect(keyState.marker, equals("marked")); }); - testWidgets('Reparent to child during update children', (WidgetTester tester) { + testWidgets('Reparent to child during update children', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); - tester.pumpWidget(new Stack( + await tester.pumpWidget(new Stack( children: [ new Container(width: 100.0, height: 100.0), new StateMarker(key: key), @@ -264,7 +263,7 @@ void main() { StateMarkerState keyState = key.currentState; keyState.marker = "marked"; - tester.pumpWidget(new Stack( + await tester.pumpWidget(new Stack( children: [ new Container(width: 100.0, height: 100.0, child: new StateMarker(key: key)), new Container(width: 100.0, height: 100.0), @@ -274,7 +273,7 @@ void main() { expect(key.currentState, equals(keyState)); expect(keyState.marker, equals("marked")); - tester.pumpWidget(new Stack( + await tester.pumpWidget(new Stack( children: [ new Container(width: 100.0, height: 100.0), new StateMarker(key: key), @@ -285,7 +284,7 @@ void main() { expect(key.currentState, equals(keyState)); expect(keyState.marker, equals("marked")); - tester.pumpWidget(new Stack( + await tester.pumpWidget(new Stack( children: [ new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0, child: new StateMarker(key: key)), @@ -295,7 +294,7 @@ void main() { expect(key.currentState, equals(keyState)); expect(keyState.marker, equals("marked")); - tester.pumpWidget(new Stack( + await tester.pumpWidget(new Stack( children: [ new Container(width: 100.0, height: 100.0), new StateMarker(key: key), @@ -307,25 +306,25 @@ void main() { expect(keyState.marker, equals("marked")); }); - testWidgets('Deactivate implies build', (WidgetTester tester) { + testWidgets('Deactivate implies build', (WidgetTester tester) async { GlobalKey key = new GlobalKey(); List log = []; DeactivateLogger logger = new DeactivateLogger(key: key, log: log); - tester.pumpWidget( + await tester.pumpWidget( new Container(key: new UniqueKey(), child: logger) ); expect(log, equals(['build'])); - tester.pumpWidget( + await tester.pumpWidget( new Container(key: new UniqueKey(), child: logger) ); expect(log, equals(['build', 'deactivate', 'build'])); log.clear(); - tester.pump(); + await tester.pump(); expect(log, isEmpty); }); } diff --git a/packages/flutter/test/widget/rotated_box_test.dart b/packages/flutter/test/widget/rotated_box_test.dart index bda2c695d9..4bd2bd140f 100644 --- a/packages/flutter/test/widget/rotated_box_test.dart +++ b/packages/flutter/test/widget/rotated_box_test.dart @@ -4,14 +4,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Rotated box control test', (WidgetTester tester) { + testWidgets('Rotated box control test', (WidgetTester tester) async { List log = []; Key rotatedBoxKey = new UniqueKey(); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new RotatedBox( key: rotatedBoxKey, @@ -45,11 +44,11 @@ void main() { expect(box.size.width, equals(65.0)); expect(box.size.height, equals(175.0)); - tester.tapAt(new Point(420.0, 280.0)); + await tester.tapAt(new Point(420.0, 280.0)); expect(log, equals(['left'])); log.clear(); - tester.tapAt(new Point(380.0, 320.0)); + await tester.tapAt(new Point(380.0, 320.0)); expect(log, equals(['right'])); log.clear(); }); diff --git a/packages/flutter/test/widget/routes_test.dart b/packages/flutter/test/widget/routes_test.dart index 0f88253e02..df83bc7b61 100644 --- a/packages/flutter/test/widget/routes_test.dart +++ b/packages/flutter/test/widget/routes_test.dart @@ -6,7 +6,6 @@ import 'dart:collection'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; final List results = []; @@ -76,28 +75,28 @@ class TestRoute extends Route { } -void runNavigatorTest( +Future runNavigatorTest( WidgetTester tester, NavigatorState host, NavigatorTransactionCallback test, List expectations -) { +) async { expect(host, isNotNull); host.openTransaction(test); expect(results, equals(expectations)); results.clear(); - tester.pump(); + await tester.pump(); } void main() { - testWidgets('Route management - push, replace, pop', (WidgetTester tester) { + testWidgets('Route management - push, replace, pop', (WidgetTester tester) async { GlobalKey navigatorKey = new GlobalKey(); - tester.pumpWidget(new Navigator( + await tester.pumpWidget(new Navigator( key: navigatorKey, onGenerateRoute: (_) => new TestRoute('initial') )); NavigatorState host = navigatorKey.currentState; - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -109,7 +108,7 @@ void main() { ] ); TestRoute second; - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -122,7 +121,7 @@ void main() { 'initial: didChangeNext second', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -135,7 +134,7 @@ void main() { 'second: didChangeNext third', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -149,7 +148,7 @@ void main() { 'second: dispose', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -161,7 +160,7 @@ void main() { 'two: didPopNext third', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -173,20 +172,20 @@ void main() { 'initial: didPopNext two', ] ); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); expect(results, equals(['initial: dispose'])); expect(routes.isEmpty, isTrue); results.clear(); }); - testWidgets('Route management - push, remove, pop', (WidgetTester tester) { + testWidgets('Route management - push, remove, pop', (WidgetTester tester) async { GlobalKey navigatorKey = new GlobalKey(); - tester.pumpWidget(new Navigator( + await tester.pumpWidget(new Navigator( key: navigatorKey, onGenerateRoute: (_) => new TestRoute('first') )); NavigatorState host = navigatorKey.currentState; - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -198,7 +197,7 @@ void main() { ] ); TestRoute second; - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -211,7 +210,7 @@ void main() { 'first: didChangeNext second', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -224,7 +223,7 @@ void main() { 'second: didChangeNext third', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -234,7 +233,7 @@ void main() { 'first: dispose', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -246,7 +245,7 @@ void main() { 'second: didPopNext third', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -260,7 +259,7 @@ void main() { ] ); TestRoute four; - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -273,7 +272,7 @@ void main() { 'three: didChangeNext four', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -284,7 +283,7 @@ void main() { 'three: dispose', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -296,20 +295,20 @@ void main() { 'second: didPopNext four', ] ); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); expect(results, equals(['second: dispose'])); expect(routes.isEmpty, isTrue); results.clear(); }); - testWidgets('Route management - push, replace, popUntil', (WidgetTester tester) { + testWidgets('Route management - push, replace, popUntil', (WidgetTester tester) async { GlobalKey navigatorKey = new GlobalKey(); - tester.pumpWidget(new Navigator( + await tester.pumpWidget(new Navigator( key: navigatorKey, onGenerateRoute: (_) => new TestRoute('A') )); NavigatorState host = navigatorKey.currentState; - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -320,7 +319,7 @@ void main() { 'A: didChangeNext null', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -334,7 +333,7 @@ void main() { ] ); TestRoute routeC; - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -348,7 +347,7 @@ void main() { ] ); TestRoute routeB; - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -362,7 +361,7 @@ void main() { 'B: dispose', ] ); - runNavigatorTest( + await runNavigatorTest( tester, host, (NavigatorTransaction transaction) { @@ -374,7 +373,7 @@ void main() { 'b: didPopNext C', ] ); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); expect(results, equals(['A: dispose', 'b: dispose'])); expect(routes.isEmpty, isTrue); results.clear(); diff --git a/packages/flutter/test/widget/scroll_events_test.dart b/packages/flutter/test/widget/scroll_events_test.dart index 1f6ba413e8..bd623d4e9f 100644 --- a/packages/flutter/test/widget/scroll_events_test.dart +++ b/packages/flutter/test/widget/scroll_events_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; Widget _buildScroller({Key key, List log}) { return new ScrollableViewport( @@ -23,120 +22,120 @@ Widget _buildScroller({Key key, List log}) { } void main() { - testWidgets('Scroll event drag', (WidgetTester tester) { + testWidgets('Scroll event drag', (WidgetTester tester) async { List log = []; - tester.pumpWidget(_buildScroller(log: log)); + await tester.pumpWidget(_buildScroller(log: log)); expect(log, equals([])); - TestGesture gesture = tester.startGesture(new Point(100.0, 100.0)); + TestGesture gesture = await tester.startGesture(new Point(100.0, 100.0)); expect(log, equals(['scrollstart'])); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(log, equals(['scrollstart'])); - gesture.moveBy(new Offset(-10.0, -10.0)); + await gesture.moveBy(new Offset(-10.0, -10.0)); expect(log, equals(['scrollstart', 'scroll'])); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(log, equals(['scrollstart', 'scroll'])); - gesture.up(); + await gesture.up(); expect(log, equals(['scrollstart', 'scroll'])); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(log, equals(['scrollstart', 'scroll', 'scrollend'])); }); - testWidgets('Scroll scrollTo animation', (WidgetTester tester) { + testWidgets('Scroll scrollTo animation', (WidgetTester tester) async { GlobalKey> scrollKey = new GlobalKey>(); List log = []; - tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); + await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); expect(log, equals([])); scrollKey.currentState.scrollTo(100.0, duration: const Duration(seconds: 1)); expect(log, equals(['scrollstart'])); - tester.pump(const Duration(milliseconds: 100)); + await tester.pump(const Duration(milliseconds: 100)); expect(log, equals(['scrollstart'])); - tester.pump(const Duration(milliseconds: 100)); + await tester.pump(const Duration(milliseconds: 100)); expect(log, equals(['scrollstart', 'scroll'])); - tester.pump(const Duration(milliseconds: 1500)); + await tester.pump(const Duration(milliseconds: 1500)); expect(log, equals(['scrollstart', 'scroll', 'scroll', 'scrollend'])); }); - testWidgets('Scroll scrollTo no animation', (WidgetTester tester) { + testWidgets('Scroll scrollTo no animation', (WidgetTester tester) async { GlobalKey> scrollKey = new GlobalKey>(); List log = []; - tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); + await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); expect(log, equals([])); scrollKey.currentState.scrollTo(100.0); expect(log, equals(['scrollstart', 'scroll', 'scrollend'])); }); - testWidgets('Scroll during animation', (WidgetTester tester) { + testWidgets('Scroll during animation', (WidgetTester tester) async { GlobalKey> scrollKey = new GlobalKey>(); List log = []; - tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); + await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); expect(log, equals([])); scrollKey.currentState.scrollTo(100.0, duration: const Duration(seconds: 1)); expect(log, equals(['scrollstart'])); - tester.pump(const Duration(milliseconds: 100)); + await tester.pump(const Duration(milliseconds: 100)); expect(log, equals(['scrollstart'])); - tester.pump(const Duration(milliseconds: 100)); + await tester.pump(const Duration(milliseconds: 100)); expect(log, equals(['scrollstart', 'scroll'])); scrollKey.currentState.scrollTo(100.0); expect(log, equals(['scrollstart', 'scroll', 'scroll'])); - tester.pump(const Duration(milliseconds: 100)); + await tester.pump(const Duration(milliseconds: 100)); expect(log, equals(['scrollstart', 'scroll', 'scroll', 'scrollend'])); - tester.pump(const Duration(milliseconds: 1500)); + await tester.pump(const Duration(milliseconds: 1500)); expect(log, equals(['scrollstart', 'scroll', 'scroll', 'scrollend'])); }); - testWidgets('Scroll during animation', (WidgetTester tester) { + testWidgets('Scroll during animation', (WidgetTester tester) async { GlobalKey> scrollKey = new GlobalKey>(); List log = []; - tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); + await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); expect(log, equals([])); scrollKey.currentState.scrollTo(100.0, duration: const Duration(seconds: 1)); expect(log, equals(['scrollstart'])); - tester.pump(const Duration(milliseconds: 100)); + await tester.pump(const Duration(milliseconds: 100)); expect(log, equals(['scrollstart'])); - tester.pump(const Duration(milliseconds: 100)); + await tester.pump(const Duration(milliseconds: 100)); expect(log, equals(['scrollstart', 'scroll'])); scrollKey.currentState.scrollTo(100.0, duration: const Duration(seconds: 1)); expect(log, equals(['scrollstart', 'scroll'])); - tester.pump(const Duration(milliseconds: 100)); + await tester.pump(const Duration(milliseconds: 100)); expect(log, equals(['scrollstart', 'scroll'])); - tester.pump(const Duration(milliseconds: 1500)); + await tester.pump(const Duration(milliseconds: 1500)); expect(log, equals(['scrollstart', 'scroll', 'scroll', 'scrollend'])); }); - testWidgets('fling, fling generates two start/end pairs', (WidgetTester tester) { + testWidgets('fling, fling generates two start/end pairs', (WidgetTester tester) async { GlobalKey> scrollKey = new GlobalKey>(); List log = []; - tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); + await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); expect(log, equals([])); - tester.flingFrom(new Point(100.0, 100.0), new Offset(-50.0, -50.0), 500.0); - tester.pump(new Duration(seconds: 1)); + await tester.flingFrom(new Point(100.0, 100.0), new Offset(-50.0, -50.0), 500.0); + await tester.pump(new Duration(seconds: 1)); log.removeWhere((String value) => value == 'scroll'); expect(log, equals(['scrollstart'])); - tester.flingFrom(new Point(100.0, 100.0), new Offset(-50.0, -50.0), 500.0); + await tester.flingFrom(new Point(100.0, 100.0), new Offset(-50.0, -50.0), 500.0); log.removeWhere((String value) => value == 'scroll'); expect(log, equals(['scrollstart', 'scrollend', 'scrollstart'])); - tester.pump(new Duration(seconds: 1)); - tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); log.removeWhere((String value) => value == 'scroll'); expect(log, equals(['scrollstart', 'scrollend', 'scrollstart', 'scrollend'])); }); - testWidgets('fling up ends', (WidgetTester tester) { + testWidgets('fling up ends', (WidgetTester tester) async { GlobalKey> scrollKey = new GlobalKey>(); List log = []; - tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); + await tester.pumpWidget(_buildScroller(key: scrollKey, log: log)); expect(log, equals([])); - tester.flingFrom(new Point(100.0, 100.0), new Offset(50.0, 50.0), 500.0); - tester.pump(new Duration(seconds: 1)); - tester.pump(new Duration(seconds: 1)); - tester.pump(new Duration(seconds: 1)); + await tester.flingFrom(new Point(100.0, 100.0), new Offset(50.0, 50.0), 500.0); + await tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); + await tester.pump(new Duration(seconds: 1)); expect(log.first, equals('scrollstart')); expect(log.last, equals('scrollend')); log.removeWhere((String value) => value == 'scroll'); diff --git a/packages/flutter/test/widget/scroll_interaction_test.dart b/packages/flutter/test/widget/scroll_interaction_test.dart index e652237c5d..cfb5229bc2 100644 --- a/packages/flutter/test/widget/scroll_interaction_test.dart +++ b/packages/flutter/test/widget/scroll_interaction_test.dart @@ -4,11 +4,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Scroll flings twice in a row does not crash', (WidgetTester tester) { - tester.pumpWidget(new Block( + testWidgets('Scroll flings twice in a row does not crash', (WidgetTester tester) async { + await tester.pumpWidget(new Block( children: [ new Container(height: 100000.0) ] @@ -19,17 +18,17 @@ void main() { expect(scrollable.scrollOffset, equals(0.0)); - tester.flingFrom(new Point(200.0, 300.0), new Offset(0.0, -200.0), 500.0); - tester.pump(); - tester.pump(const Duration(seconds: 5)); + await tester.flingFrom(new Point(200.0, 300.0), new Offset(0.0, -200.0), 500.0); + await tester.pump(); + await tester.pump(const Duration(seconds: 5)); expect(scrollable.scrollOffset, greaterThan(0.0)); double oldOffset = scrollable.scrollOffset; - tester.flingFrom(new Point(200.0, 300.0), new Offset(0.0, -200.0), 500.0); - tester.pump(); - tester.pump(const Duration(seconds: 5)); + await tester.flingFrom(new Point(200.0, 300.0), new Offset(0.0, -200.0), 500.0); + await tester.pump(); + await tester.pump(const Duration(seconds: 5)); expect(scrollable.scrollOffset, greaterThan(oldOffset)); }); diff --git a/packages/flutter/test/widget/scrollable_lazy_list_test.dart b/packages/flutter/test/widget/scrollable_lazy_list_test.dart index c22b1ae999..ccc4352fa2 100644 --- a/packages/flutter/test/widget/scrollable_lazy_list_test.dart +++ b/packages/flutter/test/widget/scrollable_lazy_list_test.dart @@ -4,12 +4,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; import 'test_widgets.dart'; void main() { - testWidgets('HomogeneousViewport mount/dismount smoke test', (WidgetTester tester) { + testWidgets('HomogeneousViewport mount/dismount smoke test', (WidgetTester tester) async { List callbackTracker = []; // the root view is 800x600 in the test environment @@ -36,7 +35,7 @@ void main() { ); } - tester.pumpWidget(builder()); + await tester.pumpWidget(builder()); FlipWidgetState testWidget = tester.state(find.byType(FlipWidget)); @@ -44,18 +43,18 @@ void main() { callbackTracker.clear(); testWidget.flip(); - tester.pump(); + await tester.pump(); expect(callbackTracker, equals([])); callbackTracker.clear(); testWidget.flip(); - tester.pump(); + await tester.pump(); expect(callbackTracker, equals([0, 1, 2, 3, 4, 5])); }); - testWidgets('HomogeneousViewport vertical', (WidgetTester tester) { + testWidgets('HomogeneousViewport vertical', (WidgetTester tester) async { List callbackTracker = []; // the root view is 800x600 in the test environment @@ -87,7 +86,7 @@ void main() { right: new Text('Not Today') ); - tester.pumpWidget(testWidget); + await tester.pumpWidget(testWidget); expect(callbackTracker, equals([1, 2, 3, 4])); @@ -96,14 +95,14 @@ void main() { scrollableKey.currentState.scrollTo(400.0); // now only 3 should fit, numbered 2-4. - tester.pumpWidget(testWidget); + await tester.pumpWidget(testWidget); expect(callbackTracker, equals([2, 3, 4])); callbackTracker.clear(); }); - testWidgets('HomogeneousViewport horizontal', (WidgetTester tester) { + testWidgets('HomogeneousViewport horizontal', (WidgetTester tester) async { List callbackTracker = []; // the root view is 800x600 in the test environment @@ -136,7 +135,7 @@ void main() { right: new Text('Not Today') ); - tester.pumpWidget(testWidget); + await tester.pumpWidget(testWidget); expect(callbackTracker, equals([1, 2, 3, 4, 5])); @@ -145,14 +144,14 @@ void main() { scrollableKey.currentState.scrollTo(400.0); // now only 4 should fit, numbered 2-5. - tester.pumpWidget(testWidget); + await tester.pumpWidget(testWidget); expect(callbackTracker, equals([2, 3, 4, 5])); callbackTracker.clear(); }); - testWidgets('ScrollableLazyList 10 items, 2-3 items visible', (WidgetTester tester) { + testWidgets('ScrollableLazyList 10 items, 2-3 items visible', (WidgetTester tester) async { List callbackTracker = []; // The root view is 800x600 in the test environment and our list @@ -176,22 +175,22 @@ void main() { itemCount: 10 ); - tester.pumpWidget(testWidget); + await tester.pumpWidget(testWidget); expect(callbackTracker, equals([0, 1])); callbackTracker.clear(); scrollableKey.currentState.scrollTo(150.0); - tester.pumpWidget(testWidget); + await tester.pumpWidget(testWidget); expect(callbackTracker, equals([0, 1, 2])); callbackTracker.clear(); scrollableKey.currentState.scrollTo(600.0); - tester.pumpWidget(testWidget); + await tester.pumpWidget(testWidget); expect(callbackTracker, equals([2, 3])); callbackTracker.clear(); scrollableKey.currentState.scrollTo(750.0); - tester.pumpWidget(testWidget); + await tester.pumpWidget(testWidget); expect(callbackTracker, equals([2, 3, 4])); callbackTracker.clear(); }); diff --git a/packages/flutter/test/widget/scrollable_list_hit_testing_test.dart b/packages/flutter/test/widget/scrollable_list_hit_testing_test.dart index b2b31497e1..6352c1a630 100644 --- a/packages/flutter/test/widget/scrollable_list_hit_testing_test.dart +++ b/packages/flutter/test/widget/scrollable_list_hit_testing_test.dart @@ -5,14 +5,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; const List items = const [0, 1, 2, 3, 4, 5]; void main() { - testWidgets('Tap item after scroll - horizontal', (WidgetTester tester) { + testWidgets('Tap item after scroll - horizontal', (WidgetTester tester) async { List tapped = []; - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new Container( height: 50.0, child: new ScrollableList( @@ -30,8 +29,8 @@ void main() { ) ) )); - tester.scroll(find.text('2'), const Offset(-280.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('2'), const Offset(-280.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -280..10 = 0 // 10..300 = 1 @@ -44,13 +43,13 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); expect(tapped, equals([])); - tester.tap(find.text('2')); + await tester.tap(find.text('2')); expect(tapped, equals([2])); }); - testWidgets('Tap item after scroll - vertical', (WidgetTester tester) { + testWidgets('Tap item after scroll - vertical', (WidgetTester tester) async { List tapped = []; - tester.pumpWidget(new Center( + await tester.pumpWidget(new Center( child: new Container( width: 50.0, child: new ScrollableList( @@ -68,8 +67,8 @@ void main() { ) ) )); - tester.scroll(find.text('1'), const Offset(0.0, -280.0)); - tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('1'), const Offset(0.0, -280.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 600px tall, and has the following items: // -280..10 = 0 // 10..300 = 1 @@ -82,16 +81,16 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); expect(tapped, equals([])); - tester.tap(find.text('1')); + await tester.tap(find.text('1')); expect(tapped, equals([1])); - tester.tap(find.text('3')); + await tester.tap(find.text('3')); expect(tapped, equals([1])); // the center of the third item is off-screen so it shouldn't get hit }); - testWidgets('Padding scroll anchor start', (WidgetTester tester) { + testWidgets('Padding scroll anchor start', (WidgetTester tester) async { List tapped = []; - tester.pumpWidget( + await tester.pumpWidget( new ScrollableList( key: new GlobalKey(), itemExtent: 290.0, @@ -106,24 +105,24 @@ void main() { }) ) ); - tester.tapAt(new Point(200.0, 19.0)); + await tester.tapAt(new Point(200.0, 19.0)); expect(tapped, equals([])); - tester.tapAt(new Point(200.0, 21.0)); + await tester.tapAt(new Point(200.0, 21.0)); expect(tapped, equals([0])); - tester.tapAt(new Point(4.0, 400.0)); + await tester.tapAt(new Point(4.0, 400.0)); expect(tapped, equals([0])); - tester.tapAt(new Point(6.0, 400.0)); + await tester.tapAt(new Point(6.0, 400.0)); expect(tapped, equals([0, 1])); - tester.tapAt(new Point(800.0 - 14.0, 400.0)); + await tester.tapAt(new Point(800.0 - 14.0, 400.0)); expect(tapped, equals([0, 1])); - tester.tapAt(new Point(800.0 - 16.0, 400.0)); + await tester.tapAt(new Point(800.0 - 16.0, 400.0)); expect(tapped, equals([0, 1, 1])); }); - testWidgets('Padding scroll anchor end', (WidgetTester tester) { + testWidgets('Padding scroll anchor end', (WidgetTester tester) async { List tapped = []; - tester.pumpWidget( + await tester.pumpWidget( new ScrollableList( key: new GlobalKey(), itemExtent: 290.0, @@ -139,17 +138,17 @@ void main() { }) ) ); - tester.tapAt(new Point(200.0, 600.0 - 9.0)); + await tester.tapAt(new Point(200.0, 600.0 - 9.0)); expect(tapped, equals([])); - tester.tapAt(new Point(200.0, 600.0 - 11.0)); + await tester.tapAt(new Point(200.0, 600.0 - 11.0)); expect(tapped, equals([5])); - tester.tapAt(new Point(4.0, 200.0)); + await tester.tapAt(new Point(4.0, 200.0)); expect(tapped, equals([5])); - tester.tapAt(new Point(6.0, 200.0)); + await tester.tapAt(new Point(6.0, 200.0)); expect(tapped, equals([5, 4])); - tester.tapAt(new Point(800.0 - 14.0, 200.0)); + await tester.tapAt(new Point(800.0 - 14.0, 200.0)); expect(tapped, equals([5, 4])); - tester.tapAt(new Point(800.0 - 16.0, 200.0)); + await tester.tapAt(new Point(800.0 - 16.0, 200.0)); expect(tapped, equals([5, 4, 4])); }); } diff --git a/packages/flutter/test/widget/scrollable_list_horizontal_test.dart b/packages/flutter/test/widget/scrollable_list_horizontal_test.dart index 205a95b1e9..0c4102c08e 100644 --- a/packages/flutter/test/widget/scrollable_list_horizontal_test.dart +++ b/packages/flutter/test/widget/scrollable_list_horizontal_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; const List items = const [0, 1, 2, 3, 4, 5]; @@ -28,12 +27,12 @@ Widget buildFrame(ViewportAnchor scrollAnchor) { } void main() { - testWidgets('Drag horizontally with scroll anchor at top', (WidgetTester tester) { - tester.pumpWidget(buildFrame(ViewportAnchor.start)); + testWidgets('Drag horizontally with scroll anchor at top', (WidgetTester tester) async { + await tester.pumpWidget(buildFrame(ViewportAnchor.start)); - tester.pump(const Duration(seconds: 1)); - tester.scroll(find.text('1'), const Offset(-300.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('1'), const Offset(-300.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -10..280 = 1 // 280..570 = 2 @@ -48,9 +47,9 @@ void main() { // the center of item 3 is visible, so this works; // if item 3 was a bit wider, such that its center was past the 800px mark, this would fail, // because it wouldn't be hit tested when scrolling from its center, as scroll() does. - tester.pump(const Duration(seconds: 1)); - tester.scroll(find.text('3'), const Offset(-290.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('3'), const Offset(-290.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -10..280 = 2 // 280..570 = 3 @@ -62,9 +61,9 @@ void main() { expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsNothing); - tester.pump(const Duration(seconds: 1)); - tester.scroll(find.text('3'), const Offset(0.0, -290.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('3'), const Offset(0.0, -290.0)); + await tester.pump(const Duration(seconds: 1)); // unchanged expect(find.text('0'), findsNothing); expect(find.text('1'), findsNothing); @@ -73,9 +72,9 @@ void main() { expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsNothing); - tester.pump(const Duration(seconds: 1)); - tester.scroll(find.text('3'), const Offset(-290.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('3'), const Offset(-290.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -10..280 = 3 // 280..570 = 4 @@ -87,14 +86,14 @@ void main() { expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsOneWidget); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); // at this point we can drag 60 pixels further before we hit the friction zone // then, every pixel we drag is equivalent to half a pixel of movement // to move item 3 entirely off screen therefore takes: // 60 + (290-60)*2 = 520 pixels // plus a couple more to be sure - tester.scroll(find.text('3'), const Offset(-522.0, 0.0)); - tester.pump(); // just after release + await tester.scroll(find.text('3'), const Offset(-522.0, 0.0)); + await tester.pump(); // just after release // screen is 800px wide, and has the following items: // -11..279 = 4 // 279..569 = 5 @@ -104,7 +103,7 @@ void main() { expect(find.text('3'), findsNothing); expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsOneWidget); - tester.pump(const Duration(seconds: 1)); // a second after release + await tester.pump(const Duration(seconds: 1)); // a second after release // screen is 800px wide, and has the following items: // -70..220 = 3 // 220..510 = 4 @@ -116,10 +115,10 @@ void main() { expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsOneWidget); - tester.pumpWidget(new Container()); - tester.pumpWidget(buildFrame(ViewportAnchor.start), const Duration(seconds: 1)); - tester.scroll(find.text('2'), const Offset(-280.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pumpWidget(new Container()); + await tester.pumpWidget(buildFrame(ViewportAnchor.start), const Duration(seconds: 1)); + await tester.scroll(find.text('2'), const Offset(-280.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -280..10 = 0 // 10..300 = 1 @@ -131,9 +130,9 @@ void main() { expect(find.text('3'), findsOneWidget); expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - tester.pump(const Duration(seconds: 1)); - tester.scroll(find.text('2'), const Offset(-290.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('2'), const Offset(-290.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -280..10 = 1 // 10..300 = 2 @@ -147,10 +146,10 @@ void main() { expect(find.text('5'), findsNothing); }); - testWidgets('Drag horizontally with scroll anchor at end', (WidgetTester tester) { - tester.pumpWidget(buildFrame(ViewportAnchor.end)); + testWidgets('Drag horizontally with scroll anchor at end', (WidgetTester tester) async { + await tester.pumpWidget(buildFrame(ViewportAnchor.end)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -70..220 = 3 // 220..510 = 4 @@ -162,8 +161,8 @@ void main() { expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsOneWidget); - tester.scroll(find.text('5'), const Offset(300.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('5'), const Offset(300.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -80..210 = 2 // 230..520 = 3 @@ -178,9 +177,9 @@ void main() { // the center of item 3 is visible, so this works; // if item 3 was a bit wider, such that its center was past the 800px mark, this would fail, // because it wouldn't be hit tested when scrolling from its center, as scroll() does. - tester.pump(const Duration(seconds: 1)); - tester.scroll(find.text('3'), const Offset(290.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('3'), const Offset(290.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -10..280 = 1 // 280..570 = 2 @@ -192,9 +191,9 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - tester.pump(const Duration(seconds: 1)); - tester.scroll(find.text('3'), const Offset(0.0, 290.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('3'), const Offset(0.0, 290.0)); + await tester.pump(const Duration(seconds: 1)); // unchanged expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); @@ -203,9 +202,9 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - tester.pump(const Duration(seconds: 1)); - tester.scroll(find.text('2'), const Offset(290.0, 0.0)); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); + await tester.scroll(find.text('2'), const Offset(290.0, 0.0)); + await tester.pump(const Duration(seconds: 1)); // screen is 800px wide, and has the following items: // -10..280 = 0 // 280..570 = 1 @@ -217,14 +216,14 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); // at this point we can drag 60 pixels further before we hit the friction zone // then, every pixel we drag is equivalent to half a pixel of movement // to move item 3 entirely off screen therefore takes: // 60 + (290-60)*2 = 520 pixels // plus a couple more to be sure - tester.scroll(find.text('1'), const Offset(522.0, 0.0)); - tester.pump(); // just after release + await tester.scroll(find.text('1'), const Offset(522.0, 0.0)); + await tester.pump(); // just after release // screen is 800px wide, and has the following items: // 280..570 = 0 // 570..860 = 1 @@ -234,7 +233,7 @@ void main() { expect(find.text('3'), findsNothing); expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - tester.pump(const Duration(seconds: 1)); // a second after release + await tester.pump(const Duration(seconds: 1)); // a second after release // screen is 800px wide, and has the following items: // 0..290 = 0 // 290..580 = 1 diff --git a/packages/flutter/test/widget/scrollable_list_vertical_test.dart b/packages/flutter/test/widget/scrollable_list_vertical_test.dart index d3a53e2a52..d37abdf73b 100644 --- a/packages/flutter/test/widget/scrollable_list_vertical_test.dart +++ b/packages/flutter/test/widget/scrollable_list_vertical_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; const List items = const [0, 1, 2, 3, 4, 5]; @@ -21,12 +20,12 @@ Widget buildFrame() { } void main() { - testWidgets('Drag vertically', (WidgetTester tester) { - tester.pumpWidget(buildFrame()); + testWidgets('Drag vertically', (WidgetTester tester) async { + await tester.pumpWidget(buildFrame()); - tester.pump(); - tester.scroll(find.text('1'), const Offset(0.0, -300.0)); - tester.pump(); + await tester.pump(); + await tester.scroll(find.text('1'), const Offset(0.0, -300.0)); + await tester.pump(); // screen is 600px high, and has the following items: // -10..280 = 1 // 280..570 = 2 @@ -38,9 +37,9 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - tester.pump(); - tester.scroll(find.text('2'), const Offset(0.0, -290.0)); - tester.pump(); + await tester.pump(); + await tester.scroll(find.text('2'), const Offset(0.0, -290.0)); + await tester.pump(); // screen is 600px high, and has the following items: // -10..280 = 2 // 280..570 = 3 @@ -52,9 +51,9 @@ void main() { expect(find.text('4'), findsOneWidget); expect(find.text('5'), findsNothing); - tester.pump(); - tester.scroll(find.text('3'), const Offset(-300.0, 0.0)); - tester.pump(); + await tester.pump(); + await tester.scroll(find.text('3'), const Offset(-300.0, 0.0)); + await tester.pump(); // nothing should have changed expect(find.text('0'), findsNothing); expect(find.text('1'), findsNothing); @@ -64,8 +63,8 @@ void main() { expect(find.text('5'), findsNothing); }); - testWidgets('Drag vertically', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Drag vertically', (WidgetTester tester) async { + await tester.pumpWidget( new ScrollableList( itemExtent: 290.0, padding: new EdgeInsets.only(top: 250.0), @@ -78,7 +77,7 @@ void main() { ) ); - tester.pump(); + await tester.pump(); // screen is 600px high, and has the following items: // 250..540 = 0 // 540..830 = 1 @@ -89,8 +88,8 @@ void main() { expect(find.text('4'), findsNothing); expect(find.text('5'), findsNothing); - tester.scroll(find.text('0'), const Offset(0.0, -300.0)); - tester.pump(); + await tester.scroll(find.text('0'), const Offset(0.0, -300.0)); + await tester.pump(); // screen is 600px high, and has the following items: // -50..240 = 0 // 240..530 = 1 diff --git a/packages/flutter/test/widget/scrollable_list_with_inherited_test.dart b/packages/flutter/test/widget/scrollable_list_with_inherited_test.dart index 1bc5bc73ce..662a1837d6 100644 --- a/packages/flutter/test/widget/scrollable_list_with_inherited_test.dart +++ b/packages/flutter/test/widget/scrollable_list_with_inherited_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; List items = [0, 1, 2, 3, 4, 5]; @@ -28,14 +27,14 @@ Widget buildFrame() { } void main() { - testWidgets('LazyBlock is a build function (smoketest)', (WidgetTester tester) { - tester.pumpWidget(buildFrame()); + testWidgets('LazyBlock is a build function (smoketest)', (WidgetTester tester) async { + await tester.pumpWidget(buildFrame()); expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsOneWidget); expect(find.text('2'), findsOneWidget); expect(find.text('3'), findsOneWidget); items.removeAt(2); - tester.pumpWidget(buildFrame()); + await tester.pumpWidget(buildFrame()); expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsOneWidget); expect(find.text('2'), findsNothing); diff --git a/packages/flutter/test/widget/semantics_1_test.dart b/packages/flutter/test/widget/semantics_1_test.dart index f7bf310f1d..d4d12d7b58 100644 --- a/packages/flutter/test/widget/semantics_1_test.dart +++ b/packages/flutter/test/widget/semantics_1_test.dart @@ -6,16 +6,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import 'test_semantics.dart'; void main() { - testWidgets('Semantics 1', (WidgetTester tester) { + testWidgets('Semantics 1', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); // smoketest - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new Semantics( label: 'test1', @@ -42,7 +41,7 @@ void main() { client.updates.clear(); // control for forking - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( @@ -79,7 +78,7 @@ void main() { client.updates.clear(); // forking semantics - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( @@ -144,7 +143,7 @@ void main() { client.updates.clear(); // toggle a branch off - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( @@ -181,7 +180,7 @@ void main() { client.updates.clear(); // toggle a branch back on - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( diff --git a/packages/flutter/test/widget/semantics_2_test.dart b/packages/flutter/test/widget/semantics_2_test.dart index dcc089d134..3fe5357dc4 100644 --- a/packages/flutter/test/widget/semantics_2_test.dart +++ b/packages/flutter/test/widget/semantics_2_test.dart @@ -6,12 +6,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import 'test_semantics.dart'; void main() { - testWidgets('Semantics 2', (WidgetTester tester) { + testWidgets('Semantics 2', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); // this test is the same as the test in Semantics 1, but @@ -19,7 +18,7 @@ void main() { // switching to not ignoring it. // forking semantics - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( @@ -84,7 +83,7 @@ void main() { client.updates.clear(); // toggle a branch off - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( @@ -121,7 +120,7 @@ void main() { client.updates.clear(); // toggle a branch back on - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( diff --git a/packages/flutter/test/widget/semantics_3_test.dart b/packages/flutter/test/widget/semantics_3_test.dart index 0e5a054067..696f298dec 100644 --- a/packages/flutter/test/widget/semantics_3_test.dart +++ b/packages/flutter/test/widget/semantics_3_test.dart @@ -5,16 +5,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import 'test_semantics.dart'; void main() { - testWidgets('Semantics 3', (WidgetTester tester) { + testWidgets('Semantics 3', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); // implicit annotators - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new Semantics( label: 'test', @@ -45,7 +44,7 @@ void main() { client.updates.clear(); // remove one - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new Container( child: new Semantics( @@ -73,7 +72,7 @@ void main() { client.updates.clear(); // change what it says - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new Container( child: new Semantics( @@ -101,7 +100,7 @@ void main() { client.updates.clear(); // add a node - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new Semantics( checked: true, @@ -132,7 +131,7 @@ void main() { client.updates.clear(); // make no changes - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new Semantics( checked: true, diff --git a/packages/flutter/test/widget/semantics_4_test.dart b/packages/flutter/test/widget/semantics_4_test.dart index 77ae48620a..cd016a5dfc 100644 --- a/packages/flutter/test/widget/semantics_4_test.dart +++ b/packages/flutter/test/widget/semantics_4_test.dart @@ -5,12 +5,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import 'test_semantics.dart'; void main() { - testWidgets('Semantics 4', (WidgetTester tester) { + testWidgets('Semantics 4', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); // O @@ -19,7 +18,7 @@ void main() { // / \ C=node with checked // C C* *=node removed next pass // - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Semantics( @@ -60,7 +59,7 @@ void main() { // L* LC C=node with checked // *=node removed next pass // - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Semantics( @@ -90,7 +89,7 @@ void main() { // OLC L=node with label // C=node with checked // - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Semantics(), diff --git a/packages/flutter/test/widget/semantics_5_test.dart b/packages/flutter/test/widget/semantics_5_test.dart index dff548c0f1..ceb6759fb6 100644 --- a/packages/flutter/test/widget/semantics_5_test.dart +++ b/packages/flutter/test/widget/semantics_5_test.dart @@ -5,15 +5,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import 'test_semantics.dart'; void main() { - testWidgets('Semantics 5', (WidgetTester tester) { + testWidgets('Semantics 5', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Semantics( diff --git a/packages/flutter/test/widget/semantics_6_test.dart b/packages/flutter/test/widget/semantics_6_test.dart index 1dfe1b7593..0dade7dfda 100644 --- a/packages/flutter/test/widget/semantics_6_test.dart +++ b/packages/flutter/test/widget/semantics_6_test.dart @@ -5,14 +5,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Semantics 6 - SemanticsDebugger smoke test', (WidgetTester tester) { + testWidgets('Semantics 6 - SemanticsDebugger smoke test', (WidgetTester tester) async { // This is a smoketest to verify that adding a debugger doesn't crash. - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Semantics(), @@ -26,7 +25,7 @@ void main() { ) ); - tester.pumpWidget( + await tester.pumpWidget( new SemanticsDebugger( child: new Stack( children: [ diff --git a/packages/flutter/test/widget/semantics_7_test.dart b/packages/flutter/test/widget/semantics_7_test.dart index 4803725583..cb48557e4b 100644 --- a/packages/flutter/test/widget/semantics_7_test.dart +++ b/packages/flutter/test/widget/semantics_7_test.dart @@ -5,19 +5,18 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import 'test_semantics.dart'; import 'package:sky_services/semantics/semantics.mojom.dart' as mojom; void main() { - testWidgets('Semantics 7 - Merging', (WidgetTester tester) { + testWidgets('Semantics 7 - Merging', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); String label; label = '1'; - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new MergeSemantics( @@ -94,7 +93,7 @@ void main() { client.updates.clear(); label = '2'; - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new MergeSemantics( diff --git a/packages/flutter/test/widget/semantics_8_test.dart b/packages/flutter/test/widget/semantics_8_test.dart index bcfb12d15d..b5ec95d973 100644 --- a/packages/flutter/test/widget/semantics_8_test.dart +++ b/packages/flutter/test/widget/semantics_8_test.dart @@ -5,15 +5,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; import 'test_semantics.dart'; void main() { - testWidgets('Semantics 8 - Merging with reset', (WidgetTester tester) { + testWidgets('Semantics 8 - Merging with reset', (WidgetTester tester) async { TestSemanticsListener client = new TestSemanticsListener(); - tester.pumpWidget( + await tester.pumpWidget( new MergeSemantics( child: new Semantics( container: true, @@ -52,7 +51,7 @@ void main() { client.updates.clear(); // switch the order of the inner Semantics node to trigger a reset - tester.pumpWidget( + await tester.pumpWidget( new MergeSemantics( child: new Semantics( container: true, diff --git a/packages/flutter/test/widget/set_state_2_test.dart b/packages/flutter/test/widget/set_state_2_test.dart index 58f11ddbab..a7bd3949ad 100644 --- a/packages/flutter/test/widget/set_state_2_test.dart +++ b/packages/flutter/test/widget/set_state_2_test.dart @@ -4,10 +4,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('setState() overbuild test', (WidgetTester tester) { + testWidgets('setState() overbuild test', (WidgetTester tester) async { List log = []; Builder inner = new Builder( builder: (BuildContext context) { @@ -16,7 +15,7 @@ void main() { } ); int value = 0; - tester.pumpWidget(new Builder( + await tester.pumpWidget(new Builder( builder: (BuildContext context) { log.add('outer'); return new StatefulBuilder( @@ -40,8 +39,8 @@ void main() { } )); log.add('---'); - tester.tap(find.text('inner'));; - tester.pump(); + await tester.tap(find.text('inner'));; + await tester.pump(); log.add('---'); expect(log, equals([ 'outer', diff --git a/packages/flutter/test/widget/set_state_3_test.dart b/packages/flutter/test/widget/set_state_3_test.dart index 2b36030362..4a51346e92 100644 --- a/packages/flutter/test/widget/set_state_3_test.dart +++ b/packages/flutter/test/widget/set_state_3_test.dart @@ -51,10 +51,10 @@ class LeafState extends State { } void main() { - testWidgets('three-way setState() smoke test', (WidgetTester tester) { - tester.pumpWidget(new Changer(new Wrapper(new Leaf()))); - tester.pumpWidget(new Changer(new Wrapper(new Leaf()))); + testWidgets('three-way setState() smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new Changer(new Wrapper(new Leaf()))); + await tester.pumpWidget(new Changer(new Wrapper(new Leaf()))); changer.test(); - tester.pump(); + await tester.pump(); }); } diff --git a/packages/flutter/test/widget/set_state_test.dart b/packages/flutter/test/widget/set_state_test.dart index 54ac8bb8d5..4d4acd0d7c 100644 --- a/packages/flutter/test/widget/set_state_test.dart +++ b/packages/flutter/test/widget/set_state_test.dart @@ -60,12 +60,12 @@ class OutsideState extends State { } void main() { - testWidgets('setState() smoke test', (WidgetTester tester) { - tester.pumpWidget(new Outside()); + testWidgets('setState() smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new Outside()); Point location = tester.getCenter(find.text('INSIDE')); - TestGesture gesture = tester.startGesture(location); - tester.pump(); - gesture.up(); - tester.pump(); + TestGesture gesture = await tester.startGesture(location); + await tester.pump(); + await gesture.up(); + await tester.pump(); }); } diff --git a/packages/flutter/test/widget/shader_mask_test.dart b/packages/flutter/test/widget/shader_mask_test.dart index bdc3a28ad6..92217e4630 100644 --- a/packages/flutter/test/widget/shader_mask_test.dart +++ b/packages/flutter/test/widget/shader_mask_test.dart @@ -18,8 +18,8 @@ Shader createShader(Rect bounds) { void main() { - testWidgets('Can be constructed', (WidgetTester tester) { + testWidgets('Can be constructed', (WidgetTester tester) async { Widget child = new Container(width: 100.0, height: 100.0); - tester.pumpWidget(new ShaderMask(child: child, shaderCallback: createShader)); + await tester.pumpWidget(new ShaderMask(child: child, shaderCallback: createShader)); }); } diff --git a/packages/flutter/test/widget/snap_scrolling_test.dart b/packages/flutter/test/widget/snap_scrolling_test.dart index 49f5954231..98fd8a1014 100644 --- a/packages/flutter/test/widget/snap_scrolling_test.dart +++ b/packages/flutter/test/widget/snap_scrolling_test.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; const double itemExtent = 200.0; Axis scrollDirection = Axis.vertical; @@ -52,58 +51,58 @@ Future fling(double velocity) { } void main() { - testWidgets('ScrollableList snap scrolling, fling(0.8)', (WidgetTester tester) { - tester.pumpWidget(buildFrame()); + testWidgets('ScrollableList snap scrolling, fling(0.8)', (WidgetTester tester) async { + await tester.pumpWidget(buildFrame()); scrollOffset = 0.0; - tester.pump(); + await tester.pump(); expect(scrollOffset, 0.0); Duration dt = const Duration(seconds: 2); fling(0.8); - tester.pump(); // Start the scheduler at 0.0 - tester.pump(dt); + await tester.pump(); // Start the scheduler at 0.0 + await tester.pump(dt); expect(scrollOffset, closeTo(200.0, 1.0)); scrollOffset = 0.0; - tester.pump(); + await tester.pump(); expect(scrollOffset, 0.0); fling(2.0); - tester.pump(); - tester.pump(dt); + await tester.pump(); + await tester.pump(dt); expect(scrollOffset, closeTo(400.0, 1.0)); scrollOffset = 400.0; - tester.pump(); + await tester.pump(); expect(scrollOffset, 400.0); fling(-0.8); - tester.pump(); - tester.pump(dt); + await tester.pump(); + await tester.pump(dt); expect(scrollOffset, closeTo(0.0, 1.0)); scrollOffset = 800.0; - tester.pump(); + await tester.pump(); expect(scrollOffset, 800.0); fling(-2.0); - tester.pump(); - tester.pump(dt); + await tester.pump(); + await tester.pump(dt); expect(scrollOffset, closeTo(200.0, 1.0)); scrollOffset = 800.0; - tester.pump(); + await tester.pump(); expect(scrollOffset, 800.0); bool completed = false; fling(-2.0).then((_) { completed = true; - expect(scrollOffset, closeTo(200.0, 1.0)); + expectSync(scrollOffset, closeTo(200.0, 1.0)); }); - tester.pump(); - tester.pump(dt); + await tester.pump(); + await tester.pump(dt); expect(completed, true); }); } diff --git a/packages/flutter/test/widget/stack_test.dart b/packages/flutter/test/widget/stack_test.dart index 0a09739c53..fd5b2cb094 100644 --- a/packages/flutter/test/widget/stack_test.dart +++ b/packages/flutter/test/widget/stack_test.dart @@ -5,23 +5,22 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; import '../rendering/rendering_tester.dart'; void main() { - testWidgets('Can construct an empty Stack', (WidgetTester tester) { - tester.pumpWidget(new Stack()); + testWidgets('Can construct an empty Stack', (WidgetTester tester) async { + await tester.pumpWidget(new Stack()); }); - testWidgets('Can construct an empty Centered Stack', (WidgetTester tester) { - tester.pumpWidget(new Center(child: new Stack())); + testWidgets('Can construct an empty Centered Stack', (WidgetTester tester) async { + await tester.pumpWidget(new Center(child: new Stack())); }); - testWidgets('Can change position data', (WidgetTester tester) { + testWidgets('Can change position data', (WidgetTester tester) async { Key key = new Key('container'); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -48,7 +47,7 @@ void main() { expect(parentData.width, isNull); expect(parentData.height, isNull); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -73,11 +72,11 @@ void main() { expect(parentData.height, isNull); }); - testWidgets('Can remove parent data', (WidgetTester tester) { + testWidgets('Can remove parent data', (WidgetTester tester) async { Key key = new Key('container'); Container container = new Container(key: key, width: 10.0, height: 10.0); - tester.pumpWidget(new Stack(children: [ new Positioned(left: 10.0, child: container) ])); + await tester.pumpWidget(new Stack(children: [ new Positioned(left: 10.0, child: container) ])); Element containerElement = tester.element(find.byKey(key)); StackParentData parentData; @@ -89,7 +88,7 @@ void main() { expect(parentData.width, isNull); expect(parentData.height, isNull); - tester.pumpWidget(new Stack(children: [ container ])); + await tester.pumpWidget(new Stack(children: [ container ])); containerElement = tester.element(find.byKey(key)); parentData = containerElement.renderObject.parentData; @@ -101,11 +100,11 @@ void main() { expect(parentData.height, isNull); }); - testWidgets('Can align non-positioned children', (WidgetTester tester) { + testWidgets('Can align non-positioned children', (WidgetTester tester) async { Key child0Key = new Key('child0'); Key child1Key = new Key('child1'); - tester.pumpWidget( + await tester.pumpWidget( new Center( child: new Stack( children: [ @@ -126,15 +125,15 @@ void main() { expect(child1RenderObjectParentData.offset, equals(const Offset(5.0, 5.0))); }); - testWidgets('Can construct an empty IndexedStack', (WidgetTester tester) { - tester.pumpWidget(new IndexedStack()); + testWidgets('Can construct an empty IndexedStack', (WidgetTester tester) async { + await tester.pumpWidget(new IndexedStack()); }); - testWidgets('Can construct an empty Centered IndexedStack', (WidgetTester tester) { - tester.pumpWidget(new Center(child: new IndexedStack())); + testWidgets('Can construct an empty Centered IndexedStack', (WidgetTester tester) async { + await tester.pumpWidget(new Center(child: new IndexedStack())); }); - testWidgets('Can construct an IndexedStack', (WidgetTester tester) { + testWidgets('Can construct an IndexedStack', (WidgetTester tester) async { int itemCount = 3; List itemsPainted; @@ -151,20 +150,20 @@ void main() { return new Center(child: new IndexedStack(children: items, index: index)); } - tester.pumpWidget(buildFrame(0)); + await tester.pumpWidget(buildFrame(0)); expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsOneWidget); expect(find.text('2'), findsOneWidget); expect(itemsPainted, equals([0])); - tester.pumpWidget(buildFrame(1)); + await tester.pumpWidget(buildFrame(1)); expect(itemsPainted, equals([1])); - tester.pumpWidget(buildFrame(2)); + await tester.pumpWidget(buildFrame(2)); expect(itemsPainted, equals([2])); }); - testWidgets('Can hit test an IndexedStack', (WidgetTester tester) { + testWidgets('Can hit test an IndexedStack', (WidgetTester tester) async { Key key = new Key('indexedStack'); int itemCount = 3; List itemsTapped; @@ -177,25 +176,25 @@ void main() { return new Center(child: new IndexedStack(children: items, key: key, index: index)); } - tester.pumpWidget(buildFrame(0)); + await tester.pumpWidget(buildFrame(0)); expect(itemsTapped, isEmpty); - tester.tap(find.byKey(key)); + await tester.tap(find.byKey(key)); expect(itemsTapped, [0]); - tester.pumpWidget(buildFrame(2)); + await tester.pumpWidget(buildFrame(2)); expect(itemsTapped, isEmpty); - tester.tap(find.byKey(key)); + await tester.tap(find.byKey(key)); expect(itemsTapped, [2]); }); - testWidgets('Can set width and height', (WidgetTester tester) { + testWidgets('Can set width and height', (WidgetTester tester) async { Key key = new Key('container'); BoxDecoration kBoxDecoration = new BoxDecoration( backgroundColor: new Color(0xFF00FF00) ); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -226,7 +225,7 @@ void main() { expect(renderBox.size.width, equals(11.0)); expect(renderBox.size.height, equals(12.0)); - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( diff --git a/packages/flutter/test/widget/stateful_component_test.dart b/packages/flutter/test/widget/stateful_component_test.dart index 9d534f92aa..005ccf5fff 100644 --- a/packages/flutter/test/widget/stateful_component_test.dart +++ b/packages/flutter/test/widget/stateful_component_test.dart @@ -5,12 +5,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; import 'test_widgets.dart'; void main() { - testWidgets('Stateful widget smoke test', (WidgetTester tester) { + testWidgets('Stateful widget smoke test', (WidgetTester tester) async { void checkTree(BoxDecoration expectedDecoration) { SingleChildRenderObjectElement element = tester.element( @@ -22,7 +21,7 @@ void main() { expect(renderObject.decoration, equals(expectedDecoration)); } - tester.pumpWidget( + await tester.pumpWidget( new FlipWidget( left: new DecoratedBox(decoration: kBoxDecorationA), right: new DecoratedBox(decoration: kBoxDecorationB) @@ -31,7 +30,7 @@ void main() { checkTree(kBoxDecorationA); - tester.pumpWidget( + await tester.pumpWidget( new FlipWidget( left: new DecoratedBox(decoration: kBoxDecorationB), right: new DecoratedBox(decoration: kBoxDecorationA) @@ -42,11 +41,11 @@ void main() { flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); checkTree(kBoxDecorationA); - tester.pumpWidget( + await tester.pumpWidget( new FlipWidget( left: new DecoratedBox(decoration: kBoxDecorationA), right: new DecoratedBox(decoration: kBoxDecorationB) @@ -56,8 +55,8 @@ void main() { checkTree(kBoxDecorationB); }); - testWidgets('Don\'t rebuild subwidgets', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Don\'t rebuild subwidgets', (WidgetTester tester) async { + await tester.pumpWidget( new FlipWidget( key: new Key('rebuild test'), left: new TestBuildCounter(), @@ -69,7 +68,7 @@ void main() { flipStatefulWidget(tester); - tester.pump(); + await tester.pump(); expect(TestBuildCounter.buildCount, equals(1)); }); diff --git a/packages/flutter/test/widget/stateful_components_test.dart b/packages/flutter/test/widget/stateful_components_test.dart index cb05646800..b57ff57a44 100644 --- a/packages/flutter/test/widget/stateful_components_test.dart +++ b/packages/flutter/test/widget/stateful_components_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class InnerWidget extends StatefulWidget { InnerWidget({ Key key }) : super(key: key); @@ -45,7 +44,7 @@ class OuterContainerState extends State { } void main() { - testWidgets('resync stateful widget', (WidgetTester tester) { + testWidgets('resync stateful widget', (WidgetTester tester) async { Key innerKey = new Key('inner'); Key outerKey = new Key('outer'); @@ -54,7 +53,7 @@ void main() { OuterContainer outer1 = new OuterContainer(key: outerKey, child: inner1); OuterContainer outer2; - tester.pumpWidget(outer1); + await tester.pumpWidget(outer1); StatefulElement innerElement = tester.element(find.byKey(innerKey)); InnerWidgetState innerElementState = innerElement.state; @@ -65,7 +64,7 @@ void main() { inner2 = new InnerWidget(key: innerKey); outer2 = new OuterContainer(key: outerKey, child: inner2); - tester.pumpWidget(outer2); + await tester.pumpWidget(outer2); expect(tester.element(find.byKey(innerKey)), equals(innerElement)); expect(innerElement.state, equals(innerElementState)); @@ -77,7 +76,7 @@ void main() { StatefulElement outerElement = tester.element(find.byKey(outerKey)); expect(outerElement.state.config, equals(outer2)); outerElement.state.setState(() {}); - tester.pump(); + await tester.pump(); expect(tester.element(find.byKey(innerKey)), equals(innerElement)); expect(innerElement.state, equals(innerElementState)); diff --git a/packages/flutter/test/widget/syncing_test.dart b/packages/flutter/test/widget/syncing_test.dart index 2b025862e7..0d5c7a33b8 100644 --- a/packages/flutter/test/widget/syncing_test.dart +++ b/packages/flutter/test/widget/syncing_test.dart @@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; class TestWidget extends StatefulWidget { TestWidget({ this.child, this.persistentState, this.syncedState }); @@ -43,8 +42,8 @@ class TestWidgetState extends State { void main() { - testWidgets('no change', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('no change', (WidgetTester tester) async { + await tester.pumpWidget( new Container( child: new Container( child: new TestWidget( @@ -60,7 +59,7 @@ void main() { expect(state.persistentState, equals(1)); expect(state.updates, equals(0)); - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new Container( child: new TestWidget( @@ -74,11 +73,11 @@ void main() { expect(state.persistentState, equals(1)); expect(state.updates, equals(1)); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); }); - testWidgets('remove one', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('remove one', (WidgetTester tester) async { + await tester.pumpWidget( new Container( child: new Container( child: new TestWidget( @@ -94,7 +93,7 @@ void main() { expect(state.persistentState, equals(10)); expect(state.updates, equals(0)); - tester.pumpWidget( + await tester.pumpWidget( new Container( child: new TestWidget( persistentState: 11, @@ -108,18 +107,18 @@ void main() { expect(state.persistentState, equals(11)); expect(state.updates, equals(0)); - tester.pumpWidget(new Container()); + await tester.pumpWidget(new Container()); }); - testWidgets('swap instances around', (WidgetTester tester) { + testWidgets('swap instances around', (WidgetTester tester) async { Widget a = new TestWidget(persistentState: 0x61, syncedState: 0x41, child: new Text('apple')); Widget b = new TestWidget(persistentState: 0x62, syncedState: 0x42, child: new Text('banana')); - tester.pumpWidget(new Column()); + await tester.pumpWidget(new Column()); GlobalKey keyA = new GlobalKey(); GlobalKey keyB = new GlobalKey(); - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( @@ -146,7 +145,7 @@ void main() { expect(second.persistentState, equals(0x62)); expect(second.syncedState, equals(0x42)); - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( @@ -175,7 +174,7 @@ void main() { // now we swap the nodes over // since they are both "old" nodes, they shouldn't sync with each other even though they look alike - tester.pumpWidget( + await tester.pumpWidget( new Column( children: [ new Container( diff --git a/packages/flutter/test/widget/table_test.dart b/packages/flutter/test/widget/table_test.dart index fc8d058299..bdf0bb6339 100644 --- a/packages/flutter/test/widget/table_test.dart +++ b/packages/flutter/test/widget/table_test.dart @@ -5,11 +5,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Table widget - control test', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Table widget - control test', (WidgetTester tester) async { + await tester.pumpWidget( new Table( children: [ new TableRow( @@ -39,8 +38,8 @@ void main() { expect(boxA.size, equals(boxB.size)); }); - testWidgets('Table widget - changing table dimensions', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Table widget - changing table dimensions', (WidgetTester tester) async { + await tester.pumpWidget( new Table( children: [ new TableRow( @@ -65,7 +64,7 @@ void main() { RenderBox boxG1 = tester.renderObject(find.text('G')); expect(boxA1, isNotNull); expect(boxG1, isNotNull); - tester.pumpWidget( + await tester.pumpWidget( new Table( children: [ new TableRow( @@ -89,8 +88,8 @@ void main() { expect(boxG1, isNot(equals(boxG2))); }); - testWidgets('Table widget - repump test', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Table widget - repump test', (WidgetTester tester) async { + await tester.pumpWidget( new Table( children: [ new TableRow( @@ -111,7 +110,7 @@ void main() { ] ) ); - tester.pumpWidget( + await tester.pumpWidget( new Table( children: [ new TableRow( @@ -141,8 +140,8 @@ void main() { expect(boxA.size, equals(boxB.size)); }); - testWidgets('Table widget - intrinsic sizing test', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Table widget - intrinsic sizing test', (WidgetTester tester) async { + await tester.pumpWidget( new Table( defaultColumnWidth: const IntrinsicColumnWidth(), children: [ @@ -174,8 +173,8 @@ void main() { expect(boxA.size.height, equals(boxB.size.height)); }); - testWidgets('Table widget - intrinsic sizing test, resizing', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Table widget - intrinsic sizing test, resizing', (WidgetTester tester) async { + await tester.pumpWidget( new Table( defaultColumnWidth: const IntrinsicColumnWidth(), children: [ @@ -197,7 +196,7 @@ void main() { ] ) ); - tester.pumpWidget( + await tester.pumpWidget( new Table( defaultColumnWidth: const IntrinsicColumnWidth(), children: [ @@ -229,8 +228,8 @@ void main() { expect(boxA.size.height, equals(boxB.size.height)); }); - testWidgets('Table widget - intrinsic sizing test, changing column widths', (WidgetTester tester) { - tester.pumpWidget( + testWidgets('Table widget - intrinsic sizing test, changing column widths', (WidgetTester tester) async { + await tester.pumpWidget( new Table( children: [ new TableRow( @@ -251,7 +250,7 @@ void main() { ] ) ); - tester.pumpWidget( + await tester.pumpWidget( new Table( defaultColumnWidth: const IntrinsicColumnWidth(), children: [ @@ -283,9 +282,9 @@ void main() { expect(boxA.size.height, equals(boxB.size.height)); }); - testWidgets('Table widget - moving test', (WidgetTester tester) { + testWidgets('Table widget - moving test', (WidgetTester tester) async { List contexts = []; - tester.pumpWidget( + await tester.pumpWidget( new Table( children: [ new TableRow( @@ -307,7 +306,7 @@ void main() { ] ) ); - tester.pumpWidget( + await tester.pumpWidget( new Table( children: [ new TableRow( diff --git a/packages/flutter/test/widget/transform_test.dart b/packages/flutter/test/widget/transform_test.dart index 80a51de99e..118782992b 100644 --- a/packages/flutter/test/widget/transform_test.dart +++ b/packages/flutter/test/widget/transform_test.dart @@ -4,12 +4,11 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('Transform origin', (WidgetTester tester) { + testWidgets('Transform origin', (WidgetTester tester) async { bool didReceiveTap = false; - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -50,15 +49,15 @@ void main() { ); expect(didReceiveTap, isFalse); - tester.tapAt(new Point(110.0, 110.0)); + await tester.tapAt(new Point(110.0, 110.0)); expect(didReceiveTap, isFalse); - tester.tapAt(new Point(190.0, 150.0)); + await tester.tapAt(new Point(190.0, 150.0)); expect(didReceiveTap, isTrue); }); - testWidgets('Transform alignment', (WidgetTester tester) { + testWidgets('Transform alignment', (WidgetTester tester) async { bool didReceiveTap = false; - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -99,15 +98,15 @@ void main() { ); expect(didReceiveTap, isFalse); - tester.tapAt(new Point(110.0, 110.0)); + await tester.tapAt(new Point(110.0, 110.0)); expect(didReceiveTap, isFalse); - tester.tapAt(new Point(190.0, 150.0)); + await tester.tapAt(new Point(190.0, 150.0)); expect(didReceiveTap, isTrue); }); - testWidgets('Transform offset + alignment', (WidgetTester tester) { + testWidgets('Transform offset + alignment', (WidgetTester tester) async { bool didReceiveTap = false; - tester.pumpWidget( + await tester.pumpWidget( new Stack( children: [ new Positioned( @@ -149,9 +148,9 @@ void main() { ); expect(didReceiveTap, isFalse); - tester.tapAt(new Point(110.0, 110.0)); + await tester.tapAt(new Point(110.0, 110.0)); expect(didReceiveTap, isFalse); - tester.tapAt(new Point(190.0, 150.0)); + await tester.tapAt(new Point(190.0, 150.0)); expect(didReceiveTap, isTrue); }); } diff --git a/packages/flutter/test/widget/two_level_list_test.dart b/packages/flutter/test/widget/two_level_list_test.dart index 644ef0a0da..2def9cf204 100644 --- a/packages/flutter/test/widget/two_level_list_test.dart +++ b/packages/flutter/test/widget/two_level_list_test.dart @@ -5,10 +5,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; void main() { - testWidgets('TwoLeveList basics', (WidgetTester tester) { + testWidgets('TwoLeveList basics', (WidgetTester tester) async { final Key topKey = new UniqueKey(); final Key sublistKey = new UniqueKey(); final Key bottomKey = new UniqueKey(); @@ -36,7 +35,7 @@ void main() { } }; - tester.pumpWidget(new MaterialApp(routes: routes)); + await tester.pumpWidget(new MaterialApp(routes: routes)); expect(find.text('Top'), findsOneWidget); expect(find.text('Sublist'), findsOneWidget); @@ -52,9 +51,9 @@ void main() { expect(getHeight(topKey), equals(getHeight(sublistKey) - 2.0)); expect(getHeight(bottomKey), equals(getHeight(sublistKey) - 2.0)); - tester.tap(find.text('Sublist')); - tester.pump(const Duration(seconds: 1)); - tester.pump(const Duration(seconds: 1)); + await tester.tap(find.text('Sublist')); + await tester.pump(const Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(find.text('Top'), findsOneWidget); expect(find.text('Sublist'), findsOneWidget); diff --git a/packages/flutter_markdown/test/flutter_markdown_test.dart b/packages/flutter_markdown/test/flutter_markdown_test.dart index 5ad8dbd8ab..c72fcd7ee6 100644 --- a/packages/flutter_markdown/test/flutter_markdown_test.dart +++ b/packages/flutter_markdown/test/flutter_markdown_test.dart @@ -1,8 +1,11 @@ +// Copyright 2016 The Chromium 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_markdown/flutter_markdown.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; import 'package:flutter/material.dart'; void main() { diff --git a/packages/flutter_sprites/test/node_test.dart b/packages/flutter_sprites/test/node_test.dart index 9ccf92e538..b573eb91ae 100644 --- a/packages/flutter_sprites/test/node_test.dart +++ b/packages/flutter_sprites/test/node_test.dart @@ -6,7 +6,6 @@ import 'dart:ui'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_sprites/flutter_sprites.dart'; -import 'package:test/test.dart'; void main() { test("Node - adding and removing children", () { @@ -69,11 +68,11 @@ void main() { expect(child1.spriteBox, isNull); }); - testWidgets("Node - transformations", (WidgetTester tester) { + testWidgets("Node - transformations", (WidgetTester tester) async { const double epsilon = 0.01; NodeWithSize rootNode = new NodeWithSize(const Size(1024.0, 1024.0)); - tester.pumpWidget(new SpriteWidget(rootNode)); + await tester.pumpWidget(new SpriteWidget(rootNode)); // Translations and transformations adding up correctly. Node child0 = new Node(); diff --git a/packages/flutter_test/lib/flutter_test.dart b/packages/flutter_test/lib/flutter_test.dart index b374436ba9..19ad1e68be 100644 --- a/packages/flutter_test/lib/flutter_test.dart +++ b/packages/flutter_test/lib/flutter_test.dart @@ -5,11 +5,15 @@ /// Testing library for flutter, built on top of `package:test`. library flutter_test; +export 'dart:async' show Future; + export 'src/all_elements.dart'; export 'src/binding.dart'; export 'src/controller.dart'; export 'src/finders.dart'; export 'src/matchers.dart'; +export 'src/test_async_utils.dart'; export 'src/service_mocker.dart'; +export 'src/stack_manipulation.dart'; export 'src/test_pointer.dart'; export 'src/widget_tester.dart'; diff --git a/packages/flutter_test/lib/src/binding.dart b/packages/flutter_test/lib/src/binding.dart index ef09dbc490..32cde2a3c4 100644 --- a/packages/flutter_test/lib/src/binding.dart +++ b/packages/flutter_test/lib/src/binding.dart @@ -3,6 +3,8 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:io'; +import 'dart:ui' as ui; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; @@ -12,6 +14,11 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:quiver/testing/async.dart'; import 'package:quiver/time.dart'; +import 'package:test/test.dart' as test_package; +import 'package:vector_math/vector_math_64.dart'; + +import 'test_async_utils.dart'; +import 'stack_manipulation.dart'; /// Enumeration of possible phases to reach in /// [WidgetTester.pumpWidget] and [TestWidgetsFlutterBinding.pump]. @@ -25,13 +32,38 @@ enum EnginePhase { sendSemanticsTree } -class TestWidgetsFlutterBinding extends BindingBase with SchedulerBinding, GestureBinding, ServicesBinding, RendererBinding, WidgetsBinding { - /// Creates and initializes the binding. This constructor is +const Size _kTestViewportSize = const Size(800.0, 600.0); + +/// Base class for bindings used by widgets library tests. +/// +/// The [ensureInitialized] method creates (if necessary) and returns +/// an instance of the appropriate subclass. +/// +/// When using these bindings, certain features are disabled. For +/// example, [timeDilation] is reset to 1.0 on initialization. +abstract class TestWidgetsFlutterBinding extends BindingBase + with SchedulerBinding, + GestureBinding, + ServicesBinding, + RendererBinding, + WidgetsBinding { + /// Creates and initializes the binding. This function is /// idempotent; calling it a second time will just return the /// previously-created instance. + /// + /// This function will use [AutomatedTestWidgetsFlutterBinding] if + /// the test was run using `flutter test`, and + /// [LiveTestWidgetsFlutterBinding] otherwise (e.g. if it was run + /// using `flutter run`). (This is determined by looking at the + /// environment variables for a variable called `FLUTTER_TEST`.) static WidgetsBinding ensureInitialized() { - if (WidgetsBinding.instance == null) - new TestWidgetsFlutterBinding(); + if (WidgetsBinding.instance == null) { + if (Platform.environment.containsKey('FLUTTER_TEST')) { + new AutomatedTestWidgetsFlutterBinding._(); + } else { + new LiveTestWidgetsFlutterBinding._(); + } + } assert(WidgetsBinding.instance is TestWidgetsFlutterBinding); return WidgetsBinding.instance; } @@ -39,65 +71,13 @@ class TestWidgetsFlutterBinding extends BindingBase with SchedulerBinding, Gestu @override void initInstances() { timeDilation = 1.0; // just in case the developer has artificially changed it for development - debugPrint = _synchronousDebugPrint; // TODO(ianh): don't do this when running as 'flutter run' super.initInstances(); } - void _synchronousDebugPrint(String message, { int wrapWidth }) { - if (wrapWidth != null) { - print(message.split('\n').expand((String line) => debugWordWrap(line, wrapWidth)).join('\n')); - } else { - print(message); - } - } + bool get inTest; - FakeAsync get fakeAsync => _fakeAsync; - bool get inTest => fakeAsync != null; - - FakeAsync _fakeAsync; - Clock _clock; - - EnginePhase phase = EnginePhase.sendSemanticsTree; - - // Pump the rendering pipeline up to the given phase. - @override - void beginFrame() { - assert(inTest); - buildOwner.buildDirtyElements(); - _beginFrame(); - buildOwner.finalizeTree(); - } - - // Cloned from RendererBinding.beginFrame() but with early-exit semantics. - void _beginFrame() { - assert(inTest); - assert(renderView != null); - pipelineOwner.flushLayout(); - if (phase == EnginePhase.layout) - return; - pipelineOwner.flushCompositingBits(); - if (phase == EnginePhase.compositingBits) - return; - pipelineOwner.flushPaint(); - if (phase == EnginePhase.paint) - return; - renderView.compositeFrame(); // this sends the bits to the GPU - if (phase == EnginePhase.composite) - return; - if (SemanticsNode.hasListeners) { - pipelineOwner.flushSemantics(); - if (phase == EnginePhase.flushSemantics) - return; - SemanticsNode.sendSemanticsTree(); - } - } - - @override - void dispatchEvent(PointerEvent event, HitTestResult result) { - assert(inTest); - super.dispatchEvent(event, result); - fakeAsync.flushMicrotasks(); - } + /// The default test timeout for tests when using this binding. + test_package.Timeout get defaultTestTimeout; /// Triggers a frame sequence (build/layout/paint/etc), /// then flushes microtasks. @@ -107,25 +87,29 @@ class TestWidgetsFlutterBinding extends BindingBase with SchedulerBinding, Gestu /// /// The supplied EnginePhase is the final phase reached during the pump pass; /// if not supplied, the whole pass is executed. - void pump([ Duration duration, EnginePhase newPhase = EnginePhase.sendSemanticsTree ]) { - assert(inTest); - assert(_clock != null); - if (duration != null) - fakeAsync.elapse(duration); - phase = newPhase; - handleBeginFrame(new Duration( - milliseconds: _clock.now().millisecondsSinceEpoch - )); - fakeAsync.flushMicrotasks(); - } + Future pump([ Duration duration, EnginePhase newPhase = EnginePhase.sendSemanticsTree ]); /// Artificially calls dispatchLocaleChanged on the Widget binding, /// then flushes microtasks. - void setLocale(String languageCode, String countryCode) { - assert(inTest); - Locale locale = new Locale(languageCode, countryCode); - dispatchLocaleChanged(locale); - fakeAsync.flushMicrotasks(); + Future setLocale(String languageCode, String countryCode) { + return TestAsyncUtils.guard(() async { + assert(inTest); + Locale locale = new Locale(languageCode, countryCode); + dispatchLocaleChanged(locale); + return null; + }); + } + + /// Acts as if the application went idle. + /// + /// Runs all remaining microtasks, including those scheduled as a result of + /// running them, until there are no more microtasks scheduled. + /// + /// Does not run timers. May result in an infinite loop or run out of memory + /// if microtasks continue to recursively schedule new microtasks. + Future idle() { + TestAsyncUtils.guardSync(); + return new Future.value(); } /// Returns the exception most recently caught by the Flutter framework. @@ -144,40 +128,30 @@ class TestWidgetsFlutterBinding extends BindingBase with SchedulerBinding, Gestu /// null in that case. dynamic takeException() { assert(inTest); - dynamic result = _pendingException?.exception; - _pendingException = null; + dynamic result = _pendingExceptionDetails?.exception; + _pendingExceptionDetails = null; return result; } - FlutterErrorDetails _pendingException; - FlutterExceptionHandler _oldHandler; - int _exceptionCount; + FlutterExceptionHandler _oldExceptionHandler; + FlutterErrorDetails _pendingExceptionDetails; - /// Called by the [testWidgets] function before a test is executed. - void preTest() { - assert(fakeAsync == null); - assert(_clock == null); - _fakeAsync = new FakeAsync(); - _clock = fakeAsync.getClock(new DateTime.utc(2015, 1, 1)); - _oldHandler = FlutterError.onError; - _exceptionCount = 0; // number of un-taken exceptions - FlutterError.onError = (FlutterErrorDetails details) { - if (_pendingException != null) { - if (_exceptionCount == 0) { - _exceptionCount = 2; - FlutterError.dumpErrorToConsole(_pendingException, forceReport: true); - } else { - _exceptionCount += 1; - } - FlutterError.dumpErrorToConsole(details, forceReport: true); - _pendingException = new FlutterErrorDetails( - exception: 'Multiple exceptions ($_exceptionCount) were detected during the running of the current test, and at least one was unexpected.', - library: 'Flutter test framework' - ); - } else { - _pendingException = details; - } - }; - } + static final Widget _kPreTestMessage = new Center( + child: new Text( + 'Test starting...', + style: const TextStyle(color: const Color(0xFFFF0000)) + ) + ); + + static final Widget _kPostTestMessage = new Center( + child: new Text( + 'Test finished.', + style: const TextStyle(color: const Color(0xFFFF0000)) + ) + ); + + /// Whether to include the output of debugDumpApp() when reporting + /// test failures. + bool showAppDumpInErrors = false; /// Invoke the callback inside a [FakeAsync] scope on which [pump] can /// advance time. @@ -186,13 +160,272 @@ class TestWidgetsFlutterBinding extends BindingBase with SchedulerBinding, Gestu /// /// Called by the [testWidgets] and [benchmarkWidgets] functions to /// run a test. - Future runTest(Future callback()) { + Future runTest(Future callback()); + + /// This is called during test execution before and after the body has been + /// executed. + /// + /// It's used by [AutomatedTestWidgetsFlutterBinding] to drain the microtasks + /// before the final [pump] that happens during test cleanup. + void asyncBarrier() { + TestAsyncUtils.verifyAllScopesClosed(); + } + + Zone _parentZone; + Completer _currentTestCompleter; + + void _testCompletionHandler() { + // This can get called twice, in the case of a Future without listeners failing, and then + // our main future completing. + assert(Zone.current == _parentZone); + assert(_currentTestCompleter != null); + if (_pendingExceptionDetails != null) { + FlutterError.dumpErrorToConsole(_pendingExceptionDetails, forceReport: true); + // test_package.registerException actually just calls the current zone's error handler (that + // is to say, _parentZone's handleUncaughtError function). FakeAsync doesn't add one of those, + // but the test package does, that's how the test package tracks errors. So really we could + // get the same effect here by calling that error handler directly or indeed just throwing. + // However, we call registerException because that's the semantically correct thing... + test_package.registerException('Test failed. See exception logs above.', _EmptyStack.instance); + _pendingExceptionDetails = null; + } + if (!_currentTestCompleter.isCompleted) + _currentTestCompleter.complete(null); + } + + Future _runTest(Future callback()) { assert(inTest); + _oldExceptionHandler = FlutterError.onError; + int _exceptionCount = 0; // number of un-taken exceptions + FlutterError.onError = (FlutterErrorDetails details) { + if (_pendingExceptionDetails != null) { + if (_exceptionCount == 0) { + _exceptionCount = 2; + FlutterError.dumpErrorToConsole(_pendingExceptionDetails, forceReport: true); + } else { + _exceptionCount += 1; + } + FlutterError.dumpErrorToConsole(details, forceReport: true); + _pendingExceptionDetails = new FlutterErrorDetails( + exception: 'Multiple exceptions ($_exceptionCount) were detected during the running of the current test, and at least one was unexpected.', + library: 'Flutter test framework' + ); + } else { + _pendingExceptionDetails = details; + } + }; + _currentTestCompleter = new Completer(); + ZoneSpecification errorHandlingZoneSpecification = new ZoneSpecification( + handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, dynamic exception, StackTrace stack) { + if (_currentTestCompleter.isCompleted) { + // Well this is not a good sign. + // Ideally, once the test has failed we would stop getting errors from the test. + // However, if someone tries hard enough they could get in a state where this happens. + // If we silently dropped these errors on the ground, nobody would ever know. So instead + // we report them to the console. They don't cause test failures, but hopefully someone + // will see them in the logs at some point. + FlutterError.dumpErrorToConsole(new FlutterErrorDetails( + exception: exception, + stack: stack, + context: 'running a test (but after the test had completed)', + library: 'Flutter test framework' + ), forceReport: true); + return; + } + // This is where test failures, e.g. those in expect(), will end up. + // Specifically, runUnaryGuarded() will call this synchronously and + // return our return value if _runTestBody fails synchronously (which it + // won't, so this never happens), and Future will call this when the + // Future completes with an error and it would otherwise call listeners + // if the listener is in a different zone (which it would be for the + // `whenComplete` handler below), or if the Future completes with an + // error and the future has no listeners at all. + // This handler further calls the onError handler above, which sets + // _pendingExceptionDetails. Nothing gets printed as a result of that + // call unless we already had an exception pending, because in general + // we want people to be able to cause the framework to report exceptions + // and then use takeException to verify that they were really caught. + // Now, if we actually get here, this isn't going to be one of those + // cases. We only get here if the test has actually failed. So, once + // we've carefully reported it, we then immediately end the test by + // calling the _testCompletionHandler in the _parentZone. + // We have to manually call _testCompletionHandler because if the Future + // library calls us, it is maybe _instead_ of calling a registered + // listener from a different zone. In our case, that would be instead of + // calling the whenComplete() listener below. + // We have to call it in the parent zone because if we called it in + // _this_ zone, the test framework would find this zone was the current + // zone and helpfully throw the error in this zone, causing us to be + // directly called again. + final String treeDump = renderViewElement?.toStringDeep() ?? ''; + final StringBuffer expectLine = new StringBuffer(); + final int stackLinesToOmit = reportExpectCall(stack, expectLine); + FlutterError.reportError(new FlutterErrorDetails( + exception: exception, + stack: stack, + context: 'running a test', + library: 'Flutter test framework', + stackFilter: (List frames) { + return FlutterError.defaultStackFilter(frames.skip(stackLinesToOmit)); + }, + informationCollector: (StringBuffer information) { + if (stackLinesToOmit > 0) + information.writeln(expectLine.toString()); + if (showAppDumpInErrors) { + information.writeln('At the time of the failure, the widget tree looked as follows:'); + information.writeln('# ${treeDump.split("\n").takeWhile((String s) => s != "").join("\n# ")}'); + } + } + )); + assert(_parentZone != null); + assert(_pendingExceptionDetails != null); + _parentZone.run(_testCompletionHandler); + } + ); + _parentZone = Zone.current; + Zone testZone = _parentZone.fork(specification: errorHandlingZoneSpecification); + testZone.runUnaryGuarded(_runTestBody, callback) + .whenComplete(_testCompletionHandler); + asyncBarrier(); // When using AutomatedTestWidgetsFlutterBinding, this flushes the microtasks. + return _currentTestCompleter.future; + } + + Future _runTestBody(Future callback()) async { + assert(inTest); + + runApp(new Container(key: new UniqueKey(), child: _kPreTestMessage)); // Reset the tree to a known state. + await pump(); + + // run the test + await callback(); + asyncBarrier(); // drains the microtasks in `flutter test` mode (when using AutomatedTestWidgetsFlutterBinding) + + if (_pendingExceptionDetails == null) { + // We only try to clean up and verify invariants if we didn't already + // fail. If we got an exception already, then we instead leave everything + // alone so that we don't cause more spurious errors. + runApp(new Container(key: new UniqueKey(), child: _kPostTestMessage)); // Unmount any remaining widgets. + await pump(); + _verifyInvariants(); + } + + assert(inTest); + return null; + } + + void _verifyInvariants() { + assert(debugAssertNoTransientCallbacks( + 'An animation is still running even after the widget tree was disposed.' + )); + } + + /// Called by the [testWidgets] function after a test is executed. + void postTest() { + assert(inTest); + FlutterError.onError = _oldExceptionHandler; + _pendingExceptionDetails = null; + _currentTestCompleter = null; + _parentZone = null; + } +} + +/// A variant of [TestWidgetsFlutterBinding] for executing tests in +/// the `flutter test` environment. +/// +/// This binding controls time, allowing tests to verify long +/// animation sequences without having to execute them in real time. +class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { + AutomatedTestWidgetsFlutterBinding._(); + + @override + void initInstances() { + debugPrint = _synchronousDebugPrint; + super.initInstances(); + ui.window.onBeginFrame = null; + } + + void _synchronousDebugPrint(String message, { int wrapWidth }) { + if (wrapWidth != null) { + print(message.split('\n').expand((String line) => debugWordWrap(line, wrapWidth)).join('\n')); + } else { + print(message); + } + } + + FakeAsync _fakeAsync; + Clock _clock; + + @override + test_package.Timeout get defaultTestTimeout => const test_package.Timeout(const Duration(seconds: 5)); + + @override + bool get inTest => _fakeAsync != null; + + @override + Future pump([ Duration duration, EnginePhase newPhase = EnginePhase.sendSemanticsTree ]) { + return TestAsyncUtils.guard(() { + assert(inTest); + assert(_clock != null); + if (duration != null) + _fakeAsync.elapse(duration); + _phase = newPhase; + if (hasScheduledFrame) { + handleBeginFrame(new Duration( + milliseconds: _clock.now().millisecondsSinceEpoch + )); + } + _fakeAsync.flushMicrotasks(); + return new Future.value(); + }); + } + + @override + Future idle() { + Future result = super.idle(); + _fakeAsync.flushMicrotasks(); + return result; + } + + EnginePhase _phase = EnginePhase.sendSemanticsTree; + + // Cloned from RendererBinding.beginFrame() but with early-exit semantics. + @override + void beginFrame() { + assert(inTest); + buildOwner.buildDirtyElements(); + assert(renderView != null); + pipelineOwner.flushLayout(); + if (_phase == EnginePhase.layout) + return; + pipelineOwner.flushCompositingBits(); + if (_phase == EnginePhase.compositingBits) + return; + pipelineOwner.flushPaint(); + if (_phase == EnginePhase.paint) + return; + renderView.compositeFrame(); // this sends the bits to the GPU + if (_phase == EnginePhase.composite) + return; + if (SemanticsNode.hasListeners) { + pipelineOwner.flushSemantics(); + if (_phase == EnginePhase.flushSemantics) + return; + SemanticsNode.sendSemanticsTree(); + } + buildOwner.finalizeTree(); + } + + @override + Future runTest(Future callback()) { + assert(!inTest); + assert(_fakeAsync == null); + assert(_clock == null); + _fakeAsync = new FakeAsync(); + _clock = _fakeAsync.getClock(new DateTime.utc(2015, 1, 1)); Future callbackResult; - fakeAsync.run((FakeAsync fakeAsync) { - assert(fakeAsync == this.fakeAsync); + _fakeAsync.run((FakeAsync fakeAsync) { + assert(fakeAsync == _fakeAsync); callbackResult = _runTest(callback); - fakeAsync.flushMicrotasks(); assert(inTest); }); // callbackResult is a Future that was created in the Zone of the fakeAsync. @@ -203,64 +436,188 @@ class TestWidgetsFlutterBinding extends BindingBase with SchedulerBinding, Gestu return new Future.value(callbackResult); } - Future _runTest(Future callback()) async { - assert(inTest); - - runApp(new Container(key: new UniqueKey())); // Reset the tree to a known state. - pump(); - - // run the test - try { - await callback(); - fakeAsync.flushMicrotasks(); - } catch (exception, stack) { - // call onError handler above - FlutterError.reportError(new FlutterErrorDetails( - exception: exception, - stack: stack, - library: 'Flutter test framework' - )); - } - - runApp(new Container(key: new UniqueKey())); // Unmount any remaining widgets. - pump(); - - // verify invariants - assert(debugAssertNoTransientCallbacks( - 'An animation is still running even after the widget tree was disposed.' - )); - assert(() { - 'A Timer is still running even after the widget tree was disposed.'; - return fakeAsync.periodicTimerCount == 0; - }); - assert(() { - 'A Timer is still running even after the widget tree was disposed.'; - return fakeAsync.nonPeriodicTimerCount == 0; - }); - assert(fakeAsync.microtaskCount == 0); // Shouldn't be possible. - - // check for unexpected exceptions - if (_pendingException != null) { - if (_exceptionCount > 1) - throw 'Test failed. See exception logs above.'; - throw 'Test failed. See exception log below.'; - } - - assert(inTest); - return null; + @override + void asyncBarrier() { + assert(_fakeAsync != null); + _fakeAsync.flushMicrotasks(); + super.asyncBarrier(); } - /// Called by the [testWidgets] function after a test is executed. + @override + void _verifyInvariants() { + super._verifyInvariants(); + assert(() { + 'A Timer is still running even after the widget tree was disposed.'; + return _fakeAsync.periodicTimerCount == 0; + }); + assert(() { + 'A Timer is still running even after the widget tree was disposed.'; + return _fakeAsync.nonPeriodicTimerCount == 0; + }); + assert(_fakeAsync.microtaskCount == 0); // Shouldn't be possible. + } + + @override void postTest() { + super.postTest(); assert(_fakeAsync != null); assert(_clock != null); - FlutterError.onError = _oldHandler; - if (_pendingException != null) - FlutterError.dumpErrorToConsole(_pendingException, forceReport: true); - _pendingException = null; - _exceptionCount = null; _clock = null; _fakeAsync = null; } } + +/// A variant of [TestWidgetsFlutterBinding] for executing tests in +/// the `flutter run` environment, on a device. This is intended to +/// allow interactive test development. +/// +/// This is not the way to run a remote-control test. To run a test on +/// a device from a development computer, see the [flutter_driver] +/// package and the `flutter drive` command. +/// +/// This binding overrides the default [SchedulerBinding] behavior to +/// ensure that tests work in the same way in this environment as they +/// would under the [AutomatedTestWidgetsFlutterBinding]. To override +/// this (and see intermediate frames that the test does not +/// explicitly trigger), set [allowAllFrames] to true. (This is likely +/// to make tests fail, though, especially if e.g. they test how many +/// times a particular widget was built.) +/// +/// This binding does not support the [EnginePhase] argument to +/// [pump]. (There would be no point setting it to a value that +/// doesn't trigger a paint, since then you could not see anything +/// anyway.) +class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { + LiveTestWidgetsFlutterBinding._(); + + @override + bool get inTest => _inTest; + bool _inTest = false; + + @override + test_package.Timeout get defaultTestTimeout => test_package.Timeout.none; + + Completer _pendingFrame; + bool _expectingFrame = false; + + /// Whether to have [pump] with a duration only pump a single frame + /// (as would happen in a normal test environment using + /// [AutomatedTestWidgetsFlutterBinding]), or whether to instead + /// pump every frame that the system requests during any + /// asynchronous pause in the test (as would normally happen when + /// running an application with [WidgetsFlutterBinding]). + /// + /// `false` is the default behavior, which is to only pump once. + /// + /// `true` allows all frame requests from the engine to be serviced. + /// + /// Setting this to `true` means pumping extra frames, which might + /// involve calling builders more, or calling paint callbacks more, + /// etc, which might interfere with the test. If you know your test + /// file wouldn't be affected by this, you can set it to true + /// persistently in that particular test file. To set this to `true` + /// while still allowing the test file to work as a normal test, add + /// the following code to your test file at the top of your `void + /// main() { }` function, before calls to `testWidgets`: + /// + /// ```dart + /// TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized(); + /// if (binding is LiveTestWidgetsFlutterBinding) + /// binding.allowAllFrames = true; + /// ``` + bool allowAllFrames = false; + + @override + void handleBeginFrame(Duration rawTimeStamp) { + if (_expectingFrame || allowAllFrames) + super.handleBeginFrame(rawTimeStamp); + if (_expectingFrame) { + assert(_pendingFrame != null); + _pendingFrame.complete(); // unlocks the test API + _pendingFrame = null; + _expectingFrame = false; + } else { + ui.window.scheduleFrame(); + } + } + + @override + Future pump([ Duration duration, EnginePhase newPhase = EnginePhase.sendSemanticsTree ]) { + assert(newPhase == EnginePhase.sendSemanticsTree); + assert(inTest); + assert(!_expectingFrame); + assert(_pendingFrame == null); + return TestAsyncUtils.guard(() { + if (duration != null) { + new Timer(duration, () { + _expectingFrame = true; + scheduleFrame(); + }); + } else { + _expectingFrame = true; + scheduleFrame(); + } + _pendingFrame = new Completer(); + return _pendingFrame.future; + }); + } + + @override + Future runTest(Future callback()) async { + assert(!inTest); + _inTest = true; + return _runTest(callback); + } + + @override + void postTest() { + super.postTest(); + assert(!_expectingFrame); + assert(_pendingFrame == null); + _inTest = false; + } + + @override + ViewConfiguration createViewConfiguration() { + final double actualWidth = ui.window.size.width * ui.window.devicePixelRatio; + final double actualHeight = ui.window.size.height * ui.window.devicePixelRatio; + final double desiredWidth = _kTestViewportSize.width; + final double desiredHeight = _kTestViewportSize.height; + double scale, shiftX, shiftY; + if ((actualWidth / actualHeight) > (desiredWidth / desiredHeight)) { + scale = actualHeight / desiredHeight; + shiftX = (actualWidth - desiredWidth * scale) / 2.0; + shiftY = 0.0; + } else { + scale = actualWidth / desiredWidth; + shiftX = 0.0; + shiftY = (actualHeight - desiredHeight * scale) / 2.0; + } + final Matrix4 matrix = new Matrix4.compose( + new Vector3(shiftX, shiftY, 0.0), // translation + new Quaternion.identity(), // rotation + new Vector3(scale, scale, 0.0) // scale + ); + return new _TestViewConfiguration(matrix); + } +} + +class _TestViewConfiguration extends ViewConfiguration { + _TestViewConfiguration(this.matrix) : super(size: _kTestViewportSize); + + final Matrix4 matrix; + + @override + Matrix4 toMatrix() => matrix; + + @override + String toString() => 'TestViewConfiguration'; +} + +class _EmptyStack implements StackTrace { + const _EmptyStack._(); + static const _EmptyStack instance = const _EmptyStack._(); + @override + String toString() => ''; +} \ No newline at end of file diff --git a/packages/flutter_test/lib/src/controller.dart b/packages/flutter_test/lib/src/controller.dart index 6ac2528d3d..f75f952f19 100644 --- a/packages/flutter_test/lib/src/controller.dart +++ b/packages/flutter_test/lib/src/controller.dart @@ -2,13 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:flutter/gestures.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'test_pointer.dart'; -import 'finders.dart'; import 'all_elements.dart'; +import 'finders.dart'; +import 'test_async_utils.dart'; +import 'test_pointer.dart'; /// Class that programmatically interacts with widgets. /// @@ -24,13 +27,17 @@ class WidgetController { // a good message otherwise, in all the generic methods below /// Checks if `finder` exists in the tree. - bool any(Finder finder) => finder.evaluate().isNotEmpty; + bool any(Finder finder) { + TestAsyncUtils.guardSync(); + return finder.evaluate().isNotEmpty; + } /// All widgets currently in the widget tree (lazy pre-order traversal). /// /// Can contain duplicates, since widgets can be used in multiple /// places in the widget tree. Iterable get allWidgets { + TestAsyncUtils.guardSync(); return allElements .map((Element element) => element.widget); } @@ -40,6 +47,7 @@ class WidgetController { /// Throws a [StateError] if `finder` is empty or matches more than /// one widget. Widget/*=T*/ widget/**/(Finder finder) { + TestAsyncUtils.guardSync(); return finder.evaluate().single.widget; } @@ -48,6 +56,7 @@ class WidgetController { /// /// Throws a [StateError] if `finder` is empty. Widget/*=T*/ firstWidget/**/(Finder finder) { + TestAsyncUtils.guardSync(); return finder.evaluate().first.widget; } @@ -57,6 +66,7 @@ class WidgetController { /// immediately, but rather a chunk at a time as the iteration progresses /// using [Iterator.moveNext]. Iterable get allElements { + TestAsyncUtils.guardSync(); return collectAllElementsFrom(binding.renderViewElement); } @@ -65,6 +75,7 @@ class WidgetController { /// Throws a [StateError] if `finder` is empty or matches more than /// one element. Element/*=T*/ element/**/(Finder finder) { + TestAsyncUtils.guardSync(); return finder.evaluate().single; } @@ -73,6 +84,7 @@ class WidgetController { /// /// Throws a [StateError] if `finder` is empty. Element/*=T*/ firstElement/**/(Finder finder) { + TestAsyncUtils.guardSync(); return finder.evaluate().first; } @@ -82,6 +94,7 @@ class WidgetController { /// immediately, but rather a chunk at a time as the iteration progresses /// using [Iterator.moveNext]. Iterable get allStates { + TestAsyncUtils.guardSync(); return allElements .where((Element element) => element is StatefulElement) .map((StatefulElement element) => element.state); @@ -92,6 +105,7 @@ class WidgetController { /// Throws a [StateError] if `finder` is empty, matches more than /// one state, or matches a widget that has no state. State/*=T*/ state/**/(Finder finder) { + TestAsyncUtils.guardSync(); return _stateOf/**/(finder.evaluate().single, finder); } @@ -101,10 +115,12 @@ class WidgetController { /// Throws a [StateError] if `finder` is empty or if the first /// matching widget has no state. State/*=T*/ firstState/**/(Finder finder) { + TestAsyncUtils.guardSync(); return _stateOf/**/(finder.evaluate().first, finder); } State/*=T*/ _stateOf/**/(Element element, Finder finder) { + TestAsyncUtils.guardSync(); if (element is StatefulElement) return element.state; throw new StateError('Widget of type ${element.widget.runtimeType}, with ${finder.description}, is not a StatefulWidget.'); @@ -118,6 +134,7 @@ class WidgetController { /// render object of its child; only [RenderObjectWidget]s have /// their own render object. Iterable get allRenderObjects { + TestAsyncUtils.guardSync(); return allElements .map((Element element) => element.renderObject); } @@ -127,6 +144,7 @@ class WidgetController { /// Throws a [StateError] if `finder` is empty or matches more than /// one widget (even if they all have the same render object). RenderObject/*=T*/ renderObject/**/(Finder finder) { + TestAsyncUtils.guardSync(); return finder.evaluate().single.renderObject; } @@ -135,6 +153,7 @@ class WidgetController { /// /// Throws a [StateError] if `finder` is empty. RenderObject/*=T*/ firstRenderObject/**/(Finder finder) { + TestAsyncUtils.guardSync(); return finder.evaluate().first.renderObject; } @@ -142,6 +161,7 @@ class WidgetController { /// Returns a list of all the [Layer] objects in the rendering. List get layers => _walkLayers(binding.renderView.layer).toList(); Iterable _walkLayers(Layer layer) sync* { + TestAsyncUtils.guardSync(); yield layer; if (layer is ContainerLayer) { ContainerLayer root = layer; @@ -160,15 +180,18 @@ class WidgetController { /// the given widget, assuming it is exposed. If the center of the /// widget is not exposed, this might send events to another /// object. - void tap(Finder finder, { int pointer: 1 }) { - tapAt(getCenter(finder), pointer: pointer); + Future tap(Finder finder, { int pointer: 1 }) { + return tapAt(getCenter(finder), pointer: pointer); } /// Dispatch a pointer down / pointer up sequence at the given /// location. - void tapAt(Point location, { int pointer: 1 }) { - startGesture(location, pointer: pointer) - ..up(); + Future tapAt(Point location, { int pointer: 1 }) { + return TestAsyncUtils.guard(() async { + TestGesture gesture = await startGesture(location, pointer: pointer); + await gesture.up(); + return null; + }); } /// Attempts a fling gesture starting from the center of the given @@ -176,27 +199,30 @@ class WidgetController { /// /// If the middle of the widget is not exposed, this might send /// events to another object. - void fling(Finder finder, Offset offset, double velocity, { int pointer: 1 }) { - flingFrom(getCenter(finder), offset, velocity, pointer: pointer); + Future fling(Finder finder, Offset offset, double velocity, { int pointer: 1 }) { + return flingFrom(getCenter(finder), offset, velocity, pointer: pointer); } /// Attempts a fling gesture starting from the given location, /// moving the given distance, reaching the given velocity. - void flingFrom(Point startLocation, Offset offset, double velocity, { int pointer: 1 }) { - assert(offset.distance > 0.0); - assert(velocity != 0.0); // velocity is pixels/second - final TestPointer p = new TestPointer(pointer); - final HitTestResult result = _hitTest(startLocation); - const int kMoveCount = 50; // Needs to be >= kHistorySize, see _LeastSquaresVelocityTrackerStrategy - final double timeStampDelta = 1000.0 * offset.distance / (kMoveCount * velocity); - double timeStamp = 0.0; - binding.dispatchEvent(p.down(startLocation, timeStamp: new Duration(milliseconds: timeStamp.round())), result); - for (int i = 0; i <= kMoveCount; i++) { - final Point location = startLocation + Offset.lerp(Offset.zero, offset, i / kMoveCount); - binding.dispatchEvent(p.move(location, timeStamp: new Duration(milliseconds: timeStamp.round())), result); - timeStamp += timeStampDelta; - } - binding.dispatchEvent(p.up(timeStamp: new Duration(milliseconds: timeStamp.round())), result); + Future flingFrom(Point startLocation, Offset offset, double velocity, { int pointer: 1 }) { + return TestAsyncUtils.guard(() async { + assert(offset.distance > 0.0); + assert(velocity != 0.0); // velocity is pixels/second + final TestPointer p = new TestPointer(pointer); + final HitTestResult result = _hitTest(startLocation); + const int kMoveCount = 50; // Needs to be >= kHistorySize, see _LeastSquaresVelocityTrackerStrategy + final double timeStampDelta = 1000.0 * offset.distance / (kMoveCount * velocity); + double timeStamp = 0.0; + await _dispatchEvent(p.down(startLocation, timeStamp: new Duration(milliseconds: timeStamp.round())), result); + for (int i = 0; i <= kMoveCount; i++) { + final Point location = startLocation + Offset.lerp(Offset.zero, offset, i / kMoveCount); + await _dispatchEvent(p.move(location, timeStamp: new Duration(milliseconds: timeStamp.round())), result); + timeStamp += timeStampDelta; + } + await _dispatchEvent(p.up(timeStamp: new Duration(milliseconds: timeStamp.round())), result); + return null; + }); } /// Attempts to drag the given widget by the given offset, by @@ -204,22 +230,25 @@ class WidgetController { /// /// If the middle of the widget is not exposed, this might send /// events to another object. - void scroll(Finder finder, Offset offset, { int pointer: 1 }) { - scrollAt(getCenter(finder), offset, pointer: pointer); + Future scroll(Finder finder, Offset offset, { int pointer: 1 }) { + return scrollAt(getCenter(finder), offset, pointer: pointer); } /// Attempts a drag gesture consisting of a pointer down, a move by /// the given offset, and a pointer up. - void scrollAt(Point startLocation, Offset offset, { int pointer: 1 }) { - startGesture(startLocation, pointer: pointer) - ..moveBy(offset) - ..up(); + Future scrollAt(Point startLocation, Offset offset, { int pointer: 1 }) { + return TestAsyncUtils.guard(() async { + TestGesture gesture = await startGesture(startLocation, pointer: pointer); + await gesture.moveBy(offset); + await gesture.up(); + return null; + }); } /// Begins a gesture at a particular point, and returns the /// [TestGesture] object which you can use to continue the gesture. - TestGesture startGesture(Point downLocation, { int pointer: 1 }) { - return new TestGesture(downLocation, pointer: pointer); + Future startGesture(Point downLocation, { int pointer: 1 }) { + return TestGesture.down(downLocation, pointer: pointer, dispatcher: _dispatchEvent); } HitTestResult _hitTest(Point location) { @@ -228,6 +257,11 @@ class WidgetController { return result; } + Future _dispatchEvent(PointerEvent event, HitTestResult result) { + binding.dispatchEvent(event, result); + return new Future.value(); + } + // GEOMETRY @@ -260,6 +294,7 @@ class WidgetController { } Point _getElementPoint(Finder finder, Point sizeToPoint(Size size)) { + TestAsyncUtils.guardSync(); Element element = finder.evaluate().single; RenderBox box = element.renderObject; assert(box != null); @@ -269,6 +304,7 @@ class WidgetController { /// Returns the size of the given widget. This is only valid once /// the widget's render object has been laid out at least once. Size getSize(Finder finder) { + TestAsyncUtils.guardSync(); Element element = finder.evaluate().single; RenderBox box = element.renderObject; assert(box != null); diff --git a/packages/flutter_test/lib/src/stack_manipulation.dart b/packages/flutter_test/lib/src/stack_manipulation.dart new file mode 100644 index 0000000000..d4ac0508f9 --- /dev/null +++ b/packages/flutter_test/lib/src/stack_manipulation.dart @@ -0,0 +1,31 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// See also test_async_utils.dart which has some stack manipulation code. + +/// Report call site for `expect()` call. Returns the number of frames that +/// should be elided if a stack were to be modified to hide the expect call, or +/// zero if no such call was found. +/// +/// If the head of the stack trace consists of a failure as a result of calling +/// the test_widgets [expect] function, this will fill the given StringBuffer +/// with the precise file and line number that called that function. +int reportExpectCall(StackTrace stack, StringBuffer information) { + final RegExp line0 = new RegExp(r'^#0 +fail \(.+\)$'); + final RegExp line1 = new RegExp(r'^#1 +expect \(.+\)$'); + final RegExp line2 = new RegExp(r'^#2 +expect \(.+\)$'); + final RegExp line3 = new RegExp(r'^#3 +[^(]+ \((.+):([0-9]+):[0-9]+\)$'); + final List stackLines = stack.toString().split('\n'); + if (line0.firstMatch(stackLines[0]) != null && + line1.firstMatch(stackLines[1]) != null && + line2.firstMatch(stackLines[2]) != null) { + Match expectMatch = line3.firstMatch(stackLines[3]); + assert(expectMatch != null); + assert(expectMatch.groupCount == 2); + information.writeln('This was caught by the test expectation on the following line:'); + information.writeln(' ${expectMatch.group(1)} line ${expectMatch.group(2)}'); + return 3; + } + return 0; +} \ No newline at end of file diff --git a/packages/flutter_test/lib/src/test_async_utils.dart b/packages/flutter_test/lib/src/test_async_utils.dart new file mode 100644 index 0000000000..408ea49e85 --- /dev/null +++ b/packages/flutter_test/lib/src/test_async_utils.dart @@ -0,0 +1,326 @@ +// Copyright 2016 The Chromium 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 'dart:async'; + +import 'package:flutter/foundation.dart'; + +class _AsyncScope { + _AsyncScope(this.creationStack, this.zone); + final StackTrace creationStack; + final Zone zone; +} + +/// Utility class for all the async APIs in the `flutter_test` library. +/// +/// This class provides checking for asynchronous APIs, allowing the library to +/// verify that all the asynchronous APIs are properly `await`ed before calling +/// another. +/// +/// For example, it prevents this kind of code: +/// +/// ```dart +/// tester.pump(); // forgot to call "await"! +/// tester.pump(); +/// ``` +/// +/// ...by detecting, in the second call to `pump`, that it should actually be: +/// +/// ```dart +/// await tester.pump(); +/// await tester.pump(); +/// ``` +/// +/// It does this while still allowing nested calls, e.g. so that you can +/// invoke [expect] from inside callbacks. +/// +/// You can use this in your own test functions, if you have some asynchronous +/// functions that must be used with "await". Wrap the contents of the function +/// in a call to TestAsyncUtils.guard(), as follows: +/// +/// ```dart +/// Future myTestFunction() => TestAsyncUtils.guard(() async { +/// // ... +/// }); +/// ``` +class TestAsyncUtils { + TestAsyncUtils._(); + static const String _className = 'TestAsyncUtils'; + + static List<_AsyncScope> _scopeStack = <_AsyncScope>[]; + + /// Invokes the given callback in a new async scope. The callback argument is + /// the asynchronous body of the calling method. The calling method is said to + /// be "guarded". Nested calls to guarded methods from within the body of this + /// one are fine, but calls to other guarded methods from outside the body of + /// this one before this one has finished will throw an exception. + /// + /// This method first calls [guardSync]. + static Future guard(Future body()) { + guardSync(); + Zone zone = Zone.current.fork( + zoneValues: { + _scopeStack: true // so we can recognize this as our own zone + } + ); + _AsyncScope scope = new _AsyncScope(StackTrace.current, zone); + _scopeStack.add(scope); + Future result = scope.zone.run(body); + result = result.whenComplete(() { + assert(_scopeStack.isNotEmpty); + assert(_scopeStack.contains(scope)); + bool leaked = false; + _AsyncScope closedScope; + StringBuffer message = new StringBuffer(); + while (_scopeStack.isNotEmpty) { + closedScope = _scopeStack.removeLast(); + if (closedScope == scope) + break; + leaked = true; + message.writeln('Asynchronous call to guarded function leaked. You must use "await" with all Future-returning test APIs.'); + final _StackEntry originalGuarder = _findResponsibleMethod(closedScope.creationStack, 'guard', message); + if (originalGuarder != null) { + message.writeln( + 'The test API method "${originalGuarder.methodName}" ' + 'from class ${originalGuarder.className} ' + 'was called from ${originalGuarder.callerFile} ' + 'on line ${originalGuarder.callerLine}, ' + 'but never completed before its parent scope closed.' + ); + } + } + if (leaked) + throw new FlutterError(message.toString().trimRight()); + }); + return result; + } + + static Zone get _currentScopeZone { + Zone zone = Zone.current; + while (zone != null) { + if (zone[_scopeStack] == true) + return zone; + zone = zone.parent; + } + return null; + } + + /// Verifies that there are no guarded methods currently pending (see [guard]). + /// + /// If a guarded method is currently pending, and this is not a call nested + /// from inside that method's body (directly or indirectly), then this method + /// will throw a detailed exception. + static void guardSync() { + if (_scopeStack.isEmpty) { + // No scopes open, so we must be fine. + return; + } + // Find the current TestAsyncUtils scope zone so we can see if it's the one we expect. + final Zone zone = _currentScopeZone; + if (zone == _scopeStack.last.zone) { + // We're still in the current scope zone. All good. + return; + } + // If we get here, we know we've got a conflict on our hands. + // We got an async barrier, but the current zone isn't the last scope that + // we pushed on the stack. + // Find which scope the conflict happened in, so that we know + // which stack trace to report the conflict as starting from. + // + // For example, if we called an async method A, which ran its body in a + // guarded block, and in its body it ran an async method B, which ran its + // body in a guarded block, but we didn't await B, then in A's block we ran + // an async method C, which ran its body in a guarded block, then we should + // complain about the call to B then the call to C. BUT. If we called an async + // method A, which ran its body in a guarded block, and in its body it ran + // an async method B, which ran its body in a guarded block, but we didn't + // await A, and then at the top level we called a method D, then we should + // complain about the call to A then the call to D. + // + // In both examples, the scope stack would have two scopes. In the first + // example, the current zone would be the zone of the _scopeStack[0] scope, + // and we would want to show _scopeStack[1]'s creationStack. In the second + // example, the current zone would not be in the _scopeStack, and we would + // want to show _scopeStack[0]'s creationStack. + int skipCount = 0; + _AsyncScope candidateScope = _scopeStack.last; + _AsyncScope scope; + do { + skipCount += 1; + scope = candidateScope; + candidateScope = skipCount < _scopeStack.length ? _scopeStack[_scopeStack.length - skipCount - 1] : null; + } while (candidateScope?.zone != zone); + assert(scope != null); + StringBuffer message = new StringBuffer(); + message.writeln('Guarded function conflict. You must use "await" with all Future-returning test APIs.'); + final _StackEntry originalGuarder = _findResponsibleMethod(scope.creationStack, 'guard', message); + final _StackEntry collidingGuarder = _findResponsibleMethod(StackTrace.current, 'guardSync', message); + if (originalGuarder != null && collidingGuarder != null) { + String originalName; + if (originalGuarder.className == null) { + originalName = '(${originalGuarder.methodName}) '; + message.writeln( + 'The guarded "${originalGuarder.methodName}" function ' + 'was called from ${originalGuarder.callerFile} ' + 'on line ${originalGuarder.callerLine}.' + ); + } else { + originalName = '(${originalGuarder.className}.${originalGuarder.methodName}) '; + message.writeln( + 'The guarded method "${originalGuarder.methodName}" ' + 'from class ${originalGuarder.className} ' + 'was called from ${originalGuarder.callerFile} ' + 'on line ${originalGuarder.callerLine}.' + ); + } + final String again = (originalGuarder.callerFile == collidingGuarder.callerFile) && + (originalGuarder.callerLine == collidingGuarder.callerLine) ? + 'again ' : ''; + String collidingName; + if ((originalGuarder.className == collidingGuarder.className) && + (originalGuarder.methodName == collidingGuarder.methodName)) { + originalName = ''; + collidingName = ''; + message.writeln( + 'Then, it ' + 'was called ${again}from ${collidingGuarder.callerFile} ' + 'on line ${collidingGuarder.callerLine}.' + ); + } else if (collidingGuarder.className == null) { + collidingName = '(${collidingGuarder.methodName}) '; + message.writeln( + 'Then, the "${collidingGuarder.methodName}" function ' + 'was called ${again}from ${collidingGuarder.callerFile} ' + 'on line ${collidingGuarder.callerLine}.' + ); + } else { + collidingName = '(${collidingGuarder.className}.${collidingGuarder.methodName}) '; + message.writeln( + 'Then, the "${collidingGuarder.methodName}" method ' + '${originalGuarder.className == collidingGuarder.className ? "(also from class ${collidingGuarder.className})" + : "from class ${collidingGuarder.className}"} ' + 'was called ${again}from ${collidingGuarder.callerFile} ' + 'on line ${collidingGuarder.callerLine}.' + ); + } + message.writeln( + 'The first ${originalGuarder.className == null ? "function" : "method"} $originalName' + 'had not yet finished executing at the time that ' + 'the second ${collidingGuarder.className == null ? "function" : "method"} $collidingName' + 'was called. Since both are guarded, and the second was not a nested call inside the first, the ' + 'first must complete its execution before the second can be called. Typically, this is achieved by ' + 'putting an "await" statement in front of the call to the first.' + ); + if (collidingGuarder.className == null && collidingGuarder.methodName == 'expect') { + message.writeln( + 'If you are confident that all test APIs are being called using "await", and ' + 'this expect() call is not being invoked at the top level but is itself being ' + 'called from some sort of callback registered before the ${originalGuarder.methodName} ' + 'method was called, then consider using expectSync() instead.' + ); + } + message.writeln( + '\n' + 'When the first ${originalGuarder.className == null ? "function" : "method"} ' + '$originalName' + 'was called, this was the stack:' + ); + message.writeln(FlutterError.defaultStackFilter(scope.creationStack.toString().trimRight().split('\n')).join('\n')); + } + throw new FlutterError(message.toString().trimRight()); + } + + /// Verifies that there are no guarded methods currently pending (see [guard]). + /// + /// This is used at the end of tests to ensure that nothing leaks out of the test. + static void verifyAllScopesClosed() { + if (_scopeStack.isNotEmpty) { + StringBuffer message = new StringBuffer(); + message.writeln('Asynchronous call to guarded function leaked. You must use "await" with all Future-returning test APIs.'); + for (_AsyncScope scope in _scopeStack) { + final _StackEntry guarder = _findResponsibleMethod(scope.creationStack, 'guard', message); + if (guarder != null) { + message.writeln( + 'The guarded method "${guarder.methodName}" ' + '${guarder.className != null ? "from class ${guarder.className} " : ""}' + 'was called from ${guarder.callerFile} ' + 'on line ${guarder.callerLine}, ' + 'but never completed before its parent scope closed.' + ); + } + } + throw new FlutterError(message.toString().trimRight()); + } + } + + static _StackEntry _findResponsibleMethod(StackTrace rawStack, String method, StringBuffer errors) { + assert(method == 'guard' || method == 'guardSync'); + final List stack = rawStack.toString().split('\n'); + assert(stack.last == ''); + stack.removeLast(); + final RegExp getClassPattern = new RegExp(r'^#[0-9]+ +([^. ]+)'); + Match lineMatch; + int index = -1; + do { // skip past frames that are from this class + index += 1; + assert(index < stack.length); + lineMatch = getClassPattern.matchAsPrefix(stack[index]); + assert(lineMatch != null); + assert(lineMatch.groupCount == 1); + } while (lineMatch.group(1) == _className); + // try to parse the stack to find the interesting frame + if (index < stack.length) { + final RegExp guardPattern = new RegExp(r'^#[0-9]+ +(?:([^. ]+)\.)?([^. ]+)'); + final Match guardMatch = guardPattern.matchAsPrefix(stack[index]); // find the class that called us + if (guardMatch != null) { + assert(guardMatch.groupCount == 2); + final String guardClass = guardMatch.group(1); // might be null + final String guardMethod = guardMatch.group(2); + while (index < stack.length) { // find the last stack frame that called the class that called us + lineMatch = getClassPattern.matchAsPrefix(stack[index]); + if (lineMatch != null) { + assert(lineMatch.groupCount == 1); + if (lineMatch.group(1) == (guardClass ?? guardMethod)) { + index += 1; + continue; + } + } + break; + } + if (index < stack.length) { + final RegExp callerPattern = new RegExp(r'^#[0-9]+ .* \((.+):([0-9]+)(?::[0-9]+)?\)$'); + final Match callerMatch = callerPattern.matchAsPrefix(stack[index]); // extract the caller's info + if (callerMatch != null) { + assert(callerMatch.groupCount == 2); + final String callerFile = callerMatch.group(1); + final String callerLine = callerMatch.group(2); + return new _StackEntry(guardClass, guardMethod, callerFile, callerLine); + } else { + // One reason you might get here is if the guarding method was called directly from + // a 'dart:' API, like from the Future/microtask mechanism, because dart: URLs in the + // stack trace don't have a column number and so don't match the regexp above. + errors.writeln('(Unable to parse the stack frame of the method that called the method that called $_className.$method(). The stack may be incomplete or bogus.)'); + errors.writeln('${stack[index]}'); + } + } else { + errors.writeln('(Unable to find the stack frame of the method that called the method that called $_className.$method(). The stack may be incomplete or bogus.)'); + } + } else { + errors.writeln('(Unable to parse the stack frame of the method that called $_className.$method(). The stack may be incomplete or bogus.)'); + errors.writeln('${stack[index]}'); + } + } else { + errors.writeln('(Unable to find the method that called $_className.$method(). The stack may be incomplete or bogus.)'); + } + return null; + } +} + +class _StackEntry { + const _StackEntry(this.className, this.methodName, this.callerFile, this.callerLine); + final String className; + final String methodName; + final String callerFile; + final String callerLine; +} diff --git a/packages/flutter_test/lib/src/test_pointer.dart b/packages/flutter_test/lib/src/test_pointer.dart index 3ad1adfd7b..f2eff4ced9 100644 --- a/packages/flutter_test/lib/src/test_pointer.dart +++ b/packages/flutter_test/lib/src/test_pointer.dart @@ -2,8 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:flutter/gestures.dart'; +import 'test_async_utils.dart'; + export 'dart:ui' show Point; /// A class for generating coherent artificial pointer events. @@ -102,68 +106,85 @@ class TestPointer { } } +/// An callback that can dispatch events and returns a future that +/// completes when the event dispatch is complete. +typedef Future AsyncHitTestDispatcher(PointerEvent event, HitTestResult result); + /// A class for performing gestures in tests. /// /// The simplest way to create a [TestGesture] is to call /// [WidgetTester.startGesture]. class TestGesture { + TestGesture._(this._dispatcher, this._result, this._pointer); + /// Create a [TestGesture] by starting with a pointerDown at the /// given point. /// /// By default, the pointer ID used is 1. This can be overridden by /// providing the `pointer` argument. /// - /// By default, the global binding is used both for hit testing and - /// for dispatching of events. The object to use for hit testing can - /// be overridden by providing `hitTestTarget`, and the object to - /// use for dispatching events can be overridden by providing an - /// `dispatcher`. - factory TestGesture(Point downLocation, { + /// By default, the global binding is used for hit testing. The + /// object to use for hit testing can be overridden by providing + /// `hitTestTarget`. + /// + /// An object to use for dispatching events must be provided via the + /// `dispatcher` argument. + static Future down(Point downLocation, { int pointer: 1, HitTestable target, - HitTestDispatcher dispatcher - }) { - // hit test - final HitTestResult result = new HitTestResult(); - target ??= GestureBinding.instance; - assert(target != null); - target.hitTest(result, downLocation); - - // dispatch down event - final TestPointer testPointer = new TestPointer(pointer); - dispatcher ??= GestureBinding.instance; + AsyncHitTestDispatcher dispatcher + }) async { assert(dispatcher != null); - dispatcher.dispatchEvent(testPointer.down(downLocation), result); + final Completer completer = new Completer(); + TestGesture result; + TestAsyncUtils.guard(() async { + // hit test + final HitTestResult hitTestResult = new HitTestResult(); + target ??= GestureBinding.instance; + assert(target != null); + target.hitTest(hitTestResult, downLocation); - // create a TestGesture - return new TestGesture._(dispatcher, result, testPointer); + // dispatch down event + final TestPointer testPointer = new TestPointer(pointer); + await dispatcher(testPointer.down(downLocation), hitTestResult); + + // create a TestGesture + result = new TestGesture._(dispatcher, hitTestResult, testPointer); + return null; + }).whenComplete(() { + completer.complete(result); + }); + return completer.future; } - const TestGesture._(this._dispatcher, this._result, this._pointer); - - final HitTestDispatcher _dispatcher; + final AsyncHitTestDispatcher _dispatcher; final HitTestResult _result; final TestPointer _pointer; /// Send a move event moving the pointer by the given offset. - void moveBy(Offset offset) { + Future moveBy(Offset offset) { assert(_pointer._isDown); - moveTo(_pointer.location + offset); + return moveTo(_pointer.location + offset); } /// Send a move event moving the pointer to the given location. - void moveTo(Point location) { - assert(_pointer._isDown); - _dispatcher.dispatchEvent(_pointer.move(location), _result); + Future moveTo(Point location) { + return TestAsyncUtils.guard(() { + assert(_pointer._isDown); + return _dispatcher(_pointer.move(location), _result); + }); } /// End the gesture by releasing the pointer. /// /// The object is no longer usable after this method has been called. - void up() { - assert(_pointer._isDown); - _dispatcher.dispatchEvent(_pointer.up(), _result); - assert(!_pointer._isDown); + Future up() { + return TestAsyncUtils.guard(() async { + assert(_pointer._isDown); + await _dispatcher(_pointer.up(), _result); + assert(!_pointer._isDown); + return null; + }); } /// End the gesture by canceling the pointer (as would happen if the @@ -171,9 +192,12 @@ class TestGesture { /// for instance). /// /// The object is no longer usable after this method has been called. - void cancel() { - assert(_pointer._isDown); - _dispatcher.dispatchEvent(_pointer.cancel(), _result); - assert(!_pointer._isDown); + Future cancel() { + return TestAsyncUtils.guard(() async { + assert(_pointer._isDown); + await _dispatcher(_pointer.cancel(), _result); + assert(!_pointer._isDown); + return null; + }); } } diff --git a/packages/flutter_test/lib/src/widget_tester.dart b/packages/flutter_test/lib/src/widget_tester.dart index 784facae67..abeb230bd6 100644 --- a/packages/flutter_test/lib/src/widget_tester.dart +++ b/packages/flutter_test/lib/src/widget_tester.dart @@ -5,11 +5,14 @@ import 'dart:async'; import 'package:flutter/widgets.dart'; -import 'package:test/test.dart'; +import 'package:test/test.dart' as test_package; import 'binding.dart'; -import 'finders.dart'; import 'controller.dart'; +import 'finders.dart'; +import 'test_async_utils.dart'; + +export 'package:test/test.dart' hide expect; /// Signature for callback to [testWidgets] and [benchmarkWidgets]. typedef Future WidgetTesterCallback(WidgetTester widgetTester); @@ -36,15 +39,15 @@ typedef Future WidgetTesterCallback(WidgetTester widgetTester); /// expect(tester, hasWidget(find.text('Success'))); /// }); void testWidgets(String description, WidgetTesterCallback callback, { - Timeout timeout: const Timeout(const Duration(seconds: 5)), - bool skip + bool skip: false, + test_package.Timeout timeout }) { TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized(); WidgetTester tester = new WidgetTester._(binding); - group('-', () { - setUp(binding.preTest); - test(description, () => binding.runTest(() => callback(tester)), skip: skip); - tearDown(binding.postTest); + timeout ??= binding.defaultTestTimeout; + test_package.group('-', () { + test_package.test(description, () => binding.runTest(() => callback(tester)), skip: skip); + test_package.tearDown(binding.postTest); }, timeout: timeout); } @@ -75,17 +78,49 @@ void testWidgets(String description, WidgetTesterCallback callback, { /// tester.pump(); /// } /// timer.stop(); -/// print('Time taken: ${timer.elapsedMilliseconds}ms'); +/// debugPrint('Time taken: ${timer.elapsedMilliseconds}ms'); /// }); /// exit(0); /// } Future benchmarkWidgets(WidgetTesterCallback callback) { assert(false); // Don't run benchmarks in checked mode. TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized(); + assert(binding is! AutomatedTestWidgetsFlutterBinding); WidgetTester tester = new WidgetTester._(binding); return binding.runTest(() => callback(tester)) ?? new Future.value(); } +/// Assert that `actual` matches `matcher`. +/// +/// See [test_package.expect] for details. This is a variant of that function +/// that additionally verifies that there are no asynchronous APIs +/// that have not yet resolved. +void expect(dynamic actual, dynamic matcher, { + String reason, + bool verbose: false, + dynamic formatter +}) { + TestAsyncUtils.guardSync(); + test_package.expect(actual, matcher, reason: reason, verbose: verbose, formatter: formatter); +} + +/// Assert that `actual` matches `matcher`. +/// +/// See [test_package.expect] for details. This variant will _not_ check that +/// there are no outstanding asynchronous API requests. As such, it can be +/// called from, e.g., callbacks that are run during build or layout, or in the +/// completion handlers of futures that execute in response to user input. +/// +/// Generally, it is better to use [expect], which does include checks to ensure +/// that asynchronous APIs are not being called. +void expectSync(dynamic actual, dynamic matcher, { + String reason, + bool verbose: false, + dynamic formatter +}) { + test_package.expect(actual, matcher, reason: reason, verbose: verbose, formatter: formatter); +} + /// Class that programmatically interacts with widgets and the test environment. class WidgetTester extends WidgetController { WidgetTester._(TestWidgetsFlutterBinding binding) : super(binding); @@ -100,17 +135,25 @@ class WidgetTester extends WidgetController { /// flushes microtasks, by calling [pump] with the same duration (if any). /// The supplied [EnginePhase] is the final phase reached during the pump pass; /// if not supplied, the whole pass is executed. - void pumpWidget(Widget widget, [ Duration duration, EnginePhase phase ]) { - runApp(widget); - binding.pump(duration, phase); + Future pumpWidget(Widget widget, [ + Duration duration, + EnginePhase phase = EnginePhase.sendSemanticsTree + ]) { + return TestAsyncUtils.guard(() { + runApp(widget); + return binding.pump(duration, phase); + }); } /// Triggers a sequence of frames for [duration] amount of time. /// /// This is a convenience function that just calls /// [TestWidgetsFlutterBinding.pump]. - void pump([ Duration duration, EnginePhase phase ]) { - binding.pump(duration, phase); + Future pump([ + Duration duration, + EnginePhase phase = EnginePhase.sendSemanticsTree + ]) { + return TestAsyncUtils.guard(() => binding.pump(duration, phase)); } /// Returns the exception most recently caught by the Flutter framework. @@ -120,12 +163,14 @@ class WidgetTester extends WidgetController { return binding.takeException(); } + /// Acts as if the application went idle. + /// /// Runs all remaining microtasks, including those scheduled as a result of /// running them, until there are no more microtasks scheduled. /// /// Does not run timers. May result in an infinite loop or run out of memory /// if microtasks continue to recursively schedule new microtasks. - void flushMicrotasks() { - binding.fakeAsync.flushMicrotasks(); + Future idle() { + return TestAsyncUtils.guard(() => binding.idle()); } } diff --git a/packages/flutter_test/test/stack_manipulation_test.dart b/packages/flutter_test/test/stack_manipulation_test.dart new file mode 100644 index 0000000000..a755fbfb2d --- /dev/null +++ b/packages/flutter_test/test/stack_manipulation_test.dart @@ -0,0 +1,28 @@ +// Copyright 2016 The Chromium 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_test/flutter_test.dart'; + +void main() { + test('stack manipulation: reportExpectCall', () { + try { + expect(false, isTrue); + } catch (e, stack) { + StringBuffer information = new StringBuffer(); + expect(reportExpectCall(stack, information), 3); + List lines = information.toString().split('\n'); + expect(lines[0], 'This was caught by the test expectation on the following line:'); + expect(lines[1], matches(r'^ .*stack_manipulation_test.dart line [0-9]+$')); + } + + try { + throw null; + expect(false, isTrue); // shouldn't get here + } catch (e, stack) { + StringBuffer information = new StringBuffer(); + expect(reportExpectCall(stack, information), 0); + expect(information.toString(), ''); + } + }); +} diff --git a/packages/flutter_test/test/test_async_utils_test.dart b/packages/flutter_test/test/test_async_utils_test.dart new file mode 100644 index 0000000000..1019e4ce38 --- /dev/null +++ b/packages/flutter_test/test/test_async_utils_test.dart @@ -0,0 +1,178 @@ +// Copyright 2016 The Chromium 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/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_test/flutter_test.dart' as flutter_test show expect; +import 'package:test/test.dart' as real_test show expect; + +// We have to use real_test's expect because the flutter_test expect() goes +// out of its way to check that we're not leaking APIs and the whole point +// of this test is to see how we handle leaking APIs. + +class TestAPI { + Future testGuard1() { + return TestAsyncUtils.guard(() async { return null; }); + } + Future testGuard2() { + return TestAsyncUtils.guard(() async { return null; }); + } +} + +class TestAPISubclass extends TestAPI { + Future testGuard3() { + return TestAsyncUtils.guard(() async { return null; }); + } +} + +Future helperFunction(WidgetTester tester) async { + await tester.pump(); +} + +Future guardedHelper(WidgetTester tester) { + return TestAsyncUtils.guard(() async { + await tester.pumpWidget(new Text('Hello')); + }); +} + +void main() { + test('TestAsyncUtils - one class', () async { + TestAPI testAPI = new TestAPI(); + Future f1, f2; + f1 = testAPI.testGuard1(); + try { + f2 = testAPI.testGuard2(); + throw 'unexpectedly did not throw'; + } on FlutterError catch (e) { + List lines = e.message.split('\n'); + real_test.expect(lines[0], 'Guarded function conflict. You must use "await" with all Future-returning test APIs.'); + real_test.expect(lines[1], matches(r'The guarded method "testGuard1" from class TestAPI was called from .*test_async_utils.dart on line [0-9]+\.')); + real_test.expect(lines[2], matches(r'Then, the "testGuard2" method \(also from class TestAPI\) was called from .*test_async_utils.dart on line [0-9]+\.')); + real_test.expect(lines[3], 'The first method (TestAPI.testGuard1) had not yet finished executing at the time that the second method (TestAPI.testGuard2) was called. Since both are guarded, and the second was not a nested call inside the first, the first must complete its execution before the second can be called. Typically, this is achieved by putting an "await" statement in front of the call to the first.'); + real_test.expect(lines[4], ''); + real_test.expect(lines[5], 'When the first method (TestAPI.testGuard1) was called, this was the stack:'); + real_test.expect(lines.length, greaterThan(6)); + } + expect(await f1, isNull); + expect(f2, isNull); + }); + + test('TestAsyncUtils - two classes, all callers in superclass', () async { + TestAPI testAPI = new TestAPISubclass(); + Future f1, f2; + f1 = testAPI.testGuard1(); + try { + f2 = testAPI.testGuard2(); + throw 'unexpectedly did not throw'; + } on FlutterError catch (e) { + List lines = e.message.split('\n'); + real_test.expect(lines[0], 'Guarded function conflict. You must use "await" with all Future-returning test APIs.'); + real_test.expect(lines[1], matches(r'^The guarded method "testGuard1" from class TestAPI was called from .*test_async_utils.dart on line [0-9]+\.$')); + real_test.expect(lines[2], matches(r'^Then, the "testGuard2" method \(also from class TestAPI\) was called from .*test_async_utils.dart on line [0-9]+\.$')); + real_test.expect(lines[3], 'The first method (TestAPI.testGuard1) had not yet finished executing at the time that the second method (TestAPI.testGuard2) was called. Since both are guarded, and the second was not a nested call inside the first, the first must complete its execution before the second can be called. Typically, this is achieved by putting an "await" statement in front of the call to the first.'); + real_test.expect(lines[4], ''); + real_test.expect(lines[5], 'When the first method (TestAPI.testGuard1) was called, this was the stack:'); + real_test.expect(lines.length, greaterThan(6)); + } + expect(await f1, isNull); + expect(f2, isNull); + }); + + test('TestAsyncUtils - two classes, mixed callers', () async { + TestAPISubclass testAPI = new TestAPISubclass(); + Future f1, f2; + f1 = testAPI.testGuard1(); + try { + f2 = testAPI.testGuard3(); + throw 'unexpectedly did not throw'; + } on FlutterError catch (e) { + List lines = e.message.split('\n'); + real_test.expect(lines[0], 'Guarded function conflict. You must use "await" with all Future-returning test APIs.'); + real_test.expect(lines[1], matches(r'^The guarded method "testGuard1" from class TestAPI was called from .*test_async_utils.dart on line [0-9]+\.$')); + real_test.expect(lines[2], matches(r'^Then, the "testGuard3" method from class TestAPISubclass was called from .*test_async_utils.dart on line [0-9]+\.$')); + real_test.expect(lines[3], 'The first method (TestAPI.testGuard1) had not yet finished executing at the time that the second method (TestAPISubclass.testGuard3) was called. Since both are guarded, and the second was not a nested call inside the first, the first must complete its execution before the second can be called. Typically, this is achieved by putting an "await" statement in front of the call to the first.'); + real_test.expect(lines[4], ''); + real_test.expect(lines[5], 'When the first method (TestAPI.testGuard1) was called, this was the stack:'); + real_test.expect(lines.length, greaterThan(6)); + } + expect(await f1, isNull); + expect(f2, isNull); + }); + + test('TestAsyncUtils - expect() catches pending async work', () async { + TestAPI testAPI = new TestAPISubclass(); + Future f1; + f1 = testAPI.testGuard1(); + try { + flutter_test.expect(0, 0); + throw 'unexpectedly did not throw'; + } on FlutterError catch (e) { + List lines = e.message.split('\n'); + real_test.expect(lines[0], 'Guarded function conflict. You must use "await" with all Future-returning test APIs.'); + real_test.expect(lines[1], matches(r'^The guarded method "testGuard1" from class TestAPI was called from .*test_async_utils.dart on line [0-9]+\.$')); + real_test.expect(lines[2], matches(r'^Then, the "expect" function was called from .*test_async_utils.dart on line [0-9]+\.$')); + real_test.expect(lines[3], 'The first method (TestAPI.testGuard1) had not yet finished executing at the time that the second function (expect) was called. Since both are guarded, and the second was not a nested call inside the first, the first must complete its execution before the second can be called. Typically, this is achieved by putting an "await" statement in front of the call to the first.'); + real_test.expect(lines[4], 'If you are confident that all test APIs are being called using "await", and this expect() call is not being invoked at the top level but is itself being called from some sort of callback registered before the testGuard1 method was called, then consider using expectSync() instead.'); + real_test.expect(lines[5], ''); + real_test.expect(lines[6], 'When the first method (TestAPI.testGuard1) was called, this was the stack:'); + real_test.expect(lines.length, greaterThan(7)); + } + expect(await f1, isNull); + }); + + testWidgets('TestAsyncUtils - expect() catches pending async work', (WidgetTester tester) async { + Future f1, f2; + try { + f1 = tester.pump(); + f2 = tester.pump(); + throw 'unexpectedly did not throw'; + } on FlutterError catch (e) { + List lines = e.message.split('\n'); + real_test.expect(lines[0], 'Guarded function conflict. You must use "await" with all Future-returning test APIs.'); + real_test.expect(lines[1], matches(r'^The guarded method "pump" from class WidgetTester was called from .*test_async_utils.dart on line [0-9]+\.$')); + real_test.expect(lines[2], matches(r'^Then, it was called from .*test_async_utils.dart on line [0-9]+\.$')); + real_test.expect(lines[3], 'The first method had not yet finished executing at the time that the second method was called. Since both are guarded, and the second was not a nested call inside the first, the first must complete its execution before the second can be called. Typically, this is achieved by putting an "await" statement in front of the call to the first.'); + real_test.expect(lines[4], ''); + real_test.expect(lines[5], 'When the first method was called, this was the stack:'); + real_test.expect(lines.length, greaterThan(6)); + } + await f1; + await f2; + }); + + testWidgets('TestAsyncUtils - expect() catches pending async work', (WidgetTester tester) async { + Future f1; + try { + f1 = tester.pump(); + TestAsyncUtils.verifyAllScopesClosed(); + throw 'unexpectedly did not throw'; + } on FlutterError catch (e) { + List lines = e.message.split('\n'); + real_test.expect(lines[0], 'Asynchronous call to guarded function leaked. You must use "await" with all Future-returning test APIs.'); + real_test.expect(lines[1], matches(r'^The guarded method "pump" from class WidgetTester was called from .*test_async_utils.dart on line [0-9]+, but never completed before its parent scope closed\.$')); + real_test.expect(lines[2], matches(r'^The guarded method "pump" from class AutomatedTestWidgetsFlutterBinding was called from [^ ]+ on line [0-9]+, but never completed before its parent scope closed\.')); + real_test.expect(lines.length, 3); + } + await f1; + }); + + testWidgets('TestAsyncUtils - expect() catches pending async work', (WidgetTester tester) async { + Future f1; + try { + f1 = tester.pump(); + TestAsyncUtils.verifyAllScopesClosed(); + throw 'unexpectedly did not throw'; + } on FlutterError catch (e) { + List lines = e.message.split('\n'); + real_test.expect(lines[0], 'Asynchronous call to guarded function leaked. You must use "await" with all Future-returning test APIs.'); + real_test.expect(lines[1], matches(r'^The guarded method "pump" from class WidgetTester was called from .*test_async_utils.dart on line [0-9]+, but never completed before its parent scope closed\.$')); + real_test.expect(lines[2], matches(r'^The guarded method "pump" from class AutomatedTestWidgetsFlutterBinding was called from [^ ]+ on line [0-9]+, but never completed before its parent scope closed\.')); + real_test.expect(lines.length, 3); + } + await f1; + }); + + // see also dev/manual_tests/test_data which contains tests run by the flutter_tools tests for 'flutter test' +} diff --git a/packages/flutter_test/test/widget_tester_test.dart b/packages/flutter_test/test/widget_tester_test.dart index 501f59eecf..8e9e2d0e04 100644 --- a/packages/flutter_test/test/widget_tester_test.dart +++ b/packages/flutter_test/test/widget_tester_test.dart @@ -4,16 +4,15 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:test/test.dart'; void main() { group('findsOneWidget', () { - testWidgets('finds exactly one widget', (WidgetTester tester) { - tester.pumpWidget(new Text('foo')); + testWidgets('finds exactly one widget', (WidgetTester tester) async { + await tester.pumpWidget(new Text('foo')); expect(find.text('foo'), findsOneWidget); }); - testWidgets('fails with a descriptive message', (WidgetTester tester) { + testWidgets('fails with a descriptive message', (WidgetTester tester) async { TestFailure failure; try { expect(find.text('foo'), findsOneWidget); @@ -30,12 +29,12 @@ void main() { }); group('findsNothing', () { - testWidgets('finds no widgets', (WidgetTester tester) { + testWidgets('finds no widgets', (WidgetTester tester) async { expect(find.text('foo'), findsNothing); }); - testWidgets('fails with a descriptive message', (WidgetTester tester) { - tester.pumpWidget(new Text('foo')); + testWidgets('fails with a descriptive message', (WidgetTester tester) async { + await tester.pumpWidget(new Text('foo')); TestFailure failure; try { diff --git a/packages/flutter_tools/lib/src/test/flutter_platform.dart b/packages/flutter_tools/lib/src/test/flutter_platform.dart index 2d0c0c3908..51d42f014b 100644 --- a/packages/flutter_tools/lib/src/test/flutter_platform.dart +++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart @@ -51,7 +51,7 @@ Future _startProcess(String mainPath, { String packages }) { '--non-interactive', '--packages=$packages', mainPath, - ]); + ], environment: { 'FLUTTER_TEST': 'true' }); } class FlutterPlatform extends PlatformPlugin { diff --git a/packages/flutter_tools/test/test_test.dart b/packages/flutter_tools/test/test_test.dart new file mode 100644 index 0000000000..73a51c212e --- /dev/null +++ b/packages/flutter_tools/test/test_test.dart @@ -0,0 +1,75 @@ +// Copyright 2015 The Chromium 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 'dart:async'; +import 'dart:io'; + +import 'package:flutter_tools/src/cache.dart'; +import 'package:flutter_tools/src/dart/sdk.dart'; +import 'package:path/path.dart' as path; +import 'package:test/test.dart'; + +import 'src/context.dart'; + +// This test depends on some files in ///dev/automated_tests/flutter_test/* + +void main() { + group('test', () { + testUsingContext('TestAsyncUtils guarded function test', () async { + Cache.flutterRoot = '../..'; + return _testFile('test_async_utils_guarded'); + }); + testUsingContext('TestAsyncUtils unguarded function test', () async { + Cache.flutterRoot = '../..'; + return _testFile('test_async_utils_unguarded'); + }); + }, timeout: new Timeout(const Duration(seconds: 5))); +} + +Future _testFile(String testName) async { + final String manualTestsDirectory = path.join('..', '..', 'dev', 'automated_tests'); + final String fullTestName = path.join(manualTestsDirectory, 'flutter_test', '${testName}_test.dart'); + final File testFile = new File(fullTestName); + expect(testFile.existsSync(), true); + final String fullTestExpectation = path.join(manualTestsDirectory, 'flutter_test', '${testName}_expectation.txt'); + final File expectationFile = new File(fullTestExpectation); + expect(expectationFile.existsSync(), true); + final ProcessResult exec = await Process.run( + path.join(dartSdkPath, 'bin', 'dart'), + [ + path.absolute(path.join('bin', 'flutter_tools.dart')), + 'test', + fullTestName + ], + workingDirectory: manualTestsDirectory + ); + expect(exec.exitCode, 0); + final List output = exec.stdout.split('\n'); + final List expectations = new File(fullTestExpectation).readAsLinesSync(); + bool allowSkip = false; + int expectationLineNumber = 0; + int outputLineNumber = 0; + while (expectationLineNumber < expectations.length) { + expect(output, hasLength(greaterThan(outputLineNumber))); + final String expectationLine = expectations[expectationLineNumber]; + final String outputLine = output[outputLineNumber]; + if (expectationLine == '<>') { + allowSkip = true; + expectationLineNumber += 1; + continue; + } + if (allowSkip) { + if (!new RegExp(expectationLine).hasMatch(outputLine)) { + outputLineNumber += 1; + continue; + } + allowSkip = false; + } + expect(outputLine, matches(expectationLine)); + expectationLineNumber += 1; + outputLineNumber += 1; + } + expect(allowSkip, isFalse); + expect(exec.stderr, ''); +}