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

Side by Side Diff: lib/unittest/unittest.dart

Issue 10447126: Revert "Removed asyncTest and improved comments." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 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 | tests/html/fileapi_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 /** 5 /**
6 * A library for writing dart unit tests. 6 * A library for writing dart unit tests.
7 * 7 *
8 * To import this library, specify the relative path to 8 * To import this library, specify the relative path to
9 * lib/unittest/unittest.dart. 9 * lib/unittest/unittest.dart.
10 * 10 *
11 * ##Concepts## 11 * ##Concepts##
12 * 12 *
13 * * Tests: Tests are specified via the top-level function [test], they can be 13 * * Tests: Tests are specified via the top-level function [test], they can be
14 * organized together using [group]. 14 * organized together using [group].
15 * * Checks: Test expectations can be specified via [expect] (see methods in 15 * * Checks: Test expectations can be specified via [expect] (see methods in
16 * [Expectation]), [expectThrow], or using assertions with the [Expect] 16 * [Expectation]), [expectThrow], or using assertions with the [Expect]
17 * class. 17 * class.
18 * * Configuration: The framework can be adapted by calling [configure] with a 18 * * Configuration: The framework can be adapted by calling [configure] with a
19 * [Configuration]. Common configurations can be found in this package 19 * [Configuration]. Common configurations can be found in this package
20 * under: 'dom\_config.dart' (deprecated), 'html\_config.dart' (for running 20 * under: 'dom\_config.dart', 'html\_config.dart', and 'vm\_config.dart'.
21 * tests compiled to Javascript in a browser), and 'vm\_config.dart' (for
22 * running native Dart tests on the VM).
23 * 21 *
24 * ##Examples## 22 * ##Examples##
25 * 23 *
26 * A trivial test: 24 * A trivial test:
27 * 25 *
28 * #import('path-to-dart/lib/unittest/unitest.dart'); 26 * #import('path-to-dart/lib/unittest/unitest.dart');
29 * main() { 27 * main() {
30 * test('this is a test', () { 28 * test('this is a test', () {
31 * int x = 2 + 3; 29 * int x = 2 + 3;
32 * expect(x).equals(5); 30 * expect(x).equals(5);
(...skipping 29 matching lines...) Expand all
62 * }); 60 * });
63 * }); 61 * });
64 * group('group B', () { 62 * group('group B', () {
65 * test('this B.1', () { 63 * test('this B.1', () {
66 * int x = 2 + 3; 64 * int x = 2 + 3;
67 * expect(x).equals(5); 65 * expect(x).equals(5);
68 * }); 66 * });
69 * }); 67 * });
70 * } 68 * }
71 * 69 *
72 * Asynchronous tests: if callbacks expect between 0 and 2 positional arguments, 70 * Asynchronous tests: if callbacks expect between 0 and 2 positional arguments.
73 * depending on the suffix of expectAsyncX(). expectAsyncX() will wrap a
74 * function into a new callback and will not consider the test complete until
75 * that callback is run. A count argument can be provided to specify the number
76 * of times the callback should be called (the default is 1).
77 * 71 *
78 * #import('path-to-dart/lib/unittest/unitest.dart'); 72 * #import('path-to-dart/lib/unittest/unitest.dart');
79 * #import('dart:dom_deprecated'); 73 * #import('dart:dom_deprecated');
80 * main() { 74 * main() {
81 * test('calllback is executed once', () { 75 * test('calllback is executed once', () {
82 * // wrap the callback of an asynchronous call with [expectAsync0] if 76 * // wrap the callback of an asynchronous call with [expectAsync0] if
83 * // the callback takes 0 arguments... 77 * // the callback takes 0 arguments...
84 * window.setTimeout(expectAsync0(() { 78 * window.setTimeout(expectAsync0(() {
85 * int x = 2 + 3; 79 * int x = 2 + 3;
86 * expect(x).equals(5); 80 * expect(x).equals(5);
87 * }), 0); 81 * }), 0);
88 * }); 82 * });
89 * 83 *
90 * test('calllback is executed twice', () { 84 * test('calllback is executed twice', () {
91 * var callback = expectAsync0(() { 85 * var callback = expectAsync0(() {
92 * int x = 2 + 3; 86 * int x = 2 + 3;
93 * expect(x).equals(5); 87 * expect(x).equals(5);
94 * }, count: 2); // <-- we can indicate multiplicity to [expectAsync0] 88 * }, count: 2); // <-- we can indicate multiplicity to [expectAsync0]
95 * window.setTimeout(callback, 0); 89 * window.setTimeout(callback, 0);
96 * window.setTimeout(callback, 0); 90 * window.setTimeout(callback, 0);
97 * }); 91 * });
98 * } 92 * }
99 * 93 *
100 * expectAsyncX() will wrap the callback code in a try/catch handler to handle
101 * exceptions (treated as test failures). There may be times when the number of
102 * times a callback should be called is non-deterministic. In this case a dummy
103 * callback can be created with expectAsync0((){}) and this can be called from
104 * the real callback when it is finally complete. In this case the body of the
105 * callback should be protected within a call to guardAsync(); this will ensure
106 * that exceptions are properly handled.
107 *
108 * Note: due to some language limitations we have to use different functions 94 * Note: due to some language limitations we have to use different functions
109 * depending on the number of positional arguments of the callback. In the 95 * depending on the number of positional arguments of the callback. In the
110 * future, we plan to expose a single `expectAsync` function that can be used 96 * future, we plan to expose a single `expectAsync` function that can be used
111 * regardless of the number of positional arguments. This requires new langauge 97 * regardless of the number of positional arguments. This requires new langauge
112 * features or fixes to the current spec (e.g. see 98 * features or fixes to the current spec (e.g. see
113 * [Issue 2706](http://dartbug.com/2706)). 99 * [Issue 2706](http://dartbug.com/2706)).
114 * 100 *
115 * Meanwhile, we plan to add this alternative API for callbacks of more than 2 101 * Meanwhile, we plan to add this alternative API for callbacks of more than 2
116 * arguments or that take named parameters. (this is not implemented yet, 102 * arguments or that take named parameters. (this is not implemented yet,
117 * but will be coming here soon). 103 * but will be coming here soon).
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 * description will include the descriptions of any surrounding group() 215 * description will include the descriptions of any surrounding group()
230 * calls. 216 * calls.
231 */ 217 */
232 void test(String spec, TestFunction body) { 218 void test(String spec, TestFunction body) {
233 ensureInitialized(); 219 ensureInitialized();
234 220
235 _tests.add(new TestCase(_tests.length + 1, _fullSpec(spec), body, 0)); 221 _tests.add(new TestCase(_tests.length + 1, _fullSpec(spec), body, 0));
236 } 222 }
237 223
238 /** 224 /**
225 * Creates a new async test case with the given description and body. The
226 * description will include the descriptions of any surrounding group()
227 * calls.
228 */
229 // TODO(sigmund): deprecate this API
230 void asyncTest(String spec, int callbacks, TestFunction body) {
231 ensureInitialized();
232
233 final testCase = new TestCase(
234 _tests.length + 1, _fullSpec(spec), body, callbacks);
235 _tests.add(testCase);
236
237 if (callbacks < 1) {
238 testCase.error(
239 'Async tests must wait for at least one callback ', '');
240 }
241 }
242
243 /**
239 * Creates a new test case with the given description and body. The 244 * Creates a new test case with the given description and body. The
240 * description will include the descriptions of any surrounding group() 245 * description will include the descriptions of any surrounding group()
241 * calls. 246 * calls.
242 * 247 *
243 * "solo_" means that this will be the only test that is run. All other tests 248 * "solo_" means that this will be the only test that is run. All other tests
244 * will be skipped. This is a convenience function to let you quickly isolate 249 * will be skipped. This is a convenience function to let you quickly isolate
245 * a single test by adding "solo_" before it to temporarily disable all other 250 * a single test by adding "solo_" before it to temporarily disable all other
246 * tests. 251 * tests.
247 */ 252 */
248 void solo_test(String spec, TestFunction body) { 253 void solo_test(String spec, TestFunction body) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 } else if (arg3 == _sentinel) { 301 } else if (arg3 == _sentinel) {
297 return callback(arg0, arg1, arg2); 302 return callback(arg0, arg1, arg2);
298 } else if (arg4 == _sentinel) { 303 } else if (arg4 == _sentinel) {
299 return callback(arg0, arg1, arg2, arg3); 304 return callback(arg0, arg1, arg2, arg3);
300 } else { 305 } else {
301 testCase.error( 306 testCase.error(
302 'unittest lib does not support callbacks with more than 4 arguments', 307 'unittest lib does not support callbacks with more than 4 arguments',
303 ''); 308 '');
304 _state = _UNCAUGHT_ERROR; 309 _state = _UNCAUGHT_ERROR;
305 } 310 }
306 }, () { if (calls == expectedCalls) _callbackDone(); }); 311 }, () { if (calls == expectedCalls) callbackDone(); });
307 } 312 }
308 313
309 invoke0() { 314 invoke0() {
310 return guardAsync( 315 return guardAsync(
311 () => _incrementCall() ? callback() : null, 316 () => _incrementCall() ? callback() : null,
312 () { if (calls == expectedCalls) _callbackDone(); }); 317 () { if (calls == expectedCalls) callbackDone(); });
313 } 318 }
314 319
315 invoke1(arg1) { 320 invoke1(arg1) {
316 return guardAsync( 321 return guardAsync(
317 () => _incrementCall() ? callback(arg1) : null, 322 () => _incrementCall() ? callback(arg1) : null,
318 () { if (calls == expectedCalls) _callbackDone(); }); 323 () { if (calls == expectedCalls) callbackDone(); });
319 } 324 }
320 325
321 invoke2(arg1, arg2) { 326 invoke2(arg1, arg2) {
322 return guardAsync( 327 return guardAsync(
323 () => _incrementCall() ? callback(arg1, arg2) : null, 328 () => _incrementCall() ? callback(arg1, arg2) : null,
324 () { if (calls == expectedCalls) _callbackDone(); }); 329 () { if (calls == expectedCalls) callbackDone(); });
325 } 330 }
326 331
327 /** Returns false if we exceded the number of expected calls. */ 332 /** Returns false if we exceded the number of expected calls. */
328 bool _incrementCall() { 333 bool _incrementCall() {
329 calls++; 334 calls++;
330 if (calls > expectedCalls) { 335 if (calls > expectedCalls) {
331 testCase.error( 336 testCase.error(
332 'Callback called more times than expected ($expectedCalls)', 337 'Callback called more times than expected ($expectedCalls)',
333 ''); 338 '');
334 _state = _UNCAUGHT_ERROR; 339 _state = _UNCAUGHT_ERROR;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 399
395 try { 400 try {
396 body(); 401 body();
397 } finally { 402 } finally {
398 // Now that the group is over, restore the previous one. 403 // Now that the group is over, restore the previous one.
399 _currentGroup = oldGroup; 404 _currentGroup = oldGroup;
400 } 405 }
401 } 406 }
402 407
403 /** Called by subclasses to indicate that an asynchronous test completed. */ 408 /** Called by subclasses to indicate that an asynchronous test completed. */
404 void _callbackDone() { 409 void callbackDone() {
405 // TODO (gram): we defer this to give the nextBatch recursive 410 // TODO (gram): we defer this to give the nextBatch recursive
406 // stack a chance to unwind. This is a temporary hack but 411 // stack a chance to unwind. This is a temporary hack but
407 // really a bunch of code here needs to be fixed. We have a 412 // really a bunch of code here needs to be fixed. We have a
408 // single array that is being iterated through by nextBatch(), 413 // single array that is being iterated through by nextBatch(),
409 // which is recursively invoked in the case of async tests that 414 // which is recursively invoked in the case of async tests that
410 // run synchronously. Bad things can then happen. 415 // run synchronously. Bad things can then happen.
411 _defer(() { 416 _defer(() {
412 _callbacksCalled++; 417 _callbacksCalled++;
413 if (_currentTest < _tests.length) { 418 if (_currentTest < _tests.length) {
414 final testCase = _tests[_currentTest]; 419 final testCase = _tests[_currentTest];
415 if (_callbacksCalled > testCase.callbacks) { 420 if (_callbacksCalled > testCase.callbacks) {
416 final expected = testCase.callbacks; 421 final expected = testCase.callbacks;
417 testCase.error( 422 testCase.error(
418 'More calls to _callbackDone() than expected. ' 423 'More calls to callbackDone() than expected. '
419 'Actual: ${_callbacksCalled}, expected: ${expected}', ''); 424 'Actual: ${_callbacksCalled}, expected: ${expected}', '');
420 _state = _UNCAUGHT_ERROR; 425 _state = _UNCAUGHT_ERROR;
421 } else if ((_callbacksCalled == testCase.callbacks) && 426 } else if ((_callbacksCalled == testCase.callbacks) &&
422 (_state != _RUNNING_TEST)) { 427 (_state != _RUNNING_TEST)) {
423 if (testCase.result == null) testCase.pass(); 428 if (testCase.result == null) testCase.pass();
424 _currentTest++; 429 _currentTest++;
425 _testRunner(); 430 _testRunner();
426 } 431 }
427 } 432 }
428 }); 433 });
429 } 434 }
430 435
431 /** 436 /** Menchanism to notify that an error was caught outside of this library. */
432 * Utility function that can be used to notify the test framework that an
433 * error was caught outside of this library.
434 */
435 void reportTestError(String msg, String trace) { 437 void reportTestError(String msg, String trace) {
436 if (_currentTest < _tests.length) { 438 if (_currentTest < _tests.length) {
437 final testCase = _tests[_currentTest]; 439 final testCase = _tests[_currentTest];
438 testCase.error(msg, trace); 440 testCase.error(msg, trace);
439 _state = _UNCAUGHT_ERROR; 441 _state = _UNCAUGHT_ERROR;
440 if (testCase.callbacks > 0) { 442 if (testCase.callbacks > 0) {
441 _currentTest++; 443 _currentTest++;
442 _testRunner(); 444 _testRunner();
443 } 445 }
444 } else { 446 } else {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 } 580 }
579 _config.onInit(); 581 _config.onInit();
580 582
581 // Immediately queue the suite up. It will run after a timeout (i.e. after 583 // Immediately queue the suite up. It will run after a timeout (i.e. after
582 // main() has returned). 584 // main() has returned).
583 _defer(_runTests); 585 _defer(_runTests);
584 } 586 }
585 587
586 /** Signature for a test function. */ 588 /** Signature for a test function. */
587 typedef void TestFunction(); 589 typedef void TestFunction();
OLDNEW
« no previous file with comments | « no previous file | tests/html/fileapi_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698