| Index: lib/src/backend/invoker.dart
|
| diff --git a/lib/src/backend/invoker.dart b/lib/src/backend/invoker.dart
|
| index 228b90e64b46583dd4eb7f5382b8425b5122d05c..057e704918cc1e64276066992b48eb151c815aa0 100644
|
| --- a/lib/src/backend/invoker.dart
|
| +++ b/lib/src/backend/invoker.dart
|
| @@ -10,6 +10,7 @@ import 'package:stack_trace/stack_trace.dart';
|
|
|
| import '../frontend/expect.dart';
|
| import '../utils.dart';
|
| +import 'closed_exception.dart';
|
| import 'live_test.dart';
|
| import 'live_test_controller.dart';
|
| import 'metadata.dart';
|
| @@ -55,6 +56,14 @@ class Invoker {
|
| LiveTest get liveTest => _controller.liveTest;
|
| LiveTestController _controller;
|
|
|
| + /// Whether the test has been closed.
|
| + ///
|
| + /// Once the test is closed, [expect] and [expectAsync] will throw
|
| + /// [ClosedException]s whenever accessed to help the test stop executing as
|
| + /// soon as possible.
|
| + bool get closed => _closed;
|
| + bool _closed = false;
|
| +
|
| /// The test being run.
|
| LocalTest get _test => liveTest.test as LocalTest;
|
|
|
| @@ -76,7 +85,9 @@ class Invoker {
|
| }
|
|
|
| Invoker._(Suite suite, LocalTest test) {
|
| - _controller = new LiveTestController(suite, test, _onRun);
|
| + _controller = new LiveTestController(suite, test, _onRun, () {
|
| + _closed = true;
|
| + });
|
| }
|
|
|
| /// Tells the invoker that there's a callback running that it should wait for
|
| @@ -87,7 +98,10 @@ class Invoker {
|
| /// that only successful tests wait for outstanding callbacks; as soon as a
|
| /// test experiences an error, any further calls to [addOutstandingCallback]
|
| /// or [removeOutstandingCallback] will do nothing.
|
| + ///
|
| + /// Throws a [ClosedException] if this test has been closed.
|
| void addOutstandingCallback() {
|
| + if (closed) throw new ClosedException();
|
| _outstandingCallbacks++;
|
| }
|
|
|
| @@ -162,10 +176,6 @@ class Invoker {
|
| new Future(_test._body)
|
| .then((_) => removeOutstandingCallback());
|
|
|
| - // Explicitly handle an error here so that we can return the [Future].
|
| - // If a [Future] returned from an error zone would throw an error
|
| - // through the zone boundary, it instead never completes, and we want to
|
| - // avoid that.
|
| _completer.future.then((_) {
|
| if (_test._tearDown == null) return null;
|
| return new Future.sync(_test._tearDown);
|
|
|