Index: pkg/unittest/lib/src/config.dart |
=================================================================== |
--- pkg/unittest/lib/src/config.dart (revision 22128) |
+++ pkg/unittest/lib/src/config.dart (working copy) |
@@ -4,6 +4,18 @@ |
part of unittest; |
+// A custom failure handler for [expect] that routes expect failures |
+// to the config. |
+class _ExpectFailureHandler extends DefaultFailureHandler { |
+ Configuration _config; |
+ |
+ _ExpectFailureHandler(this._config) : super(); |
+ |
+ void fail(String reason) { |
+ _config.onExpectFailure(reason); |
+ } |
+} |
+ |
/** |
* Hooks to configure the unittest library for different platforms. This class |
* implements the API in a platform-independent way. Tests that want to take |
@@ -30,6 +42,29 @@ |
final bool autoStart = true; |
/** |
+ * If true (the default), throw an exception at the end if any tests failed. |
+ */ |
+ bool throwOnTestFailures = true; |
+ |
+ /** |
+ * If true (the default), then tests will stop after the first failed |
+ * [expect]. If false, failed [expect]s will not cause the test |
+ * to stop (other exceptions will still terminate the test). |
+ */ |
+ bool stopTestOnExpectFailure = true; |
+ |
+ // If stopTestOnExpectFailure is false, we need to capture failures, which |
+ // we do with this List. |
+ List _testLogBuffer = new List(); |
+ |
+ /** |
+ * The constructor sets up a failure handler for [expect] that redirects |
+ * [expect] failures to [onExpectFailure]. |
+ */ |
+ Configuration() { |
+ configureExpectFailureHandler(new _ExpectFailureHandler(this)); |
+ } |
+ /** |
* Called as soon as the unittest framework becomes initialized. This is done |
* even before tests are added to the test framework. It might be used to |
* determine/debug errors that occur before the test harness starts executing. |
@@ -46,18 +81,48 @@ |
/** |
* Called when each test starts. Useful to show intermediate progress on |
- * a test suite. |
+ * a test suite. Derived classes should call this first before their own |
+ * override code. |
*/ |
void onTestStart(TestCase testCase) { |
assert(testCase != null); |
+ _testLogBuffer.clear(); |
} |
/** |
* Called when each test is first completed. Useful to show intermediate |
- * progress on a test suite. |
+ * progress on a test suite. Derived classes should call this first |
+ * before their own override code. |
*/ |
void onTestResult(TestCase testCase) { |
assert(testCase != null); |
+ if (!stopTestOnExpectFailure && _testLogBuffer.length > 0) { |
+ // Write the message/stack pairs up to the last pairs. |
+ var reason = new StringBuffer(); |
+ for (var i = 0; i < _testLogBuffer.length - 2; i += 2) { |
+ reason.write(_testLogBuffer[i]); |
+ reason.write('\n'); |
+ reason.write(_formatStack(_testLogBuffer[i+1])); |
+ reason.write('\n'); |
+ } |
+ // Write the last message. |
+ reason.write(_testLogBuffer[_testLogBuffer.length - 2]); |
+ if (testCase.result == PASS) { |
+ testCase._result = FAIL; |
+ testCase._message = reason.toString(); |
+ // Use the last stack as the overall failure stack. |
+ testCase._stackTrace = |
+ _formatStack(_testLogBuffer[_testLogBuffer.length - 1]); |
+ } else { |
+ // Add the last stack to the message; we have a further stack |
+ // caused by some other failure. |
+ reason.write(_formatStack(_testLogBuffer[_testLogBuffer.length - 1])); |
+ reason.write('\n'); |
+ // Add the existing reason to the end of the expect log to |
+ // create the final message. |
+ testCase._message = '${reason.toString()}\n${testCase._message}'; |
+ } |
+ } |
} |
/** |
@@ -78,6 +143,23 @@ |
} |
/** |
+ * Handles failures from expect(). The default in |
+ * this base configuration is to throw an exception; |
+ */ |
+ void onExpectFailure(String reason) { |
+ if (stopTestOnExpectFailure) { |
+ throw new TestFailure(reason); |
+ } else { |
+ _testLogBuffer.add(reason); |
+ try { |
+ throw ''; |
+ } catch (_, stack) { |
+ _testLogBuffer.add(stack); |
+ } |
+ } |
+ } |
+ |
+ /** |
* Called with the result of all test cases. The default implementation prints |
* the result summary using the built-in [print] command. Browser tests |
* commonly override this to reformat the output. |
@@ -127,7 +209,9 @@ |
_receivePort.close(); |
} else { |
_receivePort.close(); |
- throw new Exception('Some tests failed.'); |
+ if (throwOnTestFailures) { |
+ throw new Exception('Some tests failed.'); |
+ } |
} |
} |