Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: pkg/unittest/lib/src/test_case.dart

Issue 18191019: Changed the code for running a test case to make beter use of dart:async. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/unittest/test/unittest_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/unittest/test/unittest_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698