Run outer tearDown()s even if inner ones fail.
R=kevmoo@google.com
Review URL: https://codereview.chromium.org//1364893004 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04d6eea..f46c883 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.12.4+9
+
+* If a `tearDown()` callback throws an error, outer `tearDown()` callbacks are
+ still executed.
+
## 0.12.4+8
* Don't compile tests to JavaScript when running via `pub serve` on Dartium or
diff --git a/lib/src/backend/group.dart b/lib/src/backend/group.dart
index 69144c6..d1bc67a 100644
--- a/lib/src/backend/group.dart
+++ b/lib/src/backend/group.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import '../utils.dart';
+import 'invoker.dart';
import 'metadata.dart';
/// A group contains multiple tests and subgroups.
@@ -76,13 +77,25 @@
Future runTearDown() {
// TODO(nweiz): Use async/await here once issue 23497 has been fixed in two
// stable versions.
- if (parent != null) {
- return new Future.sync(() {
- if (tearDown != null) return tearDown();
- }).then((_) => parent.runTearDown());
+ if (parent == null) {
+ return tearDown == null ? new Future.value() : new Future.sync(tearDown);
}
- if (tearDown != null) return new Future.sync(tearDown);
- return new Future.value();
+ return _errorsDontStopTest(() {
+ if (tearDown != null) return tearDown();
+ }).then((_) => parent.runTearDown());
+ }
+
+ /// Runs [body] with special error-handling behavior.
+ ///
+ /// Errors emitted [body] will still cause be the test to fail, but they won't
+ /// cause it to *stop*. In particular, they won't remove any outstanding
+ /// callbacks registered outside of [body].
+ Future _errorsDontStopTest(body()) {
+ var completer = new Completer();
+ Invoker.current.waitForOutstandingCallbacks(() {
+ new Future.sync(body).whenComplete(completer.complete);
+ });
+ return completer.future;
}
}
diff --git a/pubspec.yaml b/pubspec.yaml
index bedb824..89683f2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: test
-version: 0.12.4+8
+version: 0.12.4+9
author: Dart Team <misc@dartlang.org>
description: A library for writing dart unit tests.
homepage: https://github.com/dart-lang/test
diff --git a/test/backend/declarer_test.dart b/test/backend/declarer_test.dart
index 4873b61..3815367 100644
--- a/test/backend/declarer_test.dart
+++ b/test/backend/declarer_test.dart
@@ -389,6 +389,26 @@
expect(outerTearDownRun, isTrue);
});
+ test("runs outer callbacks even when inner ones fail", () async {
+ var outerTearDownRun = false;
+ _declarer.tearDown(() {
+ return new Future(() => outerTearDownRun = true);
+ });
+
+ _declarer.group("inner", () {
+ _declarer.tearDown(() {
+ throw 'inner error';
+ });
+
+ _declarer.test("description", expectAsync(() {
+ expect(outerTearDownRun, isFalse);
+ }, max: 1));
+ });
+
+ await _runTest(0, shouldFail: true);
+ expect(outerTearDownRun, isTrue);
+ });
+
test("can't be called multiple times", () {
_declarer.group("group", () {
_declarer.tearDown(() {});