| Index: tests/lib_strong/async/async_await_zones_test.dart
|
| diff --git a/tests/lib_strong/async/async_await_zones_test.dart b/tests/lib_strong/async/async_await_zones_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..210b05dee778929c0d7d3f3757afd3146e927214
|
| --- /dev/null
|
| +++ b/tests/lib_strong/async/async_await_zones_test.dart
|
| @@ -0,0 +1,142 @@
|
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +// Test that async functions don't zone-register their callbacks for each
|
| +// await. Async functions should register their callback once in the beginning
|
| +// and then reuse it for all awaits in their body.
|
| +// This has two advantages: it is faster, when there are several awaits (on
|
| +// the Future class from dart:async), and it avoids zone-nesting when tracing
|
| +// stacktraces.
|
| +// See http://dartbug.com/23394 for more information.
|
| +
|
| +import 'dart:async';
|
| +import 'package:expect/expect.dart';
|
| +import 'package:async_helper/async_helper.dart';
|
| +
|
| +gee(i) async {
|
| + return await i;
|
| +}
|
| +
|
| +bar() async* {
|
| + var i = 0;
|
| + while (true) yield await gee(i++);
|
| +}
|
| +
|
| +
|
| +awaitForTest() async {
|
| + var sum = 0;
|
| + await for (var x in bar().take(100)) {
|
| + sum += x;
|
| + }
|
| + Expect.equals(4950, sum);
|
| +}
|
| +
|
| +awaitTest() async {
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + await null;
|
| + return await 499;
|
| +}
|
| +
|
| +runTests() async {
|
| + await awaitTest();
|
| + await awaitForTest();
|
| +}
|
| +
|
| +var depth = 0;
|
| +
|
| +var depthIncreases = 0;
|
| +
|
| +increaseDepth() {
|
| + depthIncreases++;
|
| + depth++;
|
| + // The async/await code should not register callbacks recursively in the
|
| + // then-calls. As such the depth should never grow too much. We don't want
|
| + // to commit to a specific value, since implementations still have some
|
| + // room in how async/await is implemented, but 20 should be safe.
|
| + Expect.isTrue(depth < 20);
|
| +}
|
| +
|
| +registerCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
|
| + var oldDepth = depth;
|
| + increaseDepth();
|
| + return parent.registerCallback(zone, () {
|
| + depth = oldDepth;
|
| + return f();
|
| + });
|
| +}
|
| +registerUnaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
|
| + var oldDepth = depth;
|
| + increaseDepth();
|
| + return parent.registerUnaryCallback(zone, (x) {
|
| + depth = oldDepth;
|
| + return f(x);
|
| + });
|
| +}
|
| +registerBinaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
|
| + var oldDepth = depth;
|
| + increaseDepth();
|
| + return parent.registerBinaryCallback(zone, (x, y) {
|
| + depth = oldDepth;
|
| + return f(x, y);
|
| + });
|
| +}
|
| +
|
| +sm(Zone self, ZoneDelegate parent, Zone zone, f) {
|
| + var oldDepth = depth;
|
| + increaseDepth();
|
| + return parent.scheduleMicrotask(zone, () {
|
| + depth = oldDepth;
|
| + return f();
|
| + });
|
| +}
|
| +
|
| +main() {
|
| + asyncStart();
|
| + var desc = new ZoneSpecification(
|
| + registerCallback: registerCallback,
|
| + registerUnaryCallback: registerUnaryCallback,
|
| + registerBinaryCallback: registerBinaryCallback,
|
| + scheduleMicrotask: sm
|
| + );
|
| + var future = runZoned(runTests, zoneSpecification: desc);
|
| + future.then((_) => asyncEnd());
|
| +}
|
|
|