Index: test/backend/invoker_test.dart |
diff --git a/test/backend/invoker_test.dart b/test/backend/invoker_test.dart |
index be27391e8fad341e5fdd39fb0c5a0a0dad74e93c..58fdfa09b86c89fa3d892a5f4966747a3b64115c 100644 |
--- a/test/backend/invoker_test.dart |
+++ b/test/backend/invoker_test.dart |
@@ -429,6 +429,55 @@ void main() { |
equals(const State(Status.complete, Result.error))); |
}); |
}); |
+ |
+ test("an asynchronous error in tearDown causes the test to error", () { |
+ var liveTest = _localTest(() {}, tearDown: () { |
+ Invoker.current.addOutstandingCallback(); |
+ new Future(() => throw "oh no"); |
+ }).load(suite); |
+ |
+ expectSingleError(liveTest); |
+ return liveTest.run(); |
+ }); |
+ |
+ test("an error reported in the test body after tearDown begins running " |
+ "doesn't stop tearDown", () { |
+ var tearDownComplete = false;; |
+ var completer = new Completer(); |
+ |
+ var liveTest; |
+ liveTest = _localTest(() { |
+ completer.future.then((_) => throw "not again"); |
+ throw "oh no"; |
+ }, tearDown: () { |
+ completer.complete(); |
+ |
+ // Pump the event queue so that we will run the following code after the |
+ // test body has thrown a second error. |
+ Invoker.current.addOutstandingCallback(); |
+ pumpEventQueue().then((_) { |
+ Invoker.current.removeOutstandingCallback(); |
+ tearDownComplete = true; |
+ }); |
+ }).load(suite); |
+ |
+ expectStates(liveTest, [ |
+ const State(Status.running, Result.success), |
+ const State(Status.complete, Result.error) |
+ ]); |
+ |
+ expectErrors(liveTest, [ |
+ (error) { |
+ expect(lastState.status, equals(Status.complete)); |
+ expect(error, equals("oh no")); |
+ }, |
+ (error) => expect(error, equals("not again")) |
+ ]); |
+ |
+ return liveTest.run().then((_) { |
+ expect(tearDownComplete, isTrue); |
+ }); |
+ }); |
}); |
test("a test doesn't complete until there are no outstanding callbacks", |
@@ -473,6 +522,56 @@ void main() { |
}); |
}); |
+ test("a test's tearDown doesn't complete until there are no outstanding " |
+ "callbacks", () { |
+ var outstandingCallbackRemoved = false; |
+ var liveTest = _localTest(() {}, tearDown: () { |
+ Invoker.current.addOutstandingCallback(); |
+ |
+ // Pump the event queue to make sure the test isn't coincidentally |
+ // completing after the outstanding callback is removed. |
+ pumpEventQueue().then((_) { |
+ outstandingCallbackRemoved = true; |
+ Invoker.current.removeOutstandingCallback(); |
+ }); |
+ }).load(suite); |
+ |
+ liveTest.onError.listen(expectAsync((_) {}, count: 0)); |
+ |
+ return liveTest.run().then((_) { |
+ expect(outstandingCallbackRemoved, isTrue); |
+ }); |
+ }); |
+ |
+ test("a test body's outstanding callbacks can't complete its tearDown", () { |
+ var outstandingCallbackRemoved = false; |
+ var completer = new Completer(); |
+ var liveTest = _localTest(() { |
+ // Once the tearDown runs, remove an outstanding callback to see if it |
+ // causes the tearDown to complete. |
+ completer.future.then((_) { |
+ Invoker.current.removeOutstandingCallback(); |
+ }); |
+ }, tearDown: () { |
+ Invoker.current.addOutstandingCallback(); |
+ |
+ // This will cause the test BODY to remove an outstanding callback, which |
+ // shouldn't cause the test to complete. |
+ completer.complete(); |
+ |
+ pumpEventQueue().then((_) { |
+ outstandingCallbackRemoved = true; |
+ Invoker.current.removeOutstandingCallback(); |
+ }); |
+ }).load(suite); |
+ |
+ liveTest.onError.listen(expectAsync((_) {}, count: 0)); |
+ |
+ return liveTest.run().then((_) { |
+ expect(outstandingCallbackRemoved, isTrue); |
+ }); |
+ }); |
+ |
test("a test's prints are captured and reported", () { |
expect(() { |
var liveTest = _localTest(() { |