From bd4cf62821fcd2df2bbac55a7fad02489b268aed Mon Sep 17 00:00:00 2001 From: Florian Loitsch Date: Mon, 18 Jun 2018 15:17:02 +0200 Subject: [PATCH] Roll sync async engine (#18454) * Roll the engine. This engine includes a VM that defaults to sync-async. flutter/engine@c8eeee4 Roll the Dart VM. --- bin/internal/engine.version | 2 +- .../exception_handling_expectation.txt | 5 +++- .../test_async_utils_guarded_test.dart | 2 +- packages/flutter/test/engine/dart_test.dart | 26 +++++++++++++++++++ packages/flutter_test/lib/src/binding.dart | 23 ++++++++-------- 5 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 packages/flutter/test/engine/dart_test.dart diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 31b5559883e..930e6258aa6 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -c3976b3c7183f479717bffed3f640fb92afbd3dc +c8eeee432bb362d657186faa00b3de7c468a9062 diff --git a/dev/automated_tests/flutter_test/exception_handling_expectation.txt b/dev/automated_tests/flutter_test/exception_handling_expectation.txt index 4c0fb6e5239..346aa983bc6 100644 --- a/dev/automated_tests/flutter_test/exception_handling_expectation.txt +++ b/dev/automated_tests/flutter_test/exception_handling_expectation.txt @@ -43,7 +43,10 @@ Who lives, who dies, who tells your story\? When the exception was thrown, this was the stack: #[0-9]+ +main. \(.+[/\\]dev[/\\]automated_tests[/\\]flutter_test[/\\]exception_handling_test\.dart:16:9\) -#[0-9]+ +main. \(.+[/\\]dev[/\\]automated_tests[/\\]flutter_test[/\\]exception_handling_test\.dart:15:77\) +#[0-9]+ +.+ \(package:flutter_test[/\\]src[/\\]binding.dart:[0-9]+:[0-9]+\) +#[0-9]+ +.+ \(package:flutter_test[/\\]src[/\\]binding.dart:[0-9]+:[0-9]+\) +#[0-9]+ +.+ \(package:flutter_test[/\\]src[/\\]binding.dart:[0-9]+:[0-9]+\) +#[0-9]+ +.+ \(package:flutter_test[/\\]src[/\\]binding.dart:[0-9]+:[0-9]+\) #[0-9]+ +.+ \(package:flutter_test[/\\]src[/\\]widget_tester\.dart:[0-9]+:[0-9]+\) <> ^\(elided [0-9]+ .+\)$ diff --git a/dev/automated_tests/flutter_test/test_async_utils_guarded_test.dart b/dev/automated_tests/flutter_test/test_async_utils_guarded_test.dart index f04a1399545..9a99f3aae15 100644 --- a/dev/automated_tests/flutter_test/test_async_utils_guarded_test.dart +++ b/dev/automated_tests/flutter_test/test_async_utils_guarded_test.dart @@ -14,7 +14,7 @@ class TestTestBinding extends AutomatedTestWidgetsFlutterBinding { Future guardedHelper(WidgetTester tester) { return TestAsyncUtils.guard(() async { - await tester.pumpWidget(const Text('Hello')); + await tester.pumpWidget(const Text('Hello', textDirection: TextDirection.ltr)); }); } diff --git a/packages/flutter/test/engine/dart_test.dart b/packages/flutter/test/engine/dart_test.dart new file mode 100644 index 00000000000..7efe12f9d13 --- /dev/null +++ b/packages/flutter/test/engine/dart_test.dart @@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:test/test.dart'; + +/// Verifies Dart semantics governed by flags set by Flutter tooling. +void main() { + group('Async', () { + String greeting = 'hello'; + Future changeGreeting() async { + greeting += ' 1'; + await new Future.value(null); + greeting += ' 2'; + } + test('execution of async method starts synchronously', () async { + expect(greeting, 'hello'); + final Future future = changeGreeting(); + expect(greeting, 'hello 1'); + await future; + expect(greeting, 'hello 1 2'); + }); + }); +} diff --git a/packages/flutter_test/lib/src/binding.dart b/packages/flutter_test/lib/src/binding.dart index 0145ae7081f..403ba11f440 100644 --- a/packages/flutter_test/lib/src/binding.dart +++ b/packages/flutter_test/lib/src/binding.dart @@ -502,7 +502,6 @@ abstract class TestWidgetsFlutterBinding extends BindingBase testZone.runBinary(_runTestBody, testBody, invariantTester) .whenComplete(testCompletionHandler); timeout?.catchError(handleUncaughtError); - asyncBarrier(); // When using AutomatedTestWidgetsFlutterBinding, this flushes the microtasks. return testCompleter.future; } @@ -532,6 +531,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase } assert(inTest); + asyncBarrier(); // When using AutomatedTestWidgetsFlutterBinding, this flushes the microtasks. return null; } @@ -848,22 +848,23 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { }); return new Future.microtask(() async { + // testBodyResult is a Future that was created in the Zone of the + // fakeAsync. This means that if we await it here, it will register a + // microtask to handle the future _in the fake async zone_. We avoid this + // by calling '.then' in the current zone. While flushing the microtasks + // of the fake-zone below, the new future will be completed and can then + // be used without fakeAsync. + final Future resultFuture = testBodyResult.then((_) { + // Do nothing. + }); + // Resolve interplay between fake async and real async calls. fakeAsync.flushMicrotasks(); while (_pendingAsyncTasks != null) { await _pendingAsyncTasks.future; fakeAsync.flushMicrotasks(); } - - // If we get here and fakeAsync != _currentFakeAsync, then the test - // probably timed out. - - // testBodyResult is a Future that was created in the Zone of the - // fakeAsync. This means that if we await it here, it will register a - // microtask to handle the future _in the fake async zone_. We avoid this - // by returning the wrapped microtask future that we've created _outside_ - // the fake async zone. - return testBodyResult; + return resultFuture; }); }