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

Side by Side Diff: client/testing/unittest/unittestsuite.dart

Issue 8418013: Huge internal clean-up of unittestsuite. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 1 month 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 | client/tests/client/json/cmd_json_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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 // TODO(rnystrom): This code is gradually moving from a Java/JUnit style to
6 // something closer to JS/Jasmine. Eventually, the UnitTestSuite class can go
7 // away completely (or become private to this library) and the only exposed API
8 // will be group()/test()/expect(). Until then, both ways are supported, which
9 // is why things look a bit weird in here.
10
11 UnitTestSuite _currentSuite;
12
13 /** 5 /**
14 * Description text of the current test group. If multiple groups are nested, 6 * Description text of the current test group. If multiple groups are nested,
15 * this will contain all of their text concatenated. 7 * this will contain all of their text concatenated.
16 */ 8 */
17 String _currentGroup = ''; 9 String _currentGroup = '';
18 10
19 /** Base class for unit test suites run in a browser. */ 11 /** Tests executed in this suite. */
20 class UnitTestSuite { 12 List<TestCase> _tests;
Anton Muhin 2011/10/28 15:54:01 maybe pack all those fields into one class?
Bob Nystrom 2011/10/28 18:16:15 I actually specifically unpacked them (they all us
Anton Muhin 2011/10/28 18:20:49 I do understand that. But (YMMV of course), I wou
21 13
22 /** Tests executed in this suite. */ 14 /** Whether this is run within dartium layout tests. */
23 List<TestCase> _tests; 15 bool _isLayoutTest = false;
24 16
25 /** Whether this suite is run within dartium layout tests. */ 17 /** Current test being executed. */
26 bool _isLayoutTest; 18 int _currentTest = 0;
27 19
28 /** Current test being executed. */ 20 /** Total number of callbacks that have been executed in the current test. */
29 int _currentTest; 21 int _callbacksCalled = 0;
30 22
31 /** Total number of callbacks that have been executed in the current test. */ 23 // TODO(rnystrom): Get rid of this if we get canonical closures for methods.
32 int _callbacksCalled; 24 EventListener _onErrorClosure;
33 25
34 /** 26 final _stateUninitialized = 0;
Siggi Cherem (dart-lang) 2011/10/28 01:33:57 should we use ALL CAPS for enum-like constants lik
jimhug 2011/10/28 15:50:44 I like Siggi's suggestion here. +1 On 2011/10/28
Bob Nystrom 2011/10/28 18:16:15 Done. We don't have a convention for constants yet
35 * Whether an undetected error occurred while running the last test. This 27 final _stateReady = 1;
36 * errors are commonly caused by DOM callbacks that were not guarded in a 28 final _stateRunningTest = 2;
37 * try-catch block.
38 */
39 bool _uncaughtError;
40 EventListener _onErrorClosure;
41 29
42 bool _queuedToRun = false; 30 /**
31 * Whether an undetected error occurred while running the last test. This
jimhug 2011/10/28 15:50:44 Nit: These
Bob Nystrom 2011/10/28 18:16:15 Done.
32 * errors are commonly caused by DOM callbacks that were not guarded in a
33 * try-catch block.
34 */
35 final _stateUncaughtError = 3;
43 36
44 /** Whether a test is currently being executed by [runTest]. */ 37 int _state = _stateUninitialized;
45 bool _testIsRunning = false;
46
47 // TODO(sigmund): remove isLayoutTest argument after converting all DOM tests
48 // to use the named constructor below.
49 // TODO(vsm): remove the ignoredWindow parameter once all tests are fixed.
50 UnitTestSuite([var ignoredWindow = null, bool isLayoutTest = false])
51 : _isLayoutTest = isLayoutTest,
52 _tests = new List<TestCase>(),
53 _currentTest = 0,
54 _callbacksCalled = 0 {
55 _onErrorClosure = (e) { _onError(e); };
56 if (_currentSuite != null) {
57 throw 'Cannot have two UnitTestSuites in flight at the same time.';
58 }
59 _currentSuite = this;
60
61 // Immediately queue the suite up. It will run after a timeout (i.e. after
62 // main() has returned).
63 run();
64 }
65
66 // TODO(jacobr): remove the ignoredWindow parameter once all tests are fixed.
67 UnitTestSuite.forLayoutTests([var ignoredWindow = null]) : this(null, true);
68
69 /** Starts running the testsuite. */
70 void run() {
71 if (_queuedToRun) {
72 return;
73 }
74
75 _queuedToRun = true;
76
77 listener(e) {
78 _currentGroup = '';
79 setUpTestSuite();
80 runTests();
81 };
82
83 try {
84 window.dynamic.on.contentLoaded.add(listener);
85 } catch(var e) {
86 // TODO(jacobr): remove this horrible hack to work around dartc bugs.
87 window.dynamic.addEventListener("DOMContentLoaded", listener, false);
88 }
89 }
90
91 /** Subclasses should override this method to register tests. */
92 void setUpTestSuite() {}
93
94 /** Enqueues a synchronous test. */
95 void addTest(TestFunction body) {
96 test(null, body);
97 }
98
99 /** Enqueues an asynchronous test that waits for [callbacks] callbacks. */
100 void addAsyncTest(TestFunction body, int callbacks) {
101 asyncTest(null, callbacks, body);
102 }
103
104 /** Runs all queued tests, one at a time. */
105 void runTests() {
106 window.postMessage('unittest-suite-start', '*');
107 window.setTimeout(() {
108 assert (_currentTest == 0);
109 // Listen for uncaught errors (see [_uncaughtError]).
110 // TODO(jacobr): remove this horrible hack when dartc bugs are fixed.
111 try {
112 window.dynamic.on.error.add(_onErrorClosure);
113 } catch(var e) {
114 window.dynamic.onerror = _onErrorClosure;
115 }
116 _nextBatch();
117 }, 0);
118 }
119
120 void _onError(e) {
121 if (_currentTest < _tests.length) {
122 final testCase = _tests[_currentTest];
123 // TODO(vsm): figure out how to expose the stack trace here
124 // Currently e.message works in dartium, but not in dartc.
125 testCase.recordError('(DOM callback has errors) Caught ${e}', '');
126 _uncaughtError = true;
127 if (testCase.callbacks > 0) {
128 _currentTest++;
129 _nextBatch();
130 }
131 }
132 }
133
134 /** Called by subclasses to indicate that an asynchronous test completed. */
135 void callbackDone() {
136 _callbacksCalled++;
137 final testCase = _tests[_currentTest];
138 if (testCase.callbacks == 0) {
139 testCase.recordError(
140 "Can't call callbackDone() on a synchronous test", '');
141 _uncaughtError = true;
142 } else if (_callbacksCalled > testCase.callbacks) {
143 final expected = testCase.callbacks;
144 testCase.recordError(
145 'More calls to callbackDone() than expected. '
146 + 'Actual: ${_callbacksCalled}, expected: ${expected}', '');
147 _uncaughtError = true;
148 } else if (_callbacksCalled == testCase.callbacks && !_testIsRunning) {
149 testCase.recordSuccess();
150 _currentTest++;
151 _nextBatch();
152 }
153 }
154
155 /**
156 * Runs a batch of tests, yielding whenever an asynchronous test starts
157 * running. Tests will resume executing when such asynchronous test calls
158 * [done] or if it fails with an exception.
159 */
160 void _nextBatch() {
161 while (_currentTest < _tests.length) {
162 final testCase = _tests[_currentTest];
163 runTest(testCase);
164 if (!testCase.isComplete() && testCase.callbacks > 0) {
165 return;
166 }
167 _currentTest++;
168 }
169 _completeTests();
170 }
171
172 /** Runs a single test. */
173 void runTest(TestCase testCase) {
174 // TODO(sigmund): remove this declaration once dartc supports trapping error
175 // traces.
176 var trace = '';
177 _uncaughtError = false;
178 _callbacksCalled = 0;
179 try {
180 _testIsRunning = true;
181 (testCase.test)();
182 if (!_uncaughtError) {
183 if (testCase.callbacks == _callbacksCalled) {
184 testCase.recordSuccess();
185 }
186 }
187 } catch (ExpectException e, var trace) {
188 if (!_uncaughtError) {
189 testCase.recordFail(e.message, trace.toString());
190 }
191 } catch (var e, var trace) {
192 if (!_uncaughtError) {
193 testCase.recordError('Caught ${e}', trace.toString());
194 }
195 } finally {
196 _testIsRunning = false;
197 }
198 }
199
200 /** Publish results on the page and notify controller. */
201 void _completeTests() {
202 try {
203 window.dynamic.on.error.remove(_onErrorClosure);
204 } catch (var e) {
205 // TODO(jacobr): remove this horrible hack to work around dartc bugs.
206 window.dynamic.onerror = null;
207 }
208
209 // This suite is done now, so discard it.
210 _currentSuite = null;
211
212 int testsFailed = 0;
213 int testsErrors = 0;
214 int testsPassed = 0;
215
216 for (TestCase t in _tests) {
217 if (t.success) {
218 testsPassed++;
219 }
220 if (t.fail) {
221 testsFailed++;
222 }
223 if (t.error) {
224 testsErrors++;
225 }
226 }
227
228 if (_isLayoutTest && testsPassed == _tests.length) {
229 document.body.innerHTML = "PASS";
230 } else {
231 StringBuffer newBody = new StringBuffer();
232 newBody.add("<table class='unittest-table'><tbody>");
233 newBody.add(testsPassed == _tests.length
234 ? "<tr><td colspan='3' class='unittest-pass'>PASS</td></tr>"
235 : "<tr><td colspan='3' class='unittest-fail'>FAIL</td></tr>");
236
237 for (TestCase t in _tests) {
238 newBody.add(t.message);
239 }
240
241 if (testsPassed == _tests.length) {
242 newBody.add("<tr><td colspan='3' class='unittest-pass'>All "
243 + testsPassed + " tests passed</td></tr>");
244 } else {
245 newBody.add("""
246 <tr><td colspan='3'>Total
247 <span class='unittest-pass'>${testsPassed} passed</span>,
248 <span class='unittest-fail'>${testsFailed} failed</span>
249 <span class='unittest-error'>${testsErrors} errors</span>
250 </td></tr>""");
251 }
252 newBody.add("</tbody></table>");
253 document.body.innerHTML = newBody.toString();
254 }
255
256 window.dynamic/*TODO(5389254)*/.postMessage('unittest-suite-done', '*');
257 }
258 }
259 38
260 /** Creates an expectation for the given value. */ 39 /** Creates an expectation for the given value. */
261 Expectation expect(value) => new Expectation(value); 40 Expectation expect(value) => new Expectation(value);
262 41
42 /** Evaluates the given function and validates that it throws an exception. */
43 void expectThrow(function) {
jimhug 2011/10/28 15:50:44 Sorrow: I'd like to ask for an optional expected
Bob Nystrom 2011/10/28 18:16:15 I didn't implement it yet because I didn't have an
44 bool threw = false;
45 try {
46 function();
47 } catch (var e) {
48 threw = true;
49 }
50 Expect.equals(true, threw, 'Expected exception but none was thrown.');
51 }
52
263 /** 53 /**
264 * Creates a new test case with the given description and body. The 54 * Creates a new test case with the given description and body. The
265 * description will include the descriptions of any surrounding group() 55 * description will include the descriptions of any surrounding group()
266 * calls. 56 * calls.
267 */ 57 */
268 void test(String spec, TestFunction body) { 58 void test(String spec, TestFunction body) {
269 _ensureActiveSuite(); 59 _ensureInitialized();
270 60
271 _currentSuite._tests.add(new TestCase( 61 _tests.add(new TestCase(_tests.length + 1, _fullSpec(spec), body, 0));
272 _currentSuite._tests.length + 1, _fullSpec(spec), body, 0));
273 } 62 }
274 63
275 /** 64 /**
276 * Creates a new async test case with the given description and body. The 65 * Creates a new async test case with the given description and body. The
277 * description will include the descriptions of any surrounding group() 66 * description will include the descriptions of any surrounding group()
278 * calls. 67 * calls.
279 */ 68 */
280 void asyncTest(String spec, int callbacks, TestFunction body) { 69 void asyncTest(String spec, int callbacks, TestFunction body) {
281 _ensureActiveSuite(); 70 _ensureInitialized();
282 71
283 final testCase = new TestCase( 72 final testCase = new TestCase(
284 _currentSuite._tests.length + 1, _fullSpec(spec), body, callbacks); 73 _tests.length + 1, _fullSpec(spec), body, callbacks);
285 _currentSuite._tests.add(testCase); 74 _tests.add(testCase);
286 75
287 if (callbacks < 1) { 76 if (callbacks < 1) {
288 testCase.recordError( 77 testCase.recordError(
289 'Async tests must wait for at least one callback ', ''); 78 'Async tests must wait for at least one callback ', '');
290 } 79 }
291 } 80 }
292 81
293 /** 82 /**
294 * Creates a new named group of tests. Calls to group() or test() within the 83 * Creates a new named group of tests. Calls to group() or test() within the
295 * body of the function passed to this will inherit this group's description. 84 * body of the function passed to this will inherit this group's description.
296 */ 85 */
297 void group(String description, void body()) { 86 void group(String description, void body()) {
298 _ensureActiveSuite(); 87 _ensureInitialized();
299 88
300 // Concatenate the new group. 89 // Concatenate the new group.
301 final oldGroup = _currentGroup; 90 final oldGroup = _currentGroup;
302 if (_currentGroup != '') { 91 if (_currentGroup != '') {
303 // Add a space. 92 // Add a space.
304 _currentGroup = '$_currentGroup $description'; 93 _currentGroup = '$_currentGroup $description';
305 } else { 94 } else {
306 // The first group. 95 // The first group.
307 _currentGroup = description; 96 _currentGroup = description;
308 } 97 }
309 98
310 try { 99 try {
311 body(); 100 body();
312 } finally { 101 } finally {
313 // Now that the group is over, restore the previous one. 102 // Now that the group is over, restore the previous one.
314 _currentGroup = oldGroup; 103 _currentGroup = oldGroup;
315 } 104 }
316 } 105 }
317 106
107 /** Called by subclasses to indicate that an asynchronous test completed. */
318 void callbackDone() { 108 void callbackDone() {
319 if (_currentSuite == null) { 109 _callbacksCalled++;
320 throw 'There is no currently-running test suite.'; 110 final testCase = _tests[_currentTest];
111 if (testCase.callbacks == 0) {
112 testCase.recordError(
113 "Can't call callbackDone() on a synchronous test", '');
114 _state = _stateUncaughtError;
115 } else if (_callbacksCalled > testCase.callbacks) {
116 final expected = testCase.callbacks;
117 testCase.recordError(
118 'More calls to callbackDone() than expected. '
119 + 'Actual: ${_callbacksCalled}, expected: ${expected}', '');
120 _state = _stateUncaughtError;
121 } else if ((_callbacksCalled == testCase.callbacks) &&
122 (_state != _stateRunningTest)) {
123 testCase.recordSuccess();
124 _currentTest++;
125 _nextBatch();
321 } 126 }
322 _currentSuite.callbackDone();
323 } 127 }
324 128
325 void forLayoutTests() { 129 void forLayoutTests() {
326 _ensureActiveSuite(); 130 _isLayoutTest = true;
327 _currentSuite._isLayoutTest = true; 131 }
132
133 /** Runs all queued tests, one at a time. */
134 _runTests() {
135 window.postMessage('unittest-suite-start', '*');
136 window.setTimeout(() {
137 assert (_currentTest == 0);
138 // Listen for uncaught errors.
139 // TODO(jacobr): remove this horrible hack when dartc bugs are fixed.
140 try {
141 window.dynamic.on.error.add(_onErrorClosure);
142 } catch(var e) {
143 window.dynamic.onerror = _onErrorClosure;
144 }
145 _nextBatch();
146 }, 0);
147 }
148
149 /** Runs a single test. */
150 _runTest(TestCase testCase) {
151 try {
152 // TODO(sigmund): remove this declaration once dartc supports trapping error
153 // traces.
154 var trace = '';
155 _callbacksCalled = 0;
156 _state = _stateRunningTest;
157
158 testCase.test();
159
160 if (_state != _stateUncaughtError) {
161 if (testCase.callbacks == _callbacksCalled) {
162 testCase.recordSuccess();
163 }
164 }
165 } catch (ExpectException e, var trace) {
166 if (_state != _stateUncaughtError) {
167 testCase.recordFail(e.message, trace.toString());
168 }
169 } catch (var e, var trace) {
170 if (_state != _stateUncaughtError) {
171 testCase.recordError('Caught ${e}', trace.toString());
172 }
173 } finally {
174 _state = _stateReady;
175 }
176 }
177
178 /**
179 * Runs a batch of tests, yielding whenever an asynchronous test starts
180 * running. Tests will resume executing when such asynchronous test calls
181 * [done] or if it fails with an exception.
182 */
183 _nextBatch() {
184 while (_currentTest < _tests.length) {
185 final testCase = _tests[_currentTest];
186
187 _runTest(testCase);
188
189 if (!testCase.isComplete && testCase.callbacks > 0) return;
190
191 _currentTest++;
192 }
193
194 _completeTests();
195 }
196
197 /** Publish results on the page and notify controller. */
198 _completeTests() {
199 try {
200 window.dynamic.on.error.remove(_onErrorClosure);
201 } catch (var e) {
202 // TODO(jacobr): remove this horrible hack to work around dartc bugs.
jimhug 2011/10/28 15:50:44 Is this hack still needed? Both here and below.
Bob Nystrom 2011/10/28 18:16:15 I only investigated briefly, but it looks like it'
203 window.dynamic.onerror = null;
204 }
205
206 _state = _stateUninitialized;
207
208 int testsFailed = 0;
209 int testsErrors = 0;
210 int testsPassed = 0;
211
212 for (TestCase t in _tests) {
213 if (t.success) testsPassed++;
214 if (t.fail) testsFailed++;
215 if (t.error) testsErrors++;
216 }
217
218 if (_isLayoutTest && testsPassed == _tests.length) {
219 document.body.innerHTML = "PASS";
220 } else {
221 var newBody = new StringBuffer();
222 newBody.add("<table class='unittest-table'><tbody>");
223 newBody.add(testsPassed == _tests.length
224 ? "<tr><td colspan='3' class='unittest-pass'>PASS</td></tr>"
225 : "<tr><td colspan='3' class='unittest-fail'>FAIL</td></tr>");
226
227 for (final test in _tests) {
228 newBody.add(test.message);
229 }
230
231 if (testsPassed == _tests.length) {
232 newBody.add("<tr><td colspan='3' class='unittest-pass'>All "
233 + testsPassed + " tests passed</td></tr>");
234 } else {
235 newBody.add("""
236 <tr><td colspan='3'>Total
237 <span class='unittest-pass'>${testsPassed} passed</span>,
238 <span class='unittest-fail'>${testsFailed} failed</span>
239 <span class='unittest-error'>${testsErrors} errors</span>
240 </td></tr>""");
241 }
242 newBody.add("</tbody></table>");
243 document.body.innerHTML = newBody.toString();
244 }
245
246 window.dynamic/*TODO(5389254)*/.postMessage('unittest-suite-done', '*');
247 }
248
249 void _onError(e) {
250 if (_currentTest < _tests.length) {
251 final testCase = _tests[_currentTest];
252 // TODO(vsm): figure out how to expose the stack trace here
253 // Currently e.message works in dartium, but not in dartc.
254 testCase.recordError('(DOM callback has errors) Caught ${e}', '');
255 _state = _stateUncaughtError;
256 if (testCase.callbacks > 0) {
257 _currentTest++;
258 _nextBatch();
259 }
260 }
328 } 261 }
329 262
330 String _fullSpec(String spec) { 263 String _fullSpec(String spec) {
331 if (spec === null) return '$_currentGroup'; 264 if (spec === null) return '$_currentGroup';
332 return _currentGroup != '' ? '$_currentGroup $spec' : spec; 265 return _currentGroup != '' ? '$_currentGroup $spec' : spec;
333 } 266 }
334 267
335 /** 268 /**
336 * Lazily creates a UnitTestSuite if there isn't already an active one. Returns 269 * Lazily initializes the test library if not already initialized.
337 * whether or not one was created.
338 */ 270 */
339 _ensureActiveSuite() { 271 _ensureInitialized() {
340 if (_currentSuite != null) { 272 if (_state != _stateUninitialized) return;
341 return; 273
274 _tests = <TestCase>[];
275 _onErrorClosure = (e) { _onError(e); };
276
277 // Immediately queue the suite up. It will run after a timeout (i.e. after
278 // main() has returned).
279 listener(e) {
280 _currentGroup = '';
281 _runTests();
282 };
283
284 try {
285 window.dynamic.on.contentLoaded.add(listener);
jimhug 2011/10/28 15:50:44 Hmm. I really don't like this window.dynamic.foo
Bob Nystrom 2011/10/28 18:16:15 I don't like it either. I'll get it cleaned up in
Siggi Cherem (dart-lang) 2011/10/28 18:21:42 Sounds good - alternatively if we really want to k
286 } catch(var e) {
287 // TODO(jacobr): remove this horrible hack to work around dartc bugs.
288 window.dynamic.addEventListener("DOMContentLoaded", listener, false);
342 } 289 }
343 290
344 _currentSuite = new UnitTestSuite(); 291 _state = _stateReady;
345 } 292 }
346 293
347 /** 294 /**
348 * Wraps an value and provides an "==" operator that can be used to verify that 295 * Wraps an value and provides an "==" operator that can be used to verify that
349 * the value matches a given expectation. 296 * the value matches a given expectation.
350 */ 297 */
351 class Expectation { 298 class Expectation {
352 final _value; 299 final _value;
353 300
354 Expectation(this._value); 301 Expectation(this._value);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 /** Whether this test case had a runtime error. */ 372 /** Whether this test case had a runtime error. */
426 bool error; 373 bool error;
427 374
428 /** Messages to display at the end of the test run. */ 375 /** Messages to display at the end of the test run. */
429 String message; 376 String message;
430 377
431 TestCase(this.id, this.description, this.test, this.callbacks) 378 TestCase(this.id, this.description, this.test, this.callbacks)
432 : success = false, 379 : success = false,
433 fail = false, 380 fail = false,
434 error = false { 381 error = false {
435 message = """<tr> 382 message = '''<tr>
436 <td>${id}</td> 383 <td>${id}</td>
437 <td class='unittest-error'>NO STATUS</td> 384 <td class="unittest-error">NO STATUS</td>
438 <td>Test did not complete</td> 385 <td>Test did not complete</td>
439 </tr>"""; 386 </tr>''';
440 } 387 }
441 388
442 bool isComplete() => success || fail || error; 389 bool get isComplete() => success || fail || error;
jimhug 2011/10/28 15:50:44 Properties are good.
Bob Nystrom 2011/10/28 18:16:15 :D
443 390
444 void recordSuccess() { 391 void recordSuccess() {
445 message = "<tr><td>${id}</td><td class='unittest-pass'>PASS</td></tr>"; 392 _setMessage('pass', '', null);
446 success = true; 393 success = true;
447 } 394 }
448 395
449 void recordError(String msg, String stackTrace) { 396 void recordError(String msg, String stackTrace) {
450 message = """ 397 _setMessage('error', msg, stackTrace);
451 <tr>
452 <td>${id}</td>
453 <td class='unittest-error'>ERROR</td>
454 <td>${msg}</td>
455 </tr>""";
456 if (stackTrace != null) {
457 message +=
458 "<tr><td></td><td colspan='2'><pre>${stackTrace}</pre></td></tr>";
459 }
460 error = true; 398 error = true;
461 } 399 }
462 400
463 void recordFail(String msg, String stackTrace) { 401 void recordFail(String msg, String stackTrace) {
464 // Include the spec description if we have one. 402 _setMessage('fail', msg, stackTrace);
465 // TODO(rnystrom): When all of our tests are using group() and test(), we 403 fail = true;
466 // can assume description will be non-null and eliminate this check. 404 }
467 if (description != null) {
468 msg = 'Expectation: $description. $msg';
469 }
470 405
471 message = """ 406 void _setMessage(String type, String msg, String stackTrace) {
407 message =
408 '''
472 <tr> 409 <tr>
473 <td>${id}</td> 410 <td>${id}</td>
474 <td class='unittest-fail'>FAIL</td> 411 <td class="unittest-$type">${type.toUpperCase()}</td>
475 <td>${msg}</td> 412 <td>Expectation: $description. $msg</td>
476 </tr>"""; 413 </tr>
414 ''';
415
477 if (stackTrace != null) { 416 if (stackTrace != null) {
478 message += 417 message +=
479 "<tr><td></td><td colspan='2'><pre>${stackTrace}</pre></td></tr>"; 418 '<tr><td></td><td colspan="2"><pre>${stackTrace}</pre></td></tr>';
480 } 419 }
481 fail = true;
482 } 420 }
483 } 421 }
484 422
485 typedef void TestFunction(); 423 typedef void TestFunction();
jimhug 2011/10/28 15:50:44 64 fewer lines with no loss of functionality? Yay
OLDNEW
« no previous file with comments | « no previous file | client/tests/client/json/cmd_json_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698