| Index: tests/language/async_await_test.dart
|
| diff --git a/tests/language/async_await_test.dart b/tests/language/async_await_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..705c0a3042cba8f152754219a1b61c7d1ad432ca
|
| --- /dev/null
|
| +++ b/tests/language/async_await_test.dart
|
| @@ -0,0 +1,2006 @@
|
| +// 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.
|
| +
|
| +library async_await_test;
|
| +
|
| +import "package:unittest/unittest.dart";
|
| +import "dart:async";
|
| +
|
| +main() {
|
| + bool checkedMode = false;
|
| + assert((checkedMode = true));
|
| +
|
| + group("basic", () {
|
| + test("async w/o await", () {
|
| + f() async { return id(42); }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("async waits", () {
|
| + // Calling an "async" function won't do anything immediately.
|
| + var result = [];
|
| + f() async {
|
| + result.add(1);
|
| + return id(42);
|
| + };
|
| + var future = f();
|
| + result.add(0);
|
| + return future.whenComplete(() {
|
| + expect(result, equals([0, 1]));
|
| + });
|
| + });
|
| +
|
| + test("async throws", () {
|
| + f() async {
|
| + throw "err";
|
| + return id(42);
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("await future", () {
|
| + f() async {
|
| + var v = await new Future.value(42);
|
| + return v;
|
| + };
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await value", () {
|
| + f() async {
|
| + var v = await id(42);
|
| + return v;
|
| + };
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await null", () {
|
| + f() async {
|
| + var v = await null;
|
| + expect(v, equals(null));
|
| + };
|
| + return f();
|
| + });
|
| +
|
| + test("await await", () {
|
| + f() async {
|
| + return await await new Future.value(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await fake value future", () {
|
| + f() async {
|
| + return await new FakeValueFuture(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await fake error future", () {
|
| + f() async {
|
| + return await new FakeErrorFuture("err");
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("await value is delayed", () {
|
| + f() async {
|
| + bool x = false;
|
| + scheduleMicrotask(() { x = true; });
|
| + var y = await true;
|
| + expect(x, equals(y));
|
| + }
|
| + return f();
|
| + });
|
| +
|
| + test("await throw", () {
|
| + f() async {
|
| + await (throw "err"); // Check grammar: Are parentheses necessary?
|
| + return id(42);
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("throw before await", () {
|
| + f() async {
|
| + var x = throw "err";
|
| + await x; // Check grammar: Are parentheses necessary?
|
| + return id(42);
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + if (checkedMode) {
|
| + test("assert before await", () {
|
| + f(v) async {
|
| + assert(v == 87);
|
| + return await new Future.microtask(() => 42);
|
| + }
|
| + return f(42).then((_) {
|
| + fail("assert didn't throw");
|
| + }, onError: (e, s) {
|
| + expect(e is AssertionError, isTrue);
|
| + });
|
| + });
|
| +
|
| + test("assert after await", () {
|
| + f(v) async {
|
| + var x = await new Future.microtask(() => 42);
|
| + assert(v == 87);
|
| + return x;
|
| + }
|
| + return f(42).then((_) {
|
| + fail("assert didn't throw");
|
| + }, onError: (e, s) {
|
| + expect(e is AssertionError, isTrue);
|
| + });
|
| + });
|
| + }
|
| +
|
| + test("async await error", () {
|
| + f() async {
|
| + await new Future.error("err");
|
| + return id(42);
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("async flattens futures", () {
|
| + f() async {
|
| + return new Future.value(42); // Not awaited.
|
| + };
|
| + return f().then((v) {
|
| + expect(v, equals(42)); // And not a Future with value 42.
|
| + });
|
| + });
|
| +
|
| + test("async flattens futures, error", () {
|
| + f() async {
|
| + return new Future.error("err"); // Not awaited.
|
| + };
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("await for", () {
|
| + f(s) async {
|
| + int i = 0;
|
| + await for (int v in s) {
|
| + i += v;
|
| + }
|
| + return i;
|
| + }
|
| + return f(mkStream()).then((v) {
|
| + expect(v, equals(45)); // 0 + 1 + ... + 9
|
| + });
|
| + });
|
| +
|
| + test("await for w/ await", () {
|
| + f(s) async {
|
| + int i = 0;
|
| + await for (int v in s) {
|
| + i += await new Future.value(v);
|
| + }
|
| + return i;
|
| + }
|
| + return f(mkStream()).then((v) {
|
| + expect(v, equals(45)); // 0 + 1 + ... + 9
|
| + });
|
| + });
|
| +
|
| + test("await for empty", () {
|
| + f(s) async {
|
| + int v = 0;
|
| + await for (int i in s) {
|
| + v += i;
|
| + }
|
| + return v;
|
| + }
|
| + var s = (new StreamController()..close()).stream;
|
| + return f(s).then((v) {
|
| + expect(v, equals(0));
|
| + });
|
| + });
|
| +
|
| + if (checkedMode) {
|
| + test("await for w/ await, asseert", () {
|
| + f(s) async {
|
| + int i = 0;
|
| + await for (int v in s) {
|
| + i += await new Future.microtask(() => v);
|
| + assert(v < 8);
|
| + }
|
| + return i;
|
| + }
|
| + return f(mkStream()).then((v) {
|
| + fail("assert didn't throw");
|
| + }, onError: (e, s) {
|
| + expect(e is AssertionError, isTrue);
|
| + });
|
| + });
|
| + }
|
| + });
|
| +
|
| + group("for", () {
|
| + test("await in for-loop", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < 10; i++) {
|
| + v += await new Future.value(42);
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10 * id(42)));
|
| + });
|
| + });
|
| +
|
| + test("await in for-init", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = await new Future.value(42); i >= 0; i -= 10) {
|
| + v += 10;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10 * 5));
|
| + });
|
| + });
|
| +
|
| + test("await in for-test", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < await new Future.value(42); i += 10) {
|
| + v += 10;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10 * 5));
|
| + });
|
| + });
|
| +
|
| + test("await in for-incr", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < 100; i += await new Future.value(42)) {
|
| + v += 10;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10 * 3));
|
| + });
|
| + });
|
| +
|
| + test("await err in for-loop", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < 10; i++) {
|
| + v += await new Future.error("err");
|
| + }
|
| + return v;
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("await err in for-init", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = await new Future.error("err"); i >= 0; i -= 10) {
|
| + v += 10;
|
| + }
|
| + return v;
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("await err in for-test", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < await new Future.error("err"); i += 10) {
|
| + v += 10;
|
| + }
|
| + return v;
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("await err in for-incr", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < 100; i += await new Future.error("err")) {
|
| + v += 10;
|
| + }
|
| + return v;
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("await in empty for-loop", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i > 0; i += 1) {
|
| + v += await new Future.value(42);
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(0));
|
| + });
|
| + });
|
| +
|
| + test("await in empty for-loop 2", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i > 0; i += await new Future.value(1)) {
|
| + v += 1;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(0));
|
| + });
|
| + });
|
| +
|
| + test("break before await in for-loop", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < 10; i += 1) {
|
| + if (i == 2) break;
|
| + v += await new Future.value(42);
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 2));
|
| + });
|
| + });
|
| +
|
| + test("break before await in for-loop 2", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < 10; i += await new Future.value(1)) {
|
| + if (i == 2) break;
|
| + v += id(42);
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 2));
|
| + });
|
| + });
|
| +
|
| + test("continue before await", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < 10; i += 1) {
|
| + if (i == 2) continue;
|
| + v += await new Future.value(42);
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 9));
|
| + });
|
| + });
|
| +
|
| + test("continue after await", () {
|
| + f() async {
|
| + int v = 0;
|
| + for (int i = 0; i < 10; i += 1) {
|
| + var j = await new Future.value(42);
|
| + if (i == 2) continue;
|
| + v += j;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 9));
|
| + });
|
| + });
|
| + });
|
| +
|
| + group("while", () {
|
| + test("await in while-loop", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + while (i < 10) {
|
| + v += await new Future.value(42);
|
| + i++;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10 * id(42)));
|
| + });
|
| + });
|
| +
|
| + test("await in while-test", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + while (i < await new Future.value(42)) {
|
| + v += 10;
|
| + i += 10;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10 * 5));
|
| + });
|
| + });
|
| +
|
| + test("await err in loop", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + while (i < 10) {
|
| + v += await new Future.error("err");
|
| + i++;
|
| + }
|
| + return v;
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("await err in test", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + while (i < await new Future.error("err")) {
|
| + v += 10;
|
| + i += 10;
|
| + }
|
| + return v;
|
| + }
|
| + return throwsErr(f());
|
| + });
|
| +
|
| + test("break before await", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + while (i < 10) {
|
| + if (i == 2) break;
|
| + v += await new Future.value(42);
|
| + i += 1;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 2));
|
| + });
|
| + });
|
| +
|
| + test("break after await", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + while (i < 10) {
|
| + v += await new Future.value(42);
|
| + if (i == 2) break;
|
| + i += 1;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 3));
|
| + });
|
| + });
|
| +
|
| + test("continue before await", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + while (i < 10) {
|
| + i += 1;
|
| + if (i == 2) continue;
|
| + v += await new Future.value(42);
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 9));
|
| + });
|
| + });
|
| +
|
| + test("continue after await", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + while (i < 10) {
|
| + i += 1;
|
| + int j = await new Future.value(42);
|
| + if (i == 2) continue;
|
| + v += j;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 9));
|
| + });
|
| + });
|
| + });
|
| +
|
| + group("do-while", () {
|
| + test("await in loop", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + do {
|
| + v += await new Future.value(42);
|
| + i++;
|
| + } while (i < 10);
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10 * id(42)));
|
| + });
|
| + });
|
| +
|
| + test("await in test", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + do {
|
| + v += 10;
|
| + i += 10;
|
| + } while (i < await new Future.value(42));
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10 * 5));
|
| + });
|
| + });
|
| +
|
| + test("await err in loop", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + do {
|
| + v += await new Future.error("err");
|
| + i++;
|
| + } while (i < 10);
|
| + return v;
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| +
|
| + test("await err in test", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + do {
|
| + v += 10;
|
| + i += 10;
|
| + } while (i < await new Future.error("err"));
|
| + return v;
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| +
|
| + test("break before await", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + do {
|
| + if (i == 2) break;
|
| + v += await new Future.value(42);
|
| + i += 1;
|
| + } while (i < 10);
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 2));
|
| + });
|
| + });
|
| +
|
| + test("break after await", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + do {
|
| + v += await new Future.value(42);
|
| + if (i == 2) break;
|
| + i += 1;
|
| + } while (i < 10);
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 3));
|
| + });
|
| + });
|
| +
|
| + test("continue before await", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + do {
|
| + i += 1;
|
| + if (i == 2) continue;
|
| + v += await new Future.value(42);
|
| + } while (i < 10);
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 9));
|
| + });
|
| + });
|
| +
|
| + test("continue after await", () {
|
| + f() async {
|
| + int v = 0;
|
| + int i = 0;
|
| + do {
|
| + i += 1;
|
| + int j = await new Future.value(42);
|
| + if (i == 2) continue;
|
| + v += j;
|
| + } while (i < 10);
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42 * 9));
|
| + });
|
| + });
|
| + });
|
| +
|
| + group("for-in", () {
|
| + test("await in for-in", () {
|
| + f() async {
|
| + var v = 0;
|
| + for (var fut in [1, 2, 3].map((v) => new Future.value(v))) {
|
| + v += await fut;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(6));
|
| + });
|
| + });
|
| +
|
| + test("await in for-in iterable", () {
|
| + f() async {
|
| + var v = 0;
|
| + for (var i in await new Future.value([1, 2, 3])) {
|
| + v += i;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(6));
|
| + });
|
| + });
|
| +
|
| + test("await err in for-in", () {
|
| + f() async {
|
| + var v = 0;
|
| + for (var fut in [1, 2, 3].map((v) => (v != 1)
|
| + ? new Future.value(v)
|
| + : new Future.error("err"))) {
|
| + v += await fut;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| +
|
| + test("await err in for-in iterable", () {
|
| + f() async {
|
| + var v = 0;
|
| + for (var i in await new Future.error("err")) {
|
| + v += i;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| +
|
| + test("break before await in for-in", () {
|
| + f() async {
|
| + var v = 0;
|
| + for (var fut in [1, 2, 3].map((v) => new Future.value(v))) {
|
| + if (v == 3) break;
|
| + v += await fut;
|
| + }
|
| + return v;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(3));
|
| + });
|
| + });
|
| + });
|
| +
|
| + group("try-catch", () {
|
| + test("try-no-catch", () {
|
| + f() async {
|
| + try {
|
| + return await id(42);
|
| + } catch(e) {
|
| + return 37;
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await in body", () {
|
| + f() async {
|
| + try {
|
| + await new Future.error(42);
|
| + } catch(e) {
|
| + return e;
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("throw before await in body", () {
|
| + int i = id(0);
|
| + f() async {
|
| + try {
|
| + if (i >= 0) throw id(42);
|
| + return await new Future.value(10);
|
| + } catch(e) {
|
| + return e;
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("try-catch await in catch", () {
|
| + f() async {
|
| + try {
|
| + throw id(42);
|
| + } catch(e) {
|
| + return await new Future.value(e);
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("try-catch await error in catch", () {
|
| + f() async {
|
| + try {
|
| + throw id(42);
|
| + } catch(e) {
|
| + await new Future.error("err");
|
| + }
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| +
|
| + test("try-catch-rethrow", () {
|
| + f() async {
|
| + try {
|
| + await new Future.error("err");
|
| + } catch(e) {
|
| + if (e == id(42)) return;
|
| + rethrow;
|
| + }
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| + });
|
| +
|
| + group("try-finally", () {
|
| + test("await in body", () {
|
| + f() async {
|
| + try {
|
| + return await new Future.value(42);
|
| + } finally {
|
| + // Don't do anything.
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await in finally", () {
|
| + var x = 0;
|
| + f() async {
|
| + try {
|
| + return id(42);
|
| + } finally {
|
| + x = await new Future.value(37);
|
| + }
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42));
|
| + expect(x, equals(37));
|
| + });
|
| + });
|
| +
|
| + test("await err in body", () {
|
| + f() async {
|
| + try {
|
| + return await new Future.error("err");
|
| + } finally {
|
| + // Don't do anything.
|
| + }
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| +
|
| + test("await err in finally", () {
|
| + f() async {
|
| + try {
|
| + return id(42);
|
| + } finally {
|
| + await new Future.error("err");
|
| + }
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| +
|
| + test("await err in both", () {
|
| + f() async {
|
| + try {
|
| + await new Future.error("not err");
|
| + } finally {
|
| + await new Future.error("err");
|
| + }
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| + });
|
| +
|
| + test("await err in body, override in finally", () {
|
| + f() async {
|
| + try {
|
| + return await new Future.error("err");
|
| + } finally {
|
| + return id(42);
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await in body, override in finally", () {
|
| + f() async {
|
| + label: try {
|
| + return await new Future.value(37);
|
| + } finally {
|
| + break label;
|
| + }
|
| + return id(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await, override in finally", () {
|
| + var x = 0;
|
| + f() async {
|
| + label: try {
|
| + return 87;
|
| + } finally {
|
| + x = await new Future.value(37);
|
| + break label;
|
| + }
|
| + return id(42);
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42));
|
| + expect(x, equals(37));
|
| + });
|
| + });
|
| +
|
| + test("throw in body, await, override in finally 3", () {
|
| + var x = 0;
|
| + f() async {
|
| + label: try {
|
| + throw "err";
|
| + } finally {
|
| + x = await new Future.value(37);
|
| + break label;
|
| + }
|
| + return id(42);
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42));
|
| + expect(x, equals(37));
|
| + });
|
| + });
|
| +
|
| + test("await err in body, override in finally 2", () {
|
| + f() async {
|
| + label: try {
|
| + return await new Future.error("err");
|
| + } finally {
|
| + break label;
|
| + }
|
| + return id(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await in body, no-exit in finally", () {
|
| + f() async {
|
| + for (int i = 0; i < 10; i++) {
|
| + try {
|
| + return await i;
|
| + } finally {
|
| + continue;
|
| + }
|
| + }
|
| + return id(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("no-exit after await in finally", () {
|
| + f() async {
|
| + int i = 0;
|
| + for (; i < 10; i++) {
|
| + try {
|
| + break;
|
| + } finally {
|
| + await new Future.value(42);
|
| + continue;
|
| + }
|
| + }
|
| + return id(i);
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(10));
|
| + });
|
| + });
|
| +
|
| + test("exit after continue, await in finally", () {
|
| + f() async {
|
| + int i = 0;
|
| + for (; i < 10; i++) {
|
| + try {
|
| + continue;
|
| + } finally {
|
| + await new Future.value(42);
|
| + break;
|
| + }
|
| + }
|
| + return id(i);
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(0));
|
| + });
|
| + });
|
| +
|
| + test("no-exit before await in finally 2", () {
|
| + f() async {
|
| + for (int i = 0; i < 10; i++) {
|
| + try {
|
| + return i;
|
| + } finally {
|
| + if (i >= 0) continue;
|
| + await new Future.value(42);
|
| + }
|
| + }
|
| + return id(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("no-exit after await in finally", () {
|
| + f() async {
|
| + for (int i = 0; i < 10; i++) {
|
| + try {
|
| + return i;
|
| + } finally {
|
| + await new Future.value(42);
|
| + continue;
|
| + }
|
| + }
|
| + return id(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("nested finallies", () {
|
| + var x = 0;
|
| + f() async {
|
| + try {
|
| + try {
|
| + return 42;
|
| + } finally {
|
| + x = await new Future.value(37);
|
| + }
|
| + } finally {
|
| + x += await new Future.value(37);
|
| + }
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42));
|
| + expect(x, equals(74));
|
| + });
|
| + });
|
| +
|
| + test("nested finallies 2", () {
|
| + var x = 0;
|
| + f() async {
|
| + label: try {
|
| + try {
|
| + break label;
|
| + } finally {
|
| + x = await new Future.value(37);
|
| + }
|
| + } finally {
|
| + x += await new Future.value(37);
|
| + }
|
| + return 42;
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42));
|
| + expect(x, equals(74));
|
| + });
|
| + });
|
| +
|
| + test("nested finallies 3", () {
|
| + var x = 0;
|
| + f() async {
|
| + label: try {
|
| + try {
|
| + break label;
|
| + } finally {
|
| + return await new Future.value(42);
|
| + }
|
| + } finally {
|
| + break label;
|
| + }
|
| + return 42;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("nested finallies, throw", () {
|
| + var x = 0;
|
| + f() async {
|
| + try {
|
| + try {
|
| + throw "err";
|
| + } finally {
|
| + x = await new Future.value(37);
|
| + }
|
| + } finally {
|
| + x += await new Future.value(37);
|
| + }
|
| + }
|
| + return f().then((v) { fail("didn't throw"); },
|
| + onError: (e) {
|
| + expect(e, equals("err"));
|
| + expect(x, equals(2 * 37));
|
| + });
|
| + });
|
| + });
|
| +
|
| + group("try-catch-finally", () {
|
| + test("await in body", () {
|
| + f() async {
|
| + try {
|
| + return await new Future.value(42);
|
| + } catch (e) {
|
| + throw null;
|
| + } finally {
|
| + if (id(42) == id(10)) return 10;
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await in catch, not hit", () {
|
| + f() async {
|
| + try {
|
| + return id(42);
|
| + } catch (e) {
|
| + await new Future.error("err");
|
| + } finally {
|
| + if (id(42) == id(10)) return 10;
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await in catch, hit", () {
|
| + f() async {
|
| + try {
|
| + return throw id(42);
|
| + } catch (e) {
|
| + return await new Future.value(e);
|
| + } finally {
|
| + if (id(42) == id(10)) return 10;
|
| + }
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("await in finally", () {
|
| + var x = 0;
|
| + f() async {
|
| + try {
|
| + return id(42);
|
| + } catch (e) {
|
| + throw null;
|
| + } finally {
|
| + x = await new Future.value(37);
|
| + if (id(42) == id(10)) return 10;
|
| + }
|
| + }
|
| + return f().then((v) {
|
| + expect(v, equals(42));
|
| + expect(x, equals(37));
|
| + });
|
| + });
|
| + });
|
| +
|
| + group("switch", () {
|
| + test("await in expression", () {
|
| + f(v) async {
|
| + switch (await new Future.value(v)) {
|
| + case 1: return 1;
|
| + case 2: return 42;
|
| + default: return 3;
|
| + }
|
| + return null;
|
| + }
|
| + return expect42(f(2));
|
| + });
|
| +
|
| + test("await err in expression", () {
|
| + f(v) async {
|
| + switch (await new Future.error("err")) {
|
| + case 1: return 1;
|
| + case 2: return 42;
|
| + default: return 3;
|
| + }
|
| + return null;
|
| + }
|
| + return throwsErr(f(2));
|
| + });
|
| +
|
| + test("await in case", () {
|
| + f(v) async {
|
| + switch (v) {
|
| + case 1: return 1;
|
| + case 2: return await new Future.value(42);
|
| + default: return 3;
|
| + }
|
| + return null;
|
| + }
|
| + return expect42(f(2));
|
| + });
|
| +
|
| + test("await err in case", () {
|
| + f(v) async {
|
| + switch (v) {
|
| + case 1: return 1;
|
| + case 2: return await new Future.error("err");
|
| + default: return 3;
|
| + }
|
| + return null;
|
| + }
|
| + return throwsErr(f(2));
|
| + });
|
| +
|
| + test("continue before await in case", () {
|
| + f(v) async {
|
| + switch (v) {
|
| + label:
|
| + case 1: return 42;
|
| + case 2:
|
| + if (v <= 2) continue label;
|
| + return await new Future.value(10);
|
| + default: return 3;
|
| + }
|
| + return null;
|
| + }
|
| + return expect42(f(2));
|
| + });
|
| +
|
| + test("continue after await in case", () {
|
| + f(v) async {
|
| + switch (v) {
|
| + label:
|
| + case 1: return 42;
|
| + case 2:
|
| + await new Future.value(10);
|
| + continue label;
|
| + default: return 3;
|
| + }
|
| + return null;
|
| + }
|
| + return expect42(f(2));
|
| + });
|
| + });
|
| +
|
| + group("if", () {
|
| + test("await in test", () {
|
| + f(v) async {
|
| + if (await new Future.value(v)) {
|
| + return 42;
|
| + } else {
|
| + return 37;
|
| + }
|
| + }
|
| + return expect42(f(true));
|
| + });
|
| +
|
| + test("await err in test", () {
|
| + f(v) async {
|
| + if (await new Future.error("err")) {
|
| + return 42;
|
| + } else {
|
| + return 37;
|
| + }
|
| + }
|
| + return throwsErr(f(true));
|
| + });
|
| +
|
| + test("await in then", () {
|
| + f(v) async {
|
| + if (v) {
|
| + return await new Future.value(42);
|
| + }
|
| + return 37;
|
| + }
|
| + return expect42(f(true));
|
| + });
|
| +
|
| + test("await err in then", () {
|
| + f(v) async {
|
| + if (v) {
|
| + return await new Future.error("err");
|
| + }
|
| + return 37;
|
| + }
|
| + return throwsErr(f(true));
|
| + });
|
| +
|
| + test("await in then with else", () {
|
| + f(v) async {
|
| + if (v) {
|
| + return await new Future.value(42);
|
| + } else {
|
| + return 87;
|
| + }
|
| + return 37;
|
| + }
|
| + return expect42(f(true));
|
| + });
|
| +
|
| + test("await err in then with else", () {
|
| + f(v) async {
|
| + if (v) {
|
| + return await new Future.error("err");
|
| + } else {
|
| + return 87;
|
| + }
|
| + return 37;
|
| + }
|
| + return throwsErr(f(true));
|
| + });
|
| +
|
| + test("await in else", () {
|
| + f(v) async {
|
| + if (v) {
|
| + return 37;
|
| + } else {
|
| + return await new Future.value(42);
|
| + }
|
| + return 87;
|
| + }
|
| + return expect42(f(false));
|
| + });
|
| +
|
| + test("await err in else", () {
|
| + f(v) async {
|
| + if (v) {
|
| + return 37;
|
| + } else {
|
| + return await new Future.error("err");
|
| + }
|
| + return 87;
|
| + }
|
| + return throwsErr(f(false));
|
| + });
|
| +
|
| + test("await in else-if test", () {
|
| + f(v) async {
|
| + if (v) {
|
| + return 37;
|
| + } else if (!await new Future.value(v)) {
|
| + return 42;
|
| + } else {
|
| + return 37;
|
| + }
|
| + return 87;
|
| + }
|
| + return expect42(f(false));
|
| + });
|
| +
|
| + test("await in else-if then", () {
|
| + f(v) async {
|
| + if (v) {
|
| + return 37;
|
| + } else if (!v) {
|
| + return await new Future.value(42);
|
| + } else {
|
| + return 37;
|
| + }
|
| + return 87;
|
| + }
|
| + return expect42(f(false));
|
| + });
|
| + });
|
| +
|
| + group("conditional operator", () {
|
| + test("await in test", () {
|
| + f(v) async {
|
| + return (await new Future.value(v)) ? 42 : 37;
|
| + }
|
| + return expect42(f(true));
|
| + });
|
| +
|
| + test("await err in test", () {
|
| + f(v) async {
|
| + return (await new Future.error("err")) ? 42 : 37;
|
| + }
|
| + return throwsErr(f(true));
|
| + });
|
| +
|
| + test("await in then", () {
|
| + f(v) async {
|
| + return v ? (await new Future.value(42)) : 37;
|
| + }
|
| + return expect42(f(true));
|
| + });
|
| +
|
| + test("await err in then", () {
|
| + f(v) async {
|
| + return v ? (await new Future.error("err")) : 37;
|
| + }
|
| + return throwsErr(f(true));
|
| + });
|
| +
|
| + test("await in else", () {
|
| + f(v) async {
|
| + return v ? 37 : (await new Future.value(42));
|
| + }
|
| + return expect42(f(false));
|
| + });
|
| +
|
| + test("await err in else", () {
|
| + f(v) async {
|
| + return v ? 37 : (await new Future.error("err"));
|
| + }
|
| + return throwsErr(f(false));
|
| + });
|
| + });
|
| +
|
| + group("async declarations", () {
|
| + var f42 = new Future.value(42);
|
| +
|
| + // Top-level declarations or local declarations in top-level functions.
|
| + test("topMethod", () {
|
| + return expect42(topMethod(f42));
|
| + });
|
| +
|
| + test("topArrowMethod", () {
|
| + return expect42(topArrowMethod(f42));
|
| + });
|
| +
|
| + test("topGetter", () {
|
| + return expect42(topGetter);
|
| + });
|
| +
|
| + test("topArrowGetter", () {
|
| + return expect42(topArrowGetter);
|
| + });
|
| +
|
| + test("topLocal", () {
|
| + return expect42(topLocal(f42));
|
| + });
|
| +
|
| + test("topArrowLocal", () {
|
| + return expect42(topArrowLocal(f42));
|
| + });
|
| +
|
| + test("topExpression", () {
|
| + return expect42(topExpression(f42));
|
| + });
|
| +
|
| + test("topArrowExpression", () {
|
| + return expect42(topArrowExpression(f42));
|
| + });
|
| +
|
| + test("topVarExpression", () {
|
| + return expect42(topVarExpression(f42));
|
| + });
|
| +
|
| + test("topVarArrowExpression", () {
|
| + return expect42(topVarArrowExpression(f42));
|
| + });
|
| +
|
| + // Static declarations or local declarations in static functions.
|
| + test("staticMethod", () {
|
| + return expect42(Async.staticMethod(f42));
|
| + });
|
| +
|
| + test("staticArrowMethod", () {
|
| + return expect42(Async.staticArrowMethod(f42));
|
| + });
|
| +
|
| + test("staticGetter", () {
|
| + return expect42(Async.staticGetter);
|
| + });
|
| +
|
| + test("staticArrowGetter", () {
|
| + return expect42(Async.staticArrowGetter);
|
| + });
|
| +
|
| + test("staticLocal", () {
|
| + return expect42(Async.staticLocal(f42));
|
| + });
|
| +
|
| + test("staticArrowLocal", () {
|
| + return expect42(Async.staticArrowLocal(f42));
|
| + });
|
| +
|
| + test("staticExpression", () {
|
| + return expect42(Async.staticExpression(f42));
|
| + });
|
| +
|
| + test("staticArrowExpression", () {
|
| + return expect42(Async.staticArrowExpression(f42));
|
| + });
|
| +
|
| + test("staticVarExpression", () {
|
| + return expect42(Async.staticVarExpression(f42));
|
| + });
|
| +
|
| + test("staticVarArrowExpression", () {
|
| + return expect42(Async.staticVarArrowExpression(f42));
|
| + });
|
| +
|
| + // Instance declarations or local declarations in instance functions.
|
| + var async = new Async();
|
| +
|
| + test("instanceMethod", () {
|
| + return expect42(async.instanceMethod(f42));
|
| + });
|
| +
|
| + test("instanceArrowMethod", () {
|
| + return expect42(async.instanceArrowMethod(f42));
|
| + });
|
| +
|
| + test("instanceGetter", () {
|
| + return expect42(async.instanceGetter);
|
| + });
|
| +
|
| + test("instanceArrowGetter", () {
|
| + return expect42(async.instanceArrowGetter);
|
| + });
|
| +
|
| + test("instanceLocal", () {
|
| + return expect42(async.instanceLocal(f42));
|
| + });
|
| +
|
| + test("instanceArrowLocal", () {
|
| + return expect42(async.instanceArrowLocal(f42));
|
| + });
|
| +
|
| + test("instanceExpression", () {
|
| + return expect42(async.instanceExpression(f42));
|
| + });
|
| +
|
| + test("instanceArrowExpression", () {
|
| + return expect42(async.instanceArrowExpression(f42));
|
| + });
|
| +
|
| + test("instanceVarExpression", () {
|
| + return expect42(async.instanceVarExpression(f42));
|
| + });
|
| +
|
| + test("instanceVarArrowExpression", () {
|
| + return expect42(async.instanceVarArrowExpression(f42));
|
| + });
|
| +
|
| + // Local functions in constructor initializer list.
|
| + test("initializerExpression", () {
|
| + var async = new Async.initializer(f42);
|
| + return expect42(async.initValue);
|
| + });
|
| +
|
| + test("initializerArrowExpression", () {
|
| + var async = new Async.initializerArrow(f42);
|
| + return expect42(async.initValue);
|
| + });
|
| +
|
| + test("async in async", () {
|
| + return expect42(asyncInAsync(f42));
|
| + });
|
| +
|
| + test("sync in async", () {
|
| + return expect42(syncInAsync(f42));
|
| + });
|
| +
|
| + test("async in sync", () {
|
| + return expect42(asyncInSync(f42));
|
| + });
|
| +
|
| + // Equality and identity.
|
| + test("Identical and equals", () {
|
| + expect(async.instanceMethod, equals(async.instanceMethod));
|
| + expect(Async.staticMethod, same(Async.staticMethod));
|
| + expect(topMethod, same(topMethod));
|
| + });
|
| + });
|
| +
|
| + group("await expression", () {
|
| + const c42 = 42;
|
| + final v42 = 42;
|
| +
|
| + test("local variable", () {
|
| + var l42 = 42;
|
| + f() async {
|
| + return await l42;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("parameter", () {
|
| + f(p) async {
|
| + return await p;
|
| + }
|
| + return expect42(f(42));
|
| + });
|
| +
|
| + test("final local variable", () {
|
| + f() async {
|
| + return await v42;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("const local variable", () {
|
| + f() async {
|
| + return await c42;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("unary prefix operator", () {
|
| + f() async {
|
| + return -await -42;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("suffix operator", () {
|
| + f() async {
|
| + var v = [42];
|
| + return await v[0];
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("unary postfix operator", () {
|
| + f() async {
|
| + var x = 42;
|
| + return await x++;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("suffix operator + increment", () {
|
| + f() async {
|
| + var v = [42];
|
| + return await v[0]++;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("suffix operator + increment 2", () {
|
| + f() async {
|
| + var v = [42];
|
| + return await v[await 0]++;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("unary pre-increment operator", () {
|
| + f() async {
|
| + var x = 41;
|
| + return await ++x;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("suffix operator + pre-increment", () {
|
| + f() async {
|
| + var v = [41];
|
| + return await ++v[0];
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("assignment operator", () {
|
| + f() async {
|
| + var x = 37;
|
| + return await (x = 42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("assignment-op operator", () {
|
| + f() async {
|
| + var x = 37;
|
| + return await (x += 5);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("binary operator", () {
|
| + f() async {
|
| + return await (10 + 11) + await (10 + 11);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("ternary operator", () {
|
| + f(v) async {
|
| + return await ((v == 10) ? new Future.value(42) : 37);
|
| + }
|
| + return expect42(f(10));
|
| + });
|
| +
|
| + test("top-level function call", () {
|
| + f() async {
|
| + return await topMethod(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("static function call", () {
|
| + f() async {
|
| + return await Async.staticMethod(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("instance function call", () {
|
| + f() async {
|
| + var a = new Async();
|
| + return await a.instanceMethod(42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("top-level function call w/ await", () {
|
| + f() async {
|
| + return await topMethod(await 42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("static function call w/ await", () {
|
| + f() async {
|
| + return await Async.staticMethod(await 42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("instance function call w/ await", () {
|
| + f() async {
|
| + var a = new Async();
|
| + return await a.instanceMethod(await 42);
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("top-level getter call", () {
|
| + f() async {
|
| + return await topGetter;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("static getter call", () {
|
| + f() async {
|
| + return await Async.staticGetter;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("top-level getter call", () {
|
| + f() async {
|
| + var a = new Async();
|
| + return await a.instanceGetter;
|
| + }
|
| + return expect42(f());
|
| + });
|
| +
|
| + test("inside assert, true", () { /// 03: ok
|
| + f() async { /// 03: continued
|
| + assert(await new Future.microtask(() => true)); /// 03: continued
|
| + return 42; /// 03: continued
|
| + } /// 03: continued
|
| + return expect42(f()); /// 03: continued
|
| + }); /// 03: continued
|
| +
|
| + test("inside assert, false", () { /// 03: continued
|
| + f() async { /// 03: continued
|
| + assert(await new Future.microtask(() => false)); /// 03: continued
|
| + return 42; /// 03: continued
|
| + } /// 03: continued
|
| + return f().then((_) { /// 03: continued
|
| + fail("assert didn't throw"); /// 03: continued
|
| + }, onError: (e, s) { /// 03: continued
|
| + expect(e is AssertionError, isTrue); /// 03: continued
|
| + }); /// 03: continued
|
| + }); /// 03: continued
|
| +
|
| + test("inside assert, function -> false", () { /// 03: continued
|
| + f() async { /// 03: continued
|
| + assert(await new Future.microtask(() => false)); /// 03: continued
|
| + return 42; /// 03: continued
|
| + } /// 03: continued
|
| + return f().then((_) { /// 03: continued
|
| + fail("assert didn't throw"); /// 03: continued
|
| + }, onError: (e, s) { /// 03: continued
|
| + expect(e is AssertionError, isTrue); /// 03: continued
|
| + }); /// 03: continued
|
| + }); /// 03: continued
|
| +
|
| + });
|
| +
|
| + group("syntax", () {
|
| + test("async as variable", () {
|
| + // Valid identifiers outside of async function.
|
| + var async = 42;
|
| + expect(async, equals(42));
|
| + });
|
| +
|
| + test("await as variable", () { /// 02: ok
|
| + // Valid identifiers outside of async function. /// 02: continued
|
| + var await = 42; /// 02: continued
|
| + expect(await, equals(42)); /// 02: continued
|
| + }); /// 02: continued
|
| +
|
| + test("yield as variable", () {
|
| + // Valid identifiers outside of async function.
|
| + var yield = 42;
|
| + expect(yield, equals(42));
|
| + });
|
| + });
|
| +}
|
| +
|
| +
|
| +// Attempt to obfuscates value to avoid too much constant folding.
|
| +id(v) {
|
| + try {
|
| + if (v != null) throw v;
|
| + } catch (e) {
|
| + return e;
|
| + }
|
| + return null;
|
| +}
|
| +
|
| +// Create a stream for testing "async for-in".
|
| +Stream mkStream() {
|
| + var c;
|
| + int i = 0;
|
| + next() {
|
| + c.add(i++);
|
| + if (i == 10) {
|
| + c.close();
|
| + } else {
|
| + scheduleMicrotask(next);
|
| + }
|
| + }
|
| + c = new StreamController(onListen: () {
|
| + scheduleMicrotask(next);
|
| + });
|
| + return c.stream;
|
| +}
|
| +
|
| +// Check that future contains the error "err".
|
| +Future throwsErr(Future future) {
|
| + return future.then((v) { fail("didn't throw"); },
|
| + onError: (e) { expect(e, equals("err")); });
|
| +}
|
| +
|
| +// Check that future contains the value 42.
|
| +Future expect42(Future future) {
|
| + return future.then((v) {
|
| + expect(v, equals(42));
|
| + });
|
| +}
|
| +
|
| +
|
| +// Various async declarations.
|
| +
|
| +Future topMethod(f) async { return await f; }
|
| +
|
| +Future topArrowMethod(f) async => await f;
|
| +
|
| +Future get topGetter async {
|
| + return await new Future.value(42);
|
| +}
|
| +
|
| +Future get topArrowGetter async => await new Future.value(42);
|
| +
|
| +Future topLocal(f) {
|
| + local() async { return await f; }
|
| + return local();
|
| +}
|
| +
|
| +Future topArrowLocal(f) {
|
| + local() async => await f;
|
| + return local();
|
| +}
|
| +
|
| +Future topExpression(f) {
|
| + return () async { return await f; } ();
|
| +}
|
| +
|
| +Future topArrowExpression(f) {
|
| + return (() async => await f) ();
|
| +}
|
| +
|
| +var topVarExpression = (f) async { return await f; };
|
| +
|
| +var topVarArrowExpression = (f) async => await f;
|
| +
|
| +class Async {
|
| + var initValue;
|
| + Async();
|
| +
|
| + Async.initializer(f) : initValue = (() async { return await f; } ());
|
| +
|
| + Async.initializerArrow(f) : initValue = ((() async => await f) ());
|
| +
|
| + /* static */
|
| + static Future staticMethod(f) async { return await f; }
|
| +
|
| + static Future staticArrowMethod(f) async => await f;
|
| +
|
| + static Future get staticGetter async {
|
| + return await new Future.value(42);
|
| + }
|
| +
|
| + static Future get staticArrowGetter async => await new Future.value(42);
|
| +
|
| + static Future staticLocal(f) {
|
| + local() async { return await f; }
|
| + return local();
|
| + }
|
| +
|
| + static Future staticArrowLocal(f) {
|
| + local() async => await f;
|
| + return local();
|
| + }
|
| +
|
| + static Future staticExpression(f) {
|
| + return () async { return await f; } ();
|
| + }
|
| +
|
| + static Future staticArrowExpression(f) {
|
| + return (() async => await f) ();
|
| + }
|
| +
|
| + static var staticVarExpression = (f) async { return await f; };
|
| +
|
| + static var staticVarArrowExpression = (f) async => await f;
|
| +
|
| + /* instance */
|
| + Future instanceMethod(f) async { return await f; }
|
| +
|
| + Future instanceArrowMethod(f) async => await f;
|
| +
|
| + Future get instanceGetter async {
|
| + return await new Future.value(42);
|
| + }
|
| +
|
| + Future get instanceArrowGetter async => await new Future.value(42);
|
| +
|
| + Future instanceLocal(f) {
|
| + local() async { return await f; }
|
| + return local();
|
| + }
|
| +
|
| + Future instanceArrowLocal(f) {
|
| + local() async => await f;
|
| + return local();
|
| + }
|
| +
|
| + Future instanceExpression(f) {
|
| + return () async { return await f; } ();
|
| + }
|
| +
|
| + Future instanceArrowExpression(f) {
|
| + return (() async => await f) ();
|
| + }
|
| +
|
| + var instanceVarExpression = (f) async { return await f; };
|
| +
|
| + var instanceVarArrowExpression = (f) async => await f;
|
| +}
|
| +
|
| +Future asyncInAsync(f) async {
|
| + inner(f) async {
|
| + return await f;
|
| + }
|
| + return await inner(f);
|
| +}
|
| +
|
| +Future asyncInSync(f) {
|
| + inner(f) async {
|
| + return await f;
|
| + }
|
| + return inner(f);
|
| +}
|
| +
|
| +Future syncInAsync(f) async {
|
| + inner(f) {
|
| + return f;
|
| + }
|
| + return await inner(f);
|
| +}
|
| +
|
| +/**
|
| + * A non-standard implementation of Future with a value.
|
| + */
|
| +class FakeValueFuture implements Future {
|
| + final _value;
|
| + FakeValueFuture(this._value);
|
| + Future then(callback(value), {Function onError}) {
|
| + return new Future.microtask(() => callback(_value));
|
| + }
|
| + Future whenComplete(callback()) {
|
| + return new Future.microtask(() { callback(); });
|
| + }
|
| + Future catchError(Function onError, {bool test(error)}) => this;
|
| + Stream asStream() => (new StreamController()..add(_value)..close()).stream;
|
| + Future timeout(Duration duration, {onTimeout}) => this;
|
| +}
|
| +
|
| +typedef BinaryFunction(a, b);
|
| +
|
| +/**
|
| + * A non-standard implementation of Future with an error.
|
| + */
|
| +class FakeErrorFuture implements Future {
|
| + final _error;
|
| + FakeErrorFuture(this._error);
|
| + Future then(callback(value), {Function onError}) {
|
| + if (onError != null) {
|
| + if (onError is BinaryFunction) {
|
| + return new Future.microtask(() => onError(_error, null));
|
| + }
|
| + return new Future.microtask(() => onError(_error));
|
| + }
|
| + return this;
|
| + }
|
| + Future whenComplete(callback()) {
|
| + return new Future.microtask(() { callback(); }).then((_) => this);
|
| + }
|
| + Future catchError(Function onError, {bool test(error)}) {
|
| + return new Future.microtask(() {
|
| + if (test != null && !test(_error)) return this;
|
| + if (onError is BinaryFunction) {
|
| + return onError(_error, null);
|
| + }
|
| + return onError(_error);
|
| + });
|
| + }
|
| + Stream asStream() =>
|
| + (new StreamController()..addError(_error)..close()).stream;
|
| + Future timeout(Duration duration, {onTimeout}) => this;
|
| +}
|
|
|