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

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

Issue 130173010: pkg/unittest: Run each test in a Zone (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: TODO for explaining async error in a more clear way Created 6 years, 10 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
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 /** 5 /**
6 * Support for writing Dart unit tests. 6 * Support for writing Dart unit tests.
7 * 7 *
8 * For information on installing and importing this library, see the 8 * For information on installing and importing this library, see the
9 * [unittest package on pub.dartlang.org] 9 * [unittest package on pub.dartlang.org]
10 * (http://pub.dartlang.org/packages/unittest). 10 * (http://pub.dartlang.org/packages/unittest).
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 _testCases.clear(); 292 _testCases.clear();
293 } 293 }
294 ++_soloNestingLevel; 294 ++_soloNestingLevel;
295 try { 295 try {
296 test(spec, body); 296 test(spec, body);
297 } finally { 297 } finally {
298 --_soloNestingLevel; 298 --_soloNestingLevel;
299 } 299 }
300 } 300 }
301 301
302 /** Sentinel value for [_SpreadArgsHelper]. */
303 class _Sentinel {
304 const _Sentinel();
305 }
306
307 /** 302 /**
308 * Indicate that [callback] is expected to be called a [count] number of times 303 * Indicate that [callback] is expected to be called a [count] number of times
309 * (by default 1). The unittest framework will wait for the callback to run the 304 * (by default 1). The unittest framework will wait for the callback to run the
310 * specified [count] times before it continues with the following test. Using 305 * specified [count] times before it continues with the following test. Using
311 * [expectAsync0] will also ensure that errors that occur within [callback] are 306 * [expectAsync0] will also ensure that errors that occur within [callback] are
312 * tracked and reported. [callback] should take 0 positional arguments (named 307 * tracked and reported. [callback] should take 0 positional arguments (named
313 * arguments are not supported). [id] can be used to provide more 308 * arguments are not supported). [id] can be used to provide more
314 * descriptive error messages if the callback is called more often than 309 * descriptive error messages if the callback is called more often than
315 * expected. [max] can be used to specify an upper bound on the number of 310 * expected. [max] can be used to specify an upper bound on the number of
316 * calls; if this is exceeded the test will fail (or be marked as in error if 311 * calls; if this is exceeded the test will fail (or be marked as in error if
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 359
365 /** 360 /**
366 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments. 361 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments.
367 */ 362 */
368 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 363 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
369 Function expectAsyncUntil2(Function callback, Function isDone, {String id}) { 364 Function expectAsyncUntil2(Function callback, Function isDone, {String id}) {
370 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke2; 365 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke2;
371 } 366 }
372 367
373 /** 368 /**
374 * Wraps the [callback] in a new function and returns that function. The new 369 * *Deprecated*
375 * function will be able to handle exceptions by directing them to the correct 370 *
376 * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that 371 * All tests are now run an isolated [Zone].
377 * might optionally be called but may never be called during the test. 372 *
378 * [callback] should take 0 positional arguments (named arguments are not 373 * You can safely remove calls to this method.
379 * supported). [id] can be used to identify the callback in error
380 * messages (for example if it is called after the test case is complete).
381 */ 374 */
382 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 375 @deprecated
383 Function protectAsync0(Function callback, {String id}) { 376 Function protectAsync0(Function callback, {String id}) {
384 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke0; 377 return callback;
385 } 378 }
386 379
387 /** 380 /**
388 * Like [protectAsync0] but [callback] should take 1 positional argument. 381 * *Deprecated*
382 *
383 * All tests are now run an isolated [Zone].
384 *
385 * You can safely remove calls to this method.
389 */ 386 */
390 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 387 @deprecated
391 Function protectAsync1(Function callback, {String id}) { 388 Function protectAsync1(Function callback, {String id}) {
392 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke1; 389 return callback;
393 } 390 }
394 391
395 /** 392 /**
396 * Like [protectAsync0] but [callback] should take 2 positional arguments. 393 * *Deprecated*
394 *
395 * All tests are now run an isolated [Zone].
396 *
397 * You can safely remove calls to this method.
397 */ 398 */
398 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 399 @deprecated
399 Function protectAsync2(Function callback, {String id}) { 400 Function protectAsync2(Function callback, {String id}) {
400 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke2; 401 return callback;
401 } 402 }
402 403
403 /** 404 /**
404 * Creates a new named group of tests. Calls to group() or test() within the 405 * Creates a new named group of tests. Calls to group() or test() within the
405 * body of the function passed to this will inherit this group's description. 406 * body of the function passed to this will inherit this group's description.
406 */ 407 */
407 void group(String description, void body()) { 408 void group(String description, void body()) {
408 ensureInitialized(); 409 ensureInitialized();
409 _requireNotRunning(); 410 _requireNotRunning();
410 _currentContext = new _GroupContext(_currentContext, description); 411 _currentContext = new _GroupContext(_currentContext, description);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 void handleExternalError(e, String message, [stack]) { 477 void handleExternalError(e, String message, [stack]) {
477 var msg = '$message\nCaught $e'; 478 var msg = '$message\nCaught $e';
478 479
479 if (currentTestCase != null) { 480 if (currentTestCase != null) {
480 currentTestCase._error(msg, stack); 481 currentTestCase._error(msg, stack);
481 } else { 482 } else {
482 _uncaughtErrorMessage = "$msg: $stack"; 483 _uncaughtErrorMessage = "$msg: $stack";
483 } 484 }
484 } 485 }
485 486
486 void rerunTests() {
487 _uncaughtErrorMessage = null;
488 _initialized = true; // We don't want to reset the test array.
489 runTests();
490 }
491
492 /** 487 /**
493 * Filter the tests. [testFilter] can be a [RegExp], a [String] or a 488 * Filter the tests. [testFilter] can be a [RegExp], a [String] or a
494 * predicate function. This is different to enabling/disabling tests 489 * predicate function. This is different to enabling/disabling tests
495 * in that it removes the tests completely. 490 * in that it removes the tests completely.
496 */ 491 */
497 void filterTests(testFilter) { 492 void filterTests(testFilter) {
498 var filterFunction; 493 var filterFunction;
499 if (testFilter is String) { 494 if (testFilter is String) {
500 RegExp re = new RegExp(testFilter); 495 RegExp re = new RegExp(testFilter);
501 filterFunction = (t) => re.hasMatch(t.description); 496 filterFunction = (t) => re.hasMatch(t.description);
502 } else if (testFilter is RegExp) { 497 } else if (testFilter is RegExp) {
503 filterFunction = (t) => testFilter.hasMatch(t.description); 498 filterFunction = (t) => testFilter.hasMatch(t.description);
504 } else if (testFilter is Function) { 499 } else if (testFilter is Function) {
505 filterFunction = testFilter; 500 filterFunction = testFilter;
506 } 501 }
507 _testCases.retainWhere(filterFunction); 502 _testCases.retainWhere(filterFunction);
508 } 503 }
509 504
510 /** Runs all queued tests, one at a time. */ 505 /** Runs all queued tests, one at a time. */
511 void runTests() { 506 void runTests() {
512 _requireNotRunning(); 507 _requireNotRunning();
513 _ensureInitialized(false); 508 _ensureInitialized(false);
514 _currentTestCaseIndex = 0; 509 _currentTestCaseIndex = 0;
515 _config.onStart(); 510 _config.onStart();
516 _runTest(); 511 _runTest();
517 } 512 }
518 513
519 /** 514 /**
520 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, it is 515 * *Deprecated*
521 * passed to the corresponding test.
522 * 516 *
523 * The value returned by [tryBody] (if any) is returned by [guardAsync]. 517 * All tests are now run an isolated [Zone].
518 *
519 * You can safely remove calls to this method.
524 */ 520 */
521 @deprecated
525 guardAsync(Function tryBody) { 522 guardAsync(Function tryBody) {
526 return _guardAsync(tryBody, null, currentTestCase); 523 return tryBody();
527 }
528
529 _guardAsync(Function tryBody, Function finallyBody, TestCase testCase) {
530 assert(testCase != null);
531 try {
532 return tryBody();
533 } catch (e, trace) {
534 _registerException(testCase, e, trace);
535 } finally {
536 if (finallyBody != null) finallyBody();
537 }
538 } 524 }
539 525
540 /** 526 /**
541 * Registers that an exception was caught for the current test. 527 * Registers that an exception was caught for the current test.
542 */ 528 */
543 void registerException(e, [trace]) { 529 void registerException(e, [trace]) {
544 _registerException(currentTestCase, e, trace); 530 _registerException(currentTestCase, e, trace);
545 } 531 }
546 532
547 /** 533 /**
(...skipping 10 matching lines...) Expand all
558 544
559 /** 545 /**
560 * Runs the next test. 546 * Runs the next test.
561 */ 547 */
562 void _runTest() { 548 void _runTest() {
563 if (_currentTestCaseIndex >= testCases.length) { 549 if (_currentTestCaseIndex >= testCases.length) {
564 assert(_currentTestCaseIndex == testCases.length); 550 assert(_currentTestCaseIndex == testCases.length);
565 _completeTests(); 551 _completeTests();
566 } else { 552 } else {
567 var testCase = testCases[_currentTestCaseIndex]; 553 var testCase = testCases[_currentTestCaseIndex];
568 Future f = _guardAsync(testCase._run, null, testCase); 554 Future f = runZoned(testCase._run, onError: (error, stack) {
555 // TODO(kevmoo) Do a better job of flagging these are async errors.
556 // https://code.google.com/p/dart/issues/detail?id=16530
557 _registerException(testCase, error, stack);
558 });
559
569 var timeout = unittestConfiguration.timeout; 560 var timeout = unittestConfiguration.timeout;
570 561
571 Timer timer; 562 Timer timer;
572 if (timeout != null) { 563 if (timeout != null) {
573 try { 564 try {
574 timer = new Timer(timeout, () { 565 timer = new Timer(timeout, () {
575 testCase._error("Test timed out after ${timeout.inSeconds} seconds."); 566 testCase._error("Test timed out after ${timeout.inSeconds} seconds.");
576 _nextTestCase(); 567 _nextTestCase();
577 }); 568 });
578 } on UnsupportedError catch (e) { 569 } on UnsupportedError catch (e) {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 702
712 if (!filterStacks) return trace; 703 if (!filterStacks) return trace;
713 704
714 // Format the stack trace by removing everything above TestCase._runTest, 705 // Format the stack trace by removing everything above TestCase._runTest,
715 // which is usually going to be irrelevant. Also fold together unittest and 706 // which is usually going to be irrelevant. Also fold together unittest and
716 // core library calls so only the function the user called is visible. 707 // core library calls so only the function the user called is visible.
717 return new Trace(trace.frames.takeWhile((frame) { 708 return new Trace(trace.frames.takeWhile((frame) {
718 return frame.package != 'unittest' || frame.member != 'TestCase._runTest'; 709 return frame.package != 'unittest' || frame.member != 'TestCase._runTest';
719 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore); 710 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore);
720 } 711 }
OLDNEW
« no previous file with comments | « pkg/unittest/lib/src/spread_args_helper.dart ('k') | pkg/unittest/test/unittest_invalid_ops_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698