Add more tests for async*/await-for operations.
Change-Id: I2c8ffb8a6738b8dee43cfdf85be0c54d2735b6cc
Reviewed-on: https://dart-review.googlesource.com/c/85391
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
diff --git a/tests/language_2/async_star/async_star_await_for_test.dart b/tests/language_2/async_star/async_star_await_for_test.dart
new file mode 100644
index 0000000..0493a1f
--- /dev/null
+++ b/tests/language_2/async_star/async_star_await_for_test.dart
@@ -0,0 +1,376 @@
+// Copyright (c) 2018, 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 `await for` and `async*` interact correctly.
+
+// An `await for` must pause its subscription immediately
+// if the `await for` body does anything asynchronous
+// (any `await`, `await for`, or pausing at a `yield`/`yield*`)
+// A pause happening synchronously in an event delivery
+// must pause the `sync*` method at the `yield` sending the event.
+// A break happening synchronously in an event delivery,
+// or while paused at a `yield`, must exit at that `yield`.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+Stream<int> stream(List<String> log) async* {
+ log.add("^");
+ try {
+ log.add("?1");
+ yield 1;
+ log.add("?2");
+ yield 2;
+ log.add("?3");
+ yield 3;
+ } finally {
+ log.add(r"$");
+ }
+}
+
+Stream<int> consume(List<String> log,
+ {int breakAt = -1,
+ int yieldAt = -1,
+ int yieldStarAt = -1,
+ int pauseAt = -1}) async* {
+ // Create stream.
+ var s = stream(log);
+ log.add("(");
+ // The "consume loop".
+ await for (var event in s) {
+ // Should be acting synchronously wrt. the delivery of the event.
+ // The source stream should be at the yield now.
+ log.add("!$event");
+ if (event == pauseAt) {
+ log.add("p$event[");
+ // Async operation causes subscription to pause.
+ // Nothing should happen in the source stream
+ // until the end of the loop body where the subscription is resumed.
+ await Future.delayed(Duration(microseconds: 1));
+ log.add("]");
+ }
+ if (event == yieldAt) {
+ log.add("y$event[");
+ // Yield may cause subscription to pause or cancel.
+ // This loop should stay at the yield until the event has been delieverd.
+ // If the receiver pauses or cancels, we delay or break the loop here.
+ yield event;
+ log.add("]");
+ }
+ if (event == yieldStarAt) {
+ log.add("Y$event[");
+ // Yield* will always cause the subscription for this loop to pause.
+ // If the listener pauses, this stream is paused. If the listener cancels,
+ // this stream is cancelled, and the yield* acts like return, cancelling
+ // the loop subscription and waiting for the cancel future.
+ yield* Stream<int>.fromIterable([event]);
+ log.add("]");
+ }
+ if (event == breakAt) {
+ log.add("b$event");
+ // Breaks the loop. This cancels the loop subscription and waits for the
+ // cancel future.
+ break;
+ }
+ }
+ // Done event from stream or cancel future has completed.
+ log.add(")");
+}
+
+main() async {
+ asyncStart();
+
+ // Just run the loop over the stream. The consume stream emits no events.
+ {
+ var log = <String>[];
+ await for (var _ in consume(log)) {
+ throw "unreachable";
+ }
+ await Future.delayed(Duration(milliseconds: 1));
+ var trace = log.join("");
+ Expects.equals(r"(^?1!1?2!2?3!3$)", trace, "straight through");
+ }
+
+ // Pause at 1, then resume.
+ // Consume loop forces a pause when it receives the 1 event.
+ // Nothing should happen until that pause is resumed.
+ {
+ var log = <String>[];
+ await for (var _ in consume(log, pauseAt: 1)) {
+ throw "unreachable";
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "pause at 1";
+ if (trace.contains("p1[?2")) {
+ message += " (did not pause in time)";
+ }
+ Expects.equals(r"(^?1!1p1[]?2!2?3!3$)", trace, message);
+ }
+
+ // Break at 1.
+ // Consume loop breaks after receiving the 1 event.
+ // The consume stream emits no events.
+ {
+ var log = <String>[];
+ await for (var _ in consume(log, breakAt: 1)) {
+ throw "unreachable";
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "break at 1";
+ if (trace.contains("b1?2")) {
+ message += " (did not cancel in time)";
+ }
+ Expects.equals(r"(^?1!1b1$)", trace, message);
+ }
+
+ // Pause then break at 1.
+ // Consume loop pauses after receiving the 1 event,
+ // then breaks before resuming. It should still be at the yield.
+ // The consume stream emits no events.
+ {
+ var log = <String>[];
+ await for (var _ in consume(log, pauseAt: 1, breakAt: 1)) {
+ throw "unreachable";
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "pause then break at 1";
+ if (trace.contains("p1[?2")) {
+ message += " (did not pause in time)";
+ }
+ if (trace.contains("b1?2")) {
+ message += " (did not cancel in time)";
+ }
+ Expects.equals(r"(^?1!1p1[]b1$)", trace, message);
+ }
+
+ // Yield at 1.
+ // The consume loop re-emits the 1 event.
+ // The test loop should receive that event while the consume loop is still
+ // at the yield statement.
+ // The consume loop may or may not pause, it should make no difference.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldAt: 1)) {
+ log.add("e$s");
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield at 1";
+ if (trace.contains("y1[?2")) {
+ message += " (did not wait for delivery)";
+ }
+ Expects.equals(r"(^?1!1y1[e1]?2!2?3!3$)", trace, message);
+ }
+
+ // Yield at 1, then pause at yield.
+ // The consume loop re-emits the 1 event.
+ // The test loop should receive that event while the consume loop is still
+ // at the yield statement.
+ // The test loop then pauses.
+ // Nothing should happen in either the original yield
+ // or the consume-function yield until the test loop ends.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldAt: 1)) {
+ log.add("e$s<");
+ // Force pause at yield.
+ await Future.delayed(Duration(milliseconds: 1));
+ log.add(">");
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield at 1, pause at yield";
+ if (trace.contains("y1[?2")) {
+ message += " (did not wait for delivery)";
+ }
+ if (trace.contains("e1<?2")) {
+ message += " (did not pause in time)";
+ }
+ Expects.equals(r"(^?1!1y1[e1<>]?2!2?3!3$)", trace, message);
+ }
+
+ // Yield at 1, then break at yield.
+ // The consume loop re-emits the 1 event.
+ // The test loop should receive that event while the consume loop is still
+ // at the yield statement.
+ // The test loop then breaks. That makes the consume loop yield return,
+ // breaking the consume loop, which makes the source yield return.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldAt: 1)) {
+ log.add("e${s}B$s");
+ break; // Force break at yield*.
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield at 1, break at yield";
+ if (trace.contains("y1[?2")) {
+ message += " (did not wait for delivery)";
+ }
+ if (trace.contains("B1?2")) {
+ message += " (did not break in time)";
+ }
+ Expects.equals(r"(^?1!1y1[e1B1$)", trace, message);
+ }
+
+ // Yield* at 1.
+ // The consume loop re-emits a stream containing the 1 event.
+ // The test loop should receive that event before the consume loop
+ // continues from the `yield*`, which again happens before the source
+ // stream continues from its `yield`.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldStarAt: 1)) {
+ log.add("e$s");
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield* at 1";
+ if (trace.contains("Y1[?2")) {
+ message += " (did not wait for delivery)";
+ }
+ Expects.equals(r"(^?1!1Y1[e1]?2!2?3!3$)", trace, message);
+ }
+
+ // Yield* at 1, pause at yield.
+ // The consume loop re-emits a stream containing the 1 event.
+ // The test loop should receive that event before the consume loop
+ // continues from the `yield*`. The test loop then force a pause.
+ // Nothing further should happen during that pause.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldStarAt: 1)) {
+ log.add("e$s<");
+ await Future.delayed(Duration(milliseconds: 1)); // force pause.
+ log.add(">");
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield* then pause at 1";
+ if (trace.contains("Y1[?2")) {
+ message += " (did not wait for delivery)";
+ }
+ if (trace.contains("e1<?2")) {
+ message += " (did not pause in time)";
+ }
+ Expects.equals(r"(^?1!1Y1[e1<>]?2!2?3!3$)", trace, message);
+ }
+
+ // Yield* at 1, then break at 1.
+ // The consume loop re-emits a stream containing the 1 event.
+ // The test loop should receive that event before the consume loop
+ // continues from the `yield*`.
+ // When the consume loop continues, it breaks,
+ // forcing the waiting source yield to return.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldStarAt: 1, breakAt: 1)) {
+ log.add("e$s");
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield* then pause at 1";
+ if (trace.contains("Y1[?2")) {
+ message += " (did not wait for delivery)";
+ }
+ Expects.equals(r"(^?1!1Y1[e1]b1$)", trace, message);
+ }
+
+ // Yield* at 1, pause at yield, then break at 1.
+ // The consume loop re-emits a stream containing the 1 event.
+ // The test loop should receive that event before the consume loop
+ // continues from the `yield*`. After the `yield*`, the consume loop breaks.
+ // This forces the waiting source yield to return.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldStarAt: 1, breakAt: 1)) {
+ log.add("e$s<");
+ await Future.delayed(Duration(milliseconds: 1)); // force pause.
+ log.add(">");
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield* then pause at 1";
+ Expects.equals(r"(^?1!1Y1[e1<>]b1$)", trace, message);
+ }
+
+ // Yield* at 1, break at yield.
+ // The consume loop re-emits a stream containing the 1 event.
+ // The test loop should receive that event before the consume loop
+ // continues from the `yield*`. The test loop then breaks,
+ // forcing the two waiting yields to return.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldStarAt: 1)) {
+ log.add("e${s}B$s");
+ break;
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield* then break at 1";
+ if (trace.contains("Y1[?2")) {
+ message += " (did not deliver event in time)";
+ }
+ if (trace.contains("e1?2")) {
+ message += " (did not cancel in time)";
+ }
+ Expects.equals(r"(^?1!1Y1[e1B1$)", trace, message);
+ }
+
+ // Yield* at 1, pause at yield, then break at yield.
+ // The consume loop re-emits a stream containing the 1 event.
+ // The test loop should receive that event before the consume loop
+ // continues from the `yield*`. The test loop then forces a pause,
+ // and then breaks before that pause is resumed.
+ // This forces the two waiting yields to return.
+ {
+ var log = <String>[];
+ await for (var s in consume(log, yieldStarAt: 1)) {
+ log.add("e$s<");
+ await Future.delayed(Duration(milliseconds: 1)); // force pause.
+ log.add(">B$s");
+ break; // And break.
+ }
+ await Future.delayed(Duration(milliseconds: 10));
+ var trace = log.join("");
+ String message = "yield* then pause then break at 1";
+ Expects.equals(r"(^?1!1Y1[e1<>B1$)", trace, message);
+ }
+
+ Expects.summarize();
+ asyncEnd();
+}
+
+class Expects {
+ static var _errors = [];
+ static int _tests = 0;
+ static void summarize() {
+ if (_errors.isNotEmpty) {
+ var buffer = StringBuffer();
+ for (var es in _errors) {
+ buffer.writeln("FAILURE:");
+ buffer.writeln(es[0]); // error
+ buffer.writeln(es[1]); // stack trace
+ }
+ ;
+ buffer.writeln("Expectations failed: ${_errors.length}"
+ ", succeeded: ${_tests - _errors.length}");
+ throw ExpectException(buffer.toString());
+ }
+ }
+
+ static void equals(o1, o2, String message) {
+ _tests++;
+ try {
+ Expect.equals(o1, o2, message);
+ } on ExpectException catch (e) {
+ var stack = StackTrace.current;
+ _errors.add([e, stack]);
+ }
+ }
+}
diff --git a/tests/language_2/async_star/async_star_cancel_test.dart b/tests/language_2/async_star/async_star_cancel_test.dart
new file mode 100644
index 0000000..c23c6ba
--- /dev/null
+++ b/tests/language_2/async_star/async_star_cancel_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2018, 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 stream cancellation is checked immediately after delivering the
+// event, and before continuing after the yield.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+main() async {
+ asyncStart();
+ var log = [];
+ Stream<int> f() async* {
+ try {
+ log.add("-1");
+ yield 1;
+ log.add("-2");
+ yield 2;
+ } finally {
+ log.add("x");
+ }
+ }
+
+ var completer = Completer();
+ var s;
+ s = f().listen((e) {
+ log.add("+$e");
+ // The `cancel` operation makes all `yield` operations act as returns.
+ // It should make the `finally` block in `f` log an "x",
+ // and nothing else.
+ completer.complete(s.cancel());
+ }, onError: (e) {
+ // Should never be reached, but if it does, we'll make the await
+ // below terminate.
+ completer.complete(new Future.sync(() {
+ Expect.fail("$e");
+ }));
+ }, onDone: () {
+ completer.complete(null);
+ });
+ await completer.future;
+ Expect.listEquals(["-1", "+1", "x"], log, "cancel");
+ asyncEnd();
+}
diff --git a/tests/language_2/async_star/async_star_invalid_test.dart b/tests/language_2/async_star/async_star_invalid_test.dart
new file mode 100644
index 0000000..529cf25
--- /dev/null
+++ b/tests/language_2/async_star/async_star_invalid_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2018, 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 various invalid uses of `yield` are disallowed.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+var yield = 42;
+
+main() async {
+ asyncStart();
+ Stream<String> f() async* {
+ // Invalid syntax.
+ yield ("a", "b"); //# 01: compile-time error
+ yield yield "twice"; //# 02: compile-time error
+
+ // Valid but curious syntax.
+ yield throw "throw"; //# 03: runtime error
+
+ // Type error.
+ yield* "one"; //# 04: compile-time error
+
+ label: yield "ok";
+ }
+ var completer = Completer();
+ f().listen(completer.complete, onError: completer.completeError,
+ onDone: () {
+ if (!completer.isCompleted) completer.completeError("not ok?");
+ });
+ Expect.equals("ok", await completer.future);
+ asyncEnd();
+}
diff --git a/tests/language_2/async_star/async_star_test.dart b/tests/language_2/async_star/async_star_test.dart
new file mode 100644
index 0000000..819039e
--- /dev/null
+++ b/tests/language_2/async_star/async_star_test.dart
@@ -0,0 +1,195 @@
+// Copyright (c) 2018, 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 "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+main() async {
+ asyncStart();
+ // Normal operations.
+ {
+ Stream<int> f() async* {
+ yield 1;
+ yield 2;
+ yield 3;
+ }
+
+ Expect.listEquals([1, 2, 3], await f().toList(), "basic1");
+ }
+
+ {
+ Stream<int> f() async* {
+ yield 1;
+ yield 2;
+ yield 3;
+ }
+
+ var log = [];
+ var completer = Completer();
+ f().listen(log.add,
+ onError: (e) {
+ // Shouldn't be reached.
+ completer.complete(new Future.sync(() {
+ Expect.fail("$e");
+ }));
+ },
+ onDone: () => completer.complete(null));
+ await completer.future;
+ Expect.listEquals([1, 2, 3], log, "basic2");
+ }
+
+ {
+ var log = [];
+ Stream<int> f() async* {
+ log.add("-1");
+ yield 1;
+ log.add("-2");
+ yield 2;
+ }
+
+ await f().forEach((e) {
+ log.add("+$e");
+ });
+ Expect.listEquals(["-1", "+1", "-2", "+2"], log, "basic3");
+ }
+
+ {
+ var log = [];
+ Stream<int> f() async* {
+ log.add("-1");
+ yield 1;
+ log.add("-2");
+ yield 2;
+ }
+
+ await for (var e in f()) {
+ log.add("+$e");
+ }
+ Expect.listEquals(["-1", "+1", "-2", "+2"], log, "basic4");
+ }
+
+ // async
+ {
+ Stream<int> f() async* {
+ yield 1;
+ await Future(() {});
+ yield 2;
+ await Future(() {});
+ yield 3;
+ }
+
+ Expect.listEquals([1, 2, 3], await f().toList(), "async");
+ }
+
+ // Yield*
+ {
+ Stream<int> f(n) async* {
+ yield n;
+ if (n == 0) return;
+ yield* f(n - 1);
+ yield n;
+ }
+
+ Expect.listEquals([3, 2, 1, 0, 1, 2, 3], await f(3).toList(), "yield*");
+ }
+
+ // Errors
+ {
+ var log = [];
+ Stream<int> f() async* {
+ yield 1;
+ throw "error";
+ }
+
+ await f().handleError((e) {
+ log.add(e);
+ }).forEach(log.add);
+ Expect.listEquals([1, "error"], log, "error");
+ }
+
+ {
+ var log = [];
+ Stream<int> f() async* {
+ yield 1;
+ yield* Future<int>.error("error").asStream(); // Emits error as error.
+ yield 3;
+ }
+
+ await f().handleError((e) {
+ log.add(e);
+ }).forEach(log.add);
+ Expect.listEquals([1, "error", 3], log, "error2");
+ }
+
+ // Pause is checked after delivering event.
+ {
+ var log = [];
+ Stream<int> f() async* {
+ log.add("-1");
+ yield 1;
+ log.add("-2");
+ yield 2;
+ }
+
+ var completer = Completer();
+ var s;
+ s = f().listen((e) {
+ log.add("+$e");
+ s.pause(Future(() {}));
+ log.add("++$e");
+ }, onError: (e) {
+ completer.complete(new Future.sync(() {
+ Expect.fail("$e");
+ }));
+ }, onDone: () => completer.complete(null));
+ await completer.future;
+ Expect.listEquals(["-1", "+1", "++1", "-2", "+2", "++2"], log, "pause");
+ }
+
+ // Await for-loop pauses between events.
+ {
+ var log = [];
+ Stream<int> f() async* {
+ log.add("-1");
+ yield 1;
+ log.add("-2");
+ yield 2;
+ }
+
+ await for (var e in f()) {
+ log.add("+$e");
+ await Future(() {}); // One timer tick.
+ log.add("++$e");
+ }
+ Expect.listEquals(["-1", "+1", "++1", "-2", "+2", "++2"], log, "looppause");
+ }
+
+ // Await for-loop break works immediately.
+ {
+ var log = [];
+ Stream<int> f() async* {
+ try {
+ log.add("-1");
+ yield 1;
+ log.add("-2");
+ yield 2;
+ log.add("-3");
+ yield 3;
+ } finally {
+ log.add("x");
+ }
+ }
+
+ await for (var e in f()) {
+ log.add("+$e");
+ await Future(() {}); // One timer tick, pauses function at yield.
+ log.add("++$e");
+ if (e == 2) break;
+ }
+ Expect.listEquals(
+ ["-1", "+1", "++1", "-2", "+2", "++2", "x"], log, "loop-pause-break");
+ }
+ asyncEnd();
+}
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index a2102b3..1edba47 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -5,6 +5,8 @@
[ $compiler == dart2js ]
arithmetic_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
async_star_cancel_while_paused_test: RuntimeError # Issue 22853
bit_operations_test: RuntimeError, OK # non JS number semantics
bit_operations_test/03: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index feca149..9e924cf 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -12,6 +12,9 @@
accessor_conflict_import_test: CompileTimeError # Issue 25626
additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
assertion_test: RuntimeError # Issue 30326; Expect.equals(expected: <1>, actual: <0>) fails.
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_test: RuntimeError
async_star_test/01: RuntimeError
async_star_test/03: RuntimeError
async_star_test/04: RuntimeError
@@ -158,6 +161,8 @@
void/void_type_usage_test/final_local_for_in2: MissingCompileTimeError
[ $compiler == dartdevk ]
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_test: RuntimeError
built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 30450, test name contains hyphen
built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 30450, test name contains hyphen
built_in_identifier_type_annotation_test/dynamic-list: RuntimeError # Issue 30450, test name contains hyphen
@@ -317,6 +322,7 @@
[ $compiler == dartdevc || $compiler == dartdevk ]
arithmetic_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
async_covariant_type_test: RuntimeError # Check too late
+async_star/async_star_await_for_test: RuntimeError
async_star_cancel_while_paused_test: RuntimeError # Issue 29920; Uncaught Expect.listEquals(list length, expected: <4>, actual: <3>) fails: Next element <*3>
async_star_pause_test: RuntimeError # Uncaught Expect.listEquals(at index 2, expected: <0+>, actual: <0!>) fails
async_star_test/02: RuntimeError
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index b514980..bd08604 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -359,6 +359,10 @@
vm/precompiled_static_initializer_test: Pass, Slow
[ $compiler == dartkp && $mode == product && $runtime == dart_precompiled && $strong ]
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_invalid_test/none: RuntimeError
+async_star/async_star_test: RuntimeError
vm/type_vm_test/28: MissingRuntimeError
vm/type_vm_test/29: MissingRuntimeError
vm/type_vm_test/30: MissingRuntimeError
@@ -406,6 +410,13 @@
assertion_initializer_const_error2_test/cc11: Crash
async_await_test: RuntimeError
async_return_types_test/nestedFuture: Fail
+async_star/async_star_cancel_test: DartkCrash
+async_star/async_star_invalid_test/01: DartkCrash
+async_star/async_star_invalid_test/02: DartkCrash
+async_star/async_star_invalid_test/03: DartkCrash
+async_star/async_star_invalid_test/04: DartkCrash
+async_star/async_star_invalid_test/none: DartkCrash
+async_star/async_star_test: DartkCrash
compile_time_constant_checked_test/02: MissingCompileTimeError
covariance_type_parameter_test/01: RuntimeError
covariance_type_parameter_test/02: RuntimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index c813c7b..d70b100 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -13,6 +13,15 @@
[ $compiler != dart2analyzer && $runtime == dart_precompiled ]
mixin_mixin2_test: Skip
+[ $compiler == precompiler && $runtime == dart_precompiled ]
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_invalid_test/01: MissingCompileTimeError
+async_star/async_star_invalid_test/02: MissingCompileTimeError
+async_star/async_star_invalid_test/04: MissingCompileTimeError
+async_star/async_star_invalid_test/none: RuntimeError
+async_star/async_star_test: RuntimeError
+
[ $runtime == dart_precompiled && $minified ]
cyclic_type_test/*: Skip
enum_duplicate_test/*: Skip # Uses Enum.toString()
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index b696b0f..47d27f2 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -18,6 +18,9 @@
set_literals/*: Skip
[ $runtime == vm ]
+async_star/async_star_await_for_test: RuntimeError
+async_star/async_star_cancel_test: RuntimeError
+async_star/async_star_test: RuntimeError
set_literals/*: Skip
[ $arch == arm64 && $runtime == vm ]