Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of unittest; | 5 part of unittest; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Represents the state for an individual unit test. | 8 * Represents the state for an individual unit test. |
| 9 * | 9 * |
| 10 * Create by calling [test] or [solo_test]. | 10 * Create by calling [test] or [solo_test]. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 | 60 |
| 61 Completer _testComplete; | 61 Completer _testComplete; |
| 62 | 62 |
| 63 TestCase._internal(this.id, this.description, this.testFunction) | 63 TestCase._internal(this.id, this.description, this.testFunction) |
| 64 : currentGroup = _currentContext.fullName, | 64 : currentGroup = _currentContext.fullName, |
| 65 setUp = _currentContext.testSetup, | 65 setUp = _currentContext.testSetup, |
| 66 tearDown = _currentContext.testTeardown; | 66 tearDown = _currentContext.testTeardown; |
| 67 | 67 |
| 68 bool get isComplete => !enabled || result != null; | 68 bool get isComplete => !enabled || result != null; |
| 69 | 69 |
| 70 void _prepTest() { | 70 errorHandler(stage) => (e) { |
| 71 _config.onTestStart(this); | 71 var stack = getAttachedStackTrace(e); |
| 72 _startTime = new DateTime.now(); | 72 if (stack == null) stack = ''; |
| 73 _runningTime = null; | 73 else stack = "$stack"; |
|
Siggi Cherem (dart-lang)
2013/07/01 18:24:31
style: if-else need { } and separate lines for eac
| |
| 74 } | 74 if (result == null || result == PASS) { |
| 75 | 75 if (e is TestFailure) { |
| 76 Future _runTest() { | 76 fail("$e", stack); |
| 77 _prepTest(); | 77 } else { |
| 78 // Increment/decrement callbackFunctionsOutstanding to prevent | 78 error("$stage failed: Caught $e", stack); |
| 79 // synchronous 'async' callbacks from causing the test to be | 79 } |
| 80 // marked as complete before the body is completely executed. | |
| 81 ++_callbackFunctionsOutstanding; | |
| 82 var f = testFunction(); | |
| 83 --_callbackFunctionsOutstanding; | |
| 84 if (f is Future) { | |
| 85 return f.then((_) => _finishTest()) | |
| 86 .catchError((error) { | |
| 87 var stack = getAttachedStackTrace(error); | |
| 88 _registerException(this, error, stack); | |
| 89 }); | |
| 90 } else { | |
| 91 _finishTest(); | |
| 92 return null; | |
| 93 } | 80 } |
| 94 } | 81 }; |
| 95 | |
| 96 void _finishTest() { | |
| 97 if (result == null && _callbackFunctionsOutstanding == 0) { | |
| 98 pass(); | |
| 99 } | |
| 100 } | |
| 101 | 82 |
| 102 /** | 83 /** |
| 103 * Perform any associated [_setUp] function and run the test. Returns | 84 * Perform any associated [_setUp] function and run the test. Returns |
| 104 * a [Future] that can be used to schedule the next test. If the test runs | 85 * a [Future] that can be used to schedule the next test. If the test runs |
| 105 * to completion synchronously, or is disabled, null is returned, to | 86 * to completion synchronously, or is disabled, null is returned, to |
| 106 * tell unittest to schedule the next test immediately. | 87 * tell unittest to schedule the next test immediately. |
| 107 */ | 88 */ |
| 108 Future _run() { | 89 Future _run() { |
| 109 if (!enabled) return null; | 90 if (!enabled) return new Future.value(); |
| 110 | 91 |
| 111 _result = _stackTrace = null; | 92 _result = _stackTrace = null; |
| 112 _message = ''; | 93 _message = ''; |
| 113 _doneTeardown = false; | |
| 114 var rtn = setUp == null ? null : setUp(); | |
| 115 if (rtn is Future) { | |
| 116 rtn.then((_) => _runTest()) | |
| 117 .catchError((e) { | |
| 118 _prepTest(); | |
| 119 // Calling error() will result in the tearDown being done. | |
| 120 // One could debate whether tearDown should be done after | |
| 121 // a failed setUp. There is no right answer, but doing it | |
| 122 // seems to be the more conservative approach, because | |
| 123 // unittest will not stop at a test failure. | |
| 124 var stack = getAttachedStackTrace(e); | |
| 125 if (stack == null) stack = ''; | |
| 126 error("$description: Test setup failed: $e", "$stack"); | |
| 127 }); | |
| 128 } else { | |
| 129 var f = _runTest(); | |
| 130 if (f != null) { | |
| 131 return f; | |
| 132 } | |
| 133 } | |
| 134 if (result == null) { // Not complete. | |
| 135 _testComplete = new Completer(); | |
| 136 return _testComplete.future; | |
| 137 } | |
| 138 return null; | |
| 139 } | |
| 140 | 94 |
| 141 void _notifyComplete() { | 95 var f = (setUp == null) ? new Future.value() : new Future(setUp); |
| 142 if (_testComplete != null) { | 96 return f.catchError(errorHandler('Setup')) |
| 143 _testComplete.complete(this); | 97 .then((_) { |
| 144 _testComplete = null; | 98 // Skip the test if setup failed. |
| 145 } | 99 if (result != null) return new Future.value(); |
| 100 _config.onTestStart(this); | |
| 101 _startTime = new DateTime.now(); | |
| 102 _runningTime = null; | |
| 103 ++_callbackFunctionsOutstanding; | |
| 104 return testFunction(); | |
| 105 }) | |
| 106 .catchError(errorHandler('Test')) | |
| 107 .then((_) { | |
| 108 _markCallbackComplete(); | |
|
Siggi Cherem (dart-lang)
2013/07/01 18:24:31
suggestion: to make the ++ and -- of callbackFunct
| |
| 109 if (result == null) { | |
| 110 // Outstanding callbacks exist; we need to return a Future. | |
| 111 _testComplete = new Completer(); | |
| 112 return _testComplete.future.whenComplete(() { | |
| 113 if (tearDown != null) { | |
| 114 return tearDown(); | |
| 115 } | |
| 116 }).catchError(errorHandler('Teardown')); | |
| 117 } else if (tearDown != null) { | |
| 118 return tearDown(); | |
| 119 } | |
| 120 }) | |
| 121 .catchError(errorHandler('Teardown')); | |
| 146 } | 122 } |
| 147 | 123 |
| 148 // Set the results, notify the config, and return true if this | 124 // Set the results, notify the config, and return true if this |
| 149 // is the first time the result is being set. | 125 // is the first time the result is being set. |
| 150 void _setResult(String testResult, String messageText, String stack) { | 126 void _setResult(String testResult, String messageText, String stack) { |
| 151 _message = messageText; | 127 _message = messageText; |
| 152 _stackTrace = _formatStack(stack); | 128 _stackTrace = _formatStack(stack); |
| 153 if (result == null) { | 129 if (result == null) { |
| 154 _result = testResult; | 130 _result = testResult; |
| 155 _config.onTestResult(this); | 131 _config.onTestResult(this); |
| 156 } else { | 132 } else { |
| 157 _result = testResult; | 133 _result = testResult; |
| 158 _config.onTestResultChanged(this); | 134 _config.onTestResultChanged(this); |
| 159 } | 135 } |
| 160 } | 136 } |
| 161 | 137 |
| 162 void _complete(String testResult, | 138 void _complete(String testResult, |
| 163 [String messageText = '', | 139 [String messageText = '', |
| 164 String stack = '']) { | 140 String stack = '']) { |
| 165 if (runningTime == null) { | 141 if (runningTime == null) { |
| 166 // The startTime can be `null` if an error happened during setup. In this | 142 // The startTime can be `null` if an error happened during setup. In this |
| 167 // case we simply report a running time of 0. | 143 // case we simply report a running time of 0. |
| 168 if (startTime != null) { | 144 if (startTime != null) { |
| 169 _runningTime = new DateTime.now().difference(startTime); | 145 _runningTime = new DateTime.now().difference(startTime); |
| 170 } else { | 146 } else { |
| 171 _runningTime = const Duration(seconds: 0); | 147 _runningTime = const Duration(seconds: 0); |
| 172 } | 148 } |
| 173 } | 149 } |
| 174 _setResult(testResult, messageText, stack); | 150 _setResult(testResult, messageText, stack); |
| 175 if (!_doneTeardown) { | 151 if (_testComplete != null) { |
| 176 _doneTeardown = true; | 152 var t = _testComplete; |
| 177 if (tearDown != null) { | 153 _testComplete = null; |
| 178 var rtn = tearDown(); | 154 t.complete(this); |
| 179 if (rtn is Future) { | |
| 180 rtn.then((_) { | |
| 181 _notifyComplete(); | |
| 182 }) | |
| 183 .catchError((error) { | |
| 184 var trace = getAttachedStackTrace(error); | |
| 185 // We don't call fail() as that will potentially result in | |
| 186 // spurious messages like 'test failed more than once'. | |
| 187 _setResult(ERROR, "$description: Test teardown failed: ${error}", | |
| 188 trace == null ? "" : trace.toString()); | |
| 189 _notifyComplete(); | |
| 190 }); | |
| 191 return; | |
| 192 } | |
| 193 } | |
| 194 } | 155 } |
| 195 _notifyComplete(); | |
| 196 } | 156 } |
| 197 | 157 |
| 198 void pass() { | 158 void pass() { |
| 199 _complete(PASS); | 159 _complete(PASS); |
| 200 } | 160 } |
| 201 | 161 |
| 202 void fail(String messageText, [String stack = '']) { | 162 void fail(String messageText, [String stack = '']) { |
| 203 assert(stack != null); | 163 assert(stack != null); |
| 204 if (result != null) { | 164 if (result != null) { |
| 205 String newMessage = (result == PASS) | 165 String newMessage = (result == PASS) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 216 assert(stack != null); | 176 assert(stack != null); |
| 217 _complete(ERROR, messageText, stack); | 177 _complete(ERROR, messageText, stack); |
| 218 } | 178 } |
| 219 | 179 |
| 220 void _markCallbackComplete() { | 180 void _markCallbackComplete() { |
| 221 if (--_callbackFunctionsOutstanding == 0 && !isComplete) { | 181 if (--_callbackFunctionsOutstanding == 0 && !isComplete) { |
| 222 pass(); | 182 pass(); |
| 223 } | 183 } |
| 224 } | 184 } |
| 225 } | 185 } |
| OLD | NEW |