|  | // Copyright (c) 2022, 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. | 
|  |  | 
|  | // @dart = 2.9 | 
|  |  | 
|  | import 'dart:isolate'; | 
|  | import 'dart:async'; | 
|  | import 'package:async_helper/async_helper.dart'; | 
|  | import 'package:expect/expect.dart'; | 
|  |  | 
|  | void main() async { | 
|  | asyncStart(); | 
|  | // Sending result back. | 
|  | await testValue(); | 
|  | await testAsyncValue(); | 
|  | // Sending error from computation back. | 
|  | await testError(); | 
|  | await testAsyncError(); | 
|  | // Sending uncaught async error back. | 
|  | await testUncaughtError(); | 
|  | // Not sending anything back before isolate dies. | 
|  | await testIsolateHangs(); | 
|  | await testIsolateKilled(); | 
|  | await testIsolateExits(); | 
|  | // Failing to start. | 
|  | await testInvalidMessage(); | 
|  | asyncEnd(); | 
|  | } | 
|  |  | 
|  | final StackTrace stack = StackTrace.fromString("Known Stacktrace"); | 
|  | final ArgumentError error = ArgumentError.value(42, "name"); | 
|  |  | 
|  | var variable = 0; | 
|  |  | 
|  | Future<void> testValue() async { | 
|  | var value = await Isolate.run<int>(() { | 
|  | variable = 1; // Changed in other isolate! | 
|  | Expect.equals(1, variable); | 
|  | return 42; | 
|  | }); | 
|  | Expect.equals(42, value); | 
|  | Expect.equals(0, variable); | 
|  | } | 
|  |  | 
|  | Future<void> testAsyncValue() async { | 
|  | var value = await Isolate.run<int>(() async { | 
|  | variable = 1; | 
|  | return 42; | 
|  | }); | 
|  | Expect.equals(42, value); | 
|  | Expect.equals(0, variable); | 
|  | } | 
|  |  | 
|  | Future<void> testError() async { | 
|  | var e = await asyncExpectThrows<ArgumentError>(Isolate.run<int>(() { | 
|  | variable = 1; | 
|  | Error.throwWithStackTrace(error, stack); | 
|  | })); | 
|  | Expect.equals(42, e.invalidValue); | 
|  | Expect.equals("name", e.name); | 
|  | Expect.equals(0, variable); | 
|  | } | 
|  |  | 
|  | Future<void> testAsyncError() async { | 
|  | var e = await asyncExpectThrows<ArgumentError>(Isolate.run<int>(() async { | 
|  | variable = 1; | 
|  | Error.throwWithStackTrace(error, stack); | 
|  | })); | 
|  | Expect.equals(42, e.invalidValue); | 
|  | Expect.equals("name", e.name); | 
|  | Expect.equals(0, variable); | 
|  | } | 
|  |  | 
|  | Future<void> testUncaughtError() async { | 
|  | var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async { | 
|  | variable = 1; | 
|  | unawaited(Future.error(error, stack)); // Uncaught error | 
|  | await Completer().future; // Never completes. | 
|  | return -1; | 
|  | })); | 
|  |  | 
|  | Expect.type<RemoteError>(e); | 
|  | Expect.equals(error.toString(), e.toString()); | 
|  | Expect.equals(0, variable); | 
|  | } | 
|  |  | 
|  | Future<void> testIsolateHangs() async { | 
|  | var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async { | 
|  | variable = 1; | 
|  | await Completer<Never>().future; // Never completes. | 
|  | // Isolate should end while hanging here, because its event loop is empty. | 
|  | })); | 
|  | Expect.type<RemoteError>(e); | 
|  | Expect.equals("Computation ended without result", e.toString()); | 
|  | Expect.equals(0, variable); | 
|  | } | 
|  |  | 
|  | Future<void> testIsolateKilled() async { | 
|  | var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async { | 
|  | variable = 1; | 
|  | Isolate.current.kill(); // Send kill request. | 
|  | await Completer<Never>().future; // Never completes. | 
|  | // Isolate should get killed while hanging here. | 
|  | })); | 
|  | Expect.type<RemoteError>(e); | 
|  | Expect.equals("Computation ended without result", e.toString()); | 
|  | Expect.equals(0, variable); | 
|  | } | 
|  |  | 
|  | Future<void> testIsolateExits() async { | 
|  | var e = await asyncExpectThrows<RemoteError>(Isolate.run<int>(() async { | 
|  | variable = 1; | 
|  | Isolate.exit(); // Dies here without sending anything back. | 
|  | })); | 
|  | Expect.type<RemoteError>(e); | 
|  | Expect.equals("Computation ended without result", e.toString()); | 
|  | Expect.equals(0, variable); | 
|  | } | 
|  |  | 
|  | Future<void> testInvalidMessage() async { | 
|  | // Regression test for http://dartbug.com/48516 | 
|  | var unsendable = RawReceivePort(); | 
|  | await asyncExpectThrows<Error>(Isolate.run<void>(() => unsendable)); | 
|  | unsendable.close(); | 
|  | // Test should not hang. | 
|  | } |