Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(685)

Unified Diff: tests/language/async_await_test.dart

Issue 968963002: Add some async/await tests. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..950d8310296233c58f68ae02db3397c0605b4b3b
--- /dev/null
+++ b/tests/language/async_await_test.dart
@@ -0,0 +1,988 @@
+// 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.
+
+import "package:unittest/unittest.dart";
+import "dart:async";
+
+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;
+}
+
+main() {
+ group("basic", () {
+ test("async works", () {
+ f() async { return id(42); }
+ return f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((_) { fail("Didn't throw"); },
+ onError: (e, s) { expect(e, equals("err")); });
Søren Gjesse 2015/03/03 08:08:41 Indentation.
Lasse Reichstein Nielsen 2015/03/03 11:22:42 I made an abstraction for "throwsErr".
+ });
+
+ test("await future", () {
+ f() async {
+ var v = await new Future.value(42);
+ expect(v, equals(42));
+ };
+ return f();
+ });
+
+ test("await value", () {
+ f() async {
+ var v = await id(42);
+ expect(v, equals(42));
+ };
+ return f();
+ });
+
+ test("await null", () {
+ f() async {
+ var v = await null;
+ expect(v, equals(null));
+ };
+ return f();
+ });
+
+ // test("await throw", () {
+ // f() async {
+ // await (throw "err"); // Check grammar: Are parentheses necessary?
+ // return id(42);
+ // }
+ // return f().then((_) { fail("Didn't throw"); },
+ // onError: (e, s) { expect(e, equals("err")); });
+ // });
+
+ test("throw before await", () {
+ f() async {
+ var x = throw "err";
+ await x; // Check grammar: Are parentheses necessary?
Søren Gjesse 2015/03/03 08:08:41 Add test for await local without a throw. Add tes
Lasse Reichstein Nielsen 2015/03/03 11:22:42 Ah, await of different expression types! Good idea
+ return id(42);
+ }
+ return f().then((_) { fail("Didn't throw"); },
+ onError: (e, s) { expect(e, equals("err")); });
+ });
+
+ test("async await error", () {
+ f() async {
+ await new Future.error("err");
+ return id(42);
+ }
+ return f().then((_) { fail("Didn't throw"); },
+ onError: (e, s) { expect(e, equals("err")); });
+ });
+
+ 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 id(42).
Søren Gjesse 2015/03/03 08:08:41 id(42) -> 42. Did you intend to use id(42) above?
Lasse Reichstein Nielsen 2015/03/03 11:22:42 Nope.
Søren Gjesse 2015/03/03 11:39:56 What I ment was that the comment should not have i
+ });
+ });
+
+ test("async flattens futures, error", () {
+ f() async {
+ return new Future.error("err"); // Not awaited.
+ };
+ return f().then((_) { fail("Didn't throw"); },
+ onError: (e, s) { expect(e, equals("err")); });
+ });
+
+ 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 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)); // 0 + 1 + ... + 9
Søren Gjesse 2015/03/03 08:08:41 Remove comment.
Lasse Reichstein Nielsen 2015/03/03 11:22:42 Done.
+ });
+ });
+ });
+
+ 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 f().then((v) { fail("didn't throw"); },
+ onError: (e) { expect(e, equals("err")); });
+ });
+
+ 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 f().then((v) { fail("didn't throw"); },
+ onError: (e) { expect(e, equals("err")); });
+ });
+
+ 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 f().then((v) { fail("didn't throw"); },
+ onError: (e) { expect(e, equals("err")); });
+ });
+
+ 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 f().then((v) { fail("didn't throw"); },
+ onError: (e) { expect(e, equals("err")); });
+ });
+
+ 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));
+ });
+ });
Søren Gjesse 2015/03/03 08:08:41 How about for tests with continue (same for while)
Lasse Reichstein Nielsen 2015/03/03 11:22:42 Sure, why not!
+ });
+
+ 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 while-loop", () {
+ f() async {
+ int v = 0;
+ int i = 0;
+ while (i < 10) {
+ v += await new Future.error("err");
+ i++;
+ }
+ return v;
+ }
+ return f().then((v) { fail("didn't throw"); },
+ onError: (e) { expect(e, equals("err")); });
+ });
+
+ test("await err in while-test", () {
+ f() async {
+ int v = 0;
+ int i = 0;
+ while (i < await new Future.error("err")) {
+ v += 10;
+ i += 10;
+ }
+ return v;
+ }
+ return f().then((v) { fail("didn't throw"); },
+ onError: (e) { expect(e, equals("err")); });
+ });
+
+ test("break before await in while", () {
+ 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));
+ });
+ });
+ });
+
+ group("do-while", () {
+ test("await in do-while-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 do-while-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 do-while-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 do-while-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 in do-while", () {
+ 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));
+ });
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ test("await in body", () {
+ f() async {
+ try {
+ await new Future.error(42);
+ } catch(e) {
+ return e;
+ }
+ }
+ return f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ test("try-catch await in catch", () {
+ f() async {
+ try {
+ throw id(42);
+ } catch(e) {
+ return await new Future.value(e);
+ }
+ }
+ return f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ test("await in body, override in finally", () {
+ f() async {
+ label: try {
+ return await new Future.value(37);
+ } finally {
+ break label;
+ }
+ return id(42);
+ }
+ return f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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")); });
Søren Gjesse 2015/03/03 08:08:41 Also checck x is 74.
Lasse Reichstein Nielsen 2015/03/03 11:22:42 Done.
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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 f().then((v) {
+ expect(v, equals(42));
+ });
+ });
+
+ 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));
+ });
+ });
+ });
+}
+
+
+// Attempt to obfuscates value to avoid too much constant folding.
+id(v) {
Søren Gjesse 2015/03/03 08:08:41 Maybe move this up to mkStream (or move mkStream d
Lasse Reichstein Nielsen 2015/03/03 11:22:42 Moving mkStream down. I have added many more helpe
+ try {
+ throw v;
+ } catch (e) {
+ return e;
+ }
+ return null;
+}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698