| Index: lib/src/backend/invoker.dart
|
| diff --git a/lib/src/backend/invoker.dart b/lib/src/backend/invoker.dart
|
| index da978ba67aa09edaecd4bd9a25bc3d190e38f563..86b5a0c7728ce4f54aaf35aadefa2a580c717245 100644
|
| --- a/lib/src/backend/invoker.dart
|
| +++ b/lib/src/backend/invoker.dart
|
| @@ -97,6 +97,12 @@ class Invoker {
|
| return Zone.current[#test.invoker];
|
| }
|
|
|
| + /// The zone that the top level of [_test.body] is running in.
|
| + ///
|
| + /// Tracking this ensures that [_timeoutTimer] isn't created in a
|
| + /// timer-mocking zone created by the test.
|
| + Zone _invokerZone;
|
| +
|
| /// The timer for tracking timeouts.
|
| ///
|
| /// This will be `null` until the test starts running.
|
| @@ -171,12 +177,14 @@ class Invoker {
|
| if (_timeoutTimer != null) _timeoutTimer.cancel();
|
|
|
| var timeout = metadata.timeout.apply(new Duration(seconds: 30));
|
| - _timeoutTimer = new Timer(timeout, () {
|
| + if (timeout == null) return;
|
| + _timeoutTimer = _invokerZone.createTimer(timeout,
|
| + Zone.current.bindCallback(() {
|
| if (liveTest.isComplete) return;
|
| _handleError(
|
| new TimeoutException(
|
| "Test timed out after ${niceDuration(timeout)}.", timeout));
|
| - });
|
| + }));
|
| }
|
|
|
| /// Notifies the invoker of an asynchronous error.
|
| @@ -215,6 +223,8 @@ class Invoker {
|
| // stable versions.
|
| Chain.capture(() {
|
| runZonedWithValues(() {
|
| + _invokerZone = Zone.current;
|
| +
|
| heartbeat();
|
|
|
| // Run the test asynchronously so that the "running" state change has
|
| @@ -234,7 +244,7 @@ class Invoker {
|
| return waitForOutstandingCallbacks(() =>
|
| runZoned(_test._tearDown, onError: _handleError));
|
| }).then((_) {
|
| - _timeoutTimer.cancel();
|
| + if (_timeoutTimer != null) _timeoutTimer.cancel();
|
| _controller.setState(
|
| new State(Status.complete, liveTest.state.result));
|
|
|
|
|