Commit 32527017 authored by Ian Hickson's avatar Ian Hickson

Make it possible to run tests live on a device (#3936)

This makes it possible to substitute 'flutter run' for 'flutter test'
and actually watch a test run on a device.

For any test that depends on flutter_test:

1. Remove any import of 'package:test/test.dart'.

2. Replace `testWidgets('...', (WidgetTester tester) {`
      with `testWidgets('...', (WidgetTester tester) async {`

3. Add an "await" in front of calls to any of the following:
    * tap()
    * tapAt()
    * fling()
    * flingFrom()
    * scroll()
    * scrollAt()
    * pump()
    * pumpWidget()

4. Replace any calls to `tester.flushMicrotasks()` with calls to
   `await tester.idle()`.

There's a guarding API that you can use, if you have particularly
complicated tests, to get better error messages. Search for
TestAsyncUtils.
parent 5fa6c0e9
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).
.*(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:
<<skip until matching line>>
\(elided .+\)
When the exception was thrown, this was the stack:
<<skip until matching line>>
\(elided .+\)
════════════════════════════════════════════════════════════════════════════════════════════════════
.*(this line has more of the test framework's output)?
Test failed\. See exception logs above\.
*
.*..:.. \+0 -1: Some tests failed\. *
// 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<Null> 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
});
}
.*..:.. \+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:
<<skip until matching line>>
(elided [0-9]+ frames from .+)
When the exception was thrown, this was the stack:
<<skip until matching line>>
(elided [0-9]+ frames from .+)
════════════════════════════════════════════════════════════════════════════════════════════════════
.*..:.. \+0 -1: - TestAsyncUtils - handling unguarded async helper functions *
Test failed. See exception logs above.
*
.*..:.. \+0 -1: Some tests failed\. *
// 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<Null> 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
});
}
......@@ -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();
});
}
......@@ -41,7 +41,7 @@ class _WeatherDemoState extends State<WeatherDemo> {
'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);
}
......
......@@ -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<String> demoCategories = const <String>['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<Null> 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<double> scrollDeltas = new List<double>();
......@@ -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);
}
......@@ -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);
});
......
......@@ -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
......
......@@ -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);
});
}
......@@ -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<String> 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<String> 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<String> defaultStackFilter(Iterable<String> frames) {
final List<String> result = <String>[];
final List<String> filteredPackages = <String>[
'dart:async-patch',
'dart:async',
'package:stack_trace',
];
final List<String> filteredClasses = <String>[
'_FakeAsync',
];
final RegExp stackParser = new RegExp(r'^#[0-9]+ +([^.]+).* \(([^/]*)/[^:]+:[0-9]+(?::[0-9]+)?\)$');
final RegExp packageParser = new RegExp(r'^([^:]+):(.+)$');
final List<String> skipped = <String>[];
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<String> where = new Set<String>.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);
......
......@@ -25,6 +25,9 @@ typedef void ValueSetter<T>(T value);
/// See also [ValueSetter].
typedef T ValueGetter<T>();
/// Signature for callbacks that filter an iterable.
typedef Iterable<T> IterableFilter<T>(Iterable<T> 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<T extends dynamic> {
......
......@@ -62,7 +62,11 @@ abstract class ProgressIndicator extends StatefulWidget {
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (value != null) {
description.add('${(value.clamp(0.0, 1.0) * 100.0).toStringAsFixed(1)}%');
} else {
description.add('<indeterminate>');
}
}
}
......
......@@ -497,6 +497,13 @@ class TabBarSelection<T> extends StatefulWidget {
static TabBarSelectionState<dynamic/*=T*/> of/*<T>*/(BuildContext context) {
return context.ancestorStateOfType(new TypeMatcher<TabBarSelectionState<dynamic/*=T*/>>());
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('current tab: $value');
description.add('available tabs: $values');
}
}
class TabBarSelectionState<T> extends State<TabBarSelection<T>> {
......
......@@ -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();
assert(renderView == null);
renderView = new RenderView(configuration: createViewConfiguration());
renderView.scheduleInitialFrame();
}
handleMetricsChanged(); // configures renderView's metrics
}
/// 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.
......
......@@ -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,
......
......@@ -703,6 +703,13 @@ class _ForkingSemanticsFragment extends _SemanticsFragment {
}
class PipelineOwner {
PipelineOwner({ this.onNeedVisualUpdate });
final VoidCallback onNeedVisualUpdate;
void requestVisualUpdate() {
if (onNeedVisualUpdate != null)
onNeedVisualUpdate();
}
List<RenderObject> _nodesNeedingLayout = <RenderObject>[];
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.
......
......@@ -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<RenderBox> {
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<RenderBox>
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<RenderBox>
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();
......
......@@ -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
......
......@@ -20,7 +20,7 @@ void main() {
yieldCount = 0;
});
test("The Caching Iterable: length caches", () {
test('The Caching Iterable: length caches', () {
Iterable<int> i = new CachingIterable<int>(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<int> i = new CachingIterable<int>(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<int> integers = new CachingIterable<int>(range(1, 5).iterator);
expect(yieldCount, equals(0));
......
// 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<String> filtered = FlutterError.defaultStackFilter(StackTrace.current.toString().trimRight().split('\n')).toList();
expect(filtered.length, 4);
expect(filtered[0], matches(r'^#0 +main\.<anonymous closure> \(.*stack_trace_test\.dart:[0-9]+:[0-9]+\)$'));
expect(filtered[1], matches(r'^#1 +Declarer\.test\.<anonymous closure>\.<<anonymous closure>_async_body>\.<anonymous closure>\.<<anonymous closure>_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<String> filtered = FlutterError.defaultStackFilter(StackTrace.current.toString().trimRight().split('\n')).toList();
expect(filtered.length, 2);
expect(filtered[0], matches(r'^#0 +main\.<anonymous closure>\.<<anonymous closure>_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\)$'));
});
}
......@@ -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', () {
......
......@@ -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';
......
......@@ -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';
......
......@@ -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<DropDownMenuItem<int>> items = <DropDownMenuItem<int>>[];
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
});
}
......@@ -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: <Widget>[new LinearProgressIndicator(value: 0.0)]));
testWidgets('LinearProgressIndicator causes a repaint when it changes', (WidgetTester tester) async {
await tester.pumpWidget(new Block(children: <Widget>[new LinearProgressIndicator(value: 0.0)]));
List<Layer> layers1 = tester.layers;
tester.pumpWidget(new Block(children: <Widget>[new LinearProgressIndicator(value: 0.5)]));
await tester.pumpWidget(new Block(children: <Widget>[new LinearProgressIndicator(value: 0.5)]));
List<Layer> layers2 = tester.layers;
expect(layers1, isNot(equals(layers2)));
});
......
......@@ -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<Null>.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);
});
}
......@@ -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')),
......
......@@ -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));
});
......
......@@ -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));
});
}
......@@ -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: <OverlayEntry>[
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: <OverlayEntry>[
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: <OverlayEntry>[
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: <OverlayEntry>[
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: <OverlayEntry>[
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: <OverlayEntry>[
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: <OverlayEntry>[
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: <OverlayEntry>[
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);
......
......@@ -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)));
});
}
......@@ -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
......
......@@ -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));
......
......@@ -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,
......
......@@ -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));
......
......@@ -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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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)));
......
......@@ -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<Size> _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,
......
......@@ -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/*<RenderImage>*/(find.byKey(key)).image;
}
void pumpTreeToLayout(WidgetTester tester, Widget widget) {
Future<Null> 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);
});
......
......@@ -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: <Widget>[
......@@ -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: <Widget>[
......@@ -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));
});
......
......@@ -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<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
PersistentBottomSheetController<Null> 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));
});
......
......@@ -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/*<Null>*/(
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/*<Null>*/(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<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
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);
......
......@@ -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,
......
......@@ -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<BadDisposeWidget> {
}
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);
});
}
......@@ -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(
......
......@@ -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: <Widget>[new Center()]));
testWidgets('Can be placed in an infinite box', (WidgetTester tester) async {
await tester.pumpWidget(new Block(children: <Widget>[new Center()]));
});
}
......@@ -4,7 +4,6 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:test/test.dart';
final List<String> log = <String>[];
......@@ -20,8 +19,8 @@ class PathClipper extends CustomClipper<Path> {
}
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(<String>['getClip']));
tester.tapAt(new Point(10.0, 10.0));
await tester.tapAt(new Point(10.0, 10.0));
expect(log, equals(<String>['getClip']));
log.clear();
tester.tapAt(new Point(100.0, 100.0));
await tester.tapAt(new Point(100.0, 100.0));
expect(log, equals(<String>['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(<String>[]));
tester.tapAt(new Point(10.0, 10.0));
await tester.tapAt(new Point(10.0, 10.0));
expect(log, equals(<String>[]));
log.clear();
tester.tapAt(new Point(400.0, 300.0));
await tester.tapAt(new Point(400.0, 300.0));
expect(log, equals(<String>['tap']));
log.clear();
});
......
......@@ -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: <Widget>[
new Positioned(
......
......@@ -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: <Widget>[
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))
......
......@@ -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);
});
......
......@@ -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<String> log = <String>[];
tester.pumpWidget(new CustomPaint(
await tester.pumpWidget(new CustomPaint(
painter: new TestCustomPainter(
log: log,
name: 'background'
......
......@@ -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)));
});
}
......@@ -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<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
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<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
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<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
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();
});
}
......@@ -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
});
}
......@@ -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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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,
......
......@@ -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<int> log = <int>[];
......@@ -52,7 +51,7 @@ void main() {
);
}
tester.pumpWidget(
await tester.pumpWidget(
new Flow(
delegate: new TestFlowDelegate(startOffset: startOffset),
children: <Widget>[
......@@ -67,22 +66,22 @@ void main() {
)
);
tester.tap(find.text('0'));
await tester.tap(find.text('0'));
expect(log, equals(<int>[0]));
tester.tap(find.text('1'));
await tester.tap(find.text('1'));
expect(log, equals(<int>[0, 1]));
tester.tap(find.text('2'));
await tester.tap(find.text('2'));
expect(log, equals(<int>[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(<int>[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(<int>[0]));
});
}
......@@ -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);
......
......@@ -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<Null> 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<Null> 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<Null> 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('');
});
}
......@@ -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,
......
......@@ -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<Null> pumpWidgetTree(HitTestBehavior behavior) {
return tester.pumpWidget(
new Stack(
children: <Widget>[
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);
......
......@@ -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<Null> {
}
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.
......
......@@ -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);
......
......@@ -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],
......
......@@ -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
......
......@@ -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<TriggerableWidget> {
}
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));
......
......@@ -4,7 +4,6 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:test/test.dart';
List<String> ancestors = <String>[];
......@@ -28,8 +27,8 @@ class TestWidgetState extends State<TestWidget> {
}
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(<String>['Container', 'RenderObjectToWidgetAdapter<RenderBox>']));
});
}
......@@ -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)));
});
......
......@@ -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: <Widget>[
new Block(
......
......@@ -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<String> log = new List<String>();
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(<String>[
'bottom',
......
......@@ -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());
});
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment