| OLD | NEW |
| 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 * |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 // as default values to named arguments. | 316 // as default values to named arguments. |
| 317 final _sentinel = const _Sentinel(); | 317 final _sentinel = const _Sentinel(); |
| 318 | 318 |
| 319 /** Simulates spread arguments using named arguments. */ | 319 /** Simulates spread arguments using named arguments. */ |
| 320 // TODO(sigmund): remove this class and simply use a closure with named | 320 // TODO(sigmund): remove this class and simply use a closure with named |
| 321 // arguments (if still applicable). | 321 // arguments (if still applicable). |
| 322 class _SpreadArgsHelper { | 322 class _SpreadArgsHelper { |
| 323 Function _callback; | 323 Function _callback; |
| 324 int _expectedCalls; | 324 int _expectedCalls; |
| 325 int _calls = 0; | 325 int _calls = 0; |
| 326 int _testNum; |
| 326 TestCase _testCase; | 327 TestCase _testCase; |
| 327 Function _shouldCallBack; | 328 Function _shouldCallBack; |
| 328 Function _isDone; | 329 Function _isDone; |
| 329 | 330 |
| 330 _init(Function callback, Function shouldCallBack, Function isDone, | 331 _init(Function callback, Function shouldCallBack, Function isDone, |
| 331 [expectedCalls = 0]) { | 332 [expectedCalls = 0]) { |
| 332 ensureInitialized(); | 333 ensureInitialized(); |
| 333 assert(_currentTest < _tests.length); | 334 assert(_currentTest < _tests.length); |
| 334 _callback = callback; | 335 _callback = callback; |
| 335 _shouldCallBack = shouldCallBack; | 336 _shouldCallBack = shouldCallBack; |
| 336 _isDone = isDone; | 337 _isDone = isDone; |
| 337 _expectedCalls = expectedCalls; | 338 _expectedCalls = expectedCalls; |
| 339 _testNum = _currentTest; |
| 338 _testCase = _tests[_currentTest]; | 340 _testCase = _tests[_currentTest]; |
| 339 if (expectedCalls > 0) { | 341 if (expectedCalls > 0) { |
| 340 _testCase.callbacks++; | 342 _testCase.callbacks++; |
| 341 } | 343 } |
| 342 } | 344 } |
| 343 | 345 |
| 344 _SpreadArgsHelper(callback, shouldCallBack, isDone) { | 346 _SpreadArgsHelper(callback, shouldCallBack, isDone) { |
| 345 _init(callback, shouldCallBack, isDone); | 347 _init(callback, shouldCallBack, isDone); |
| 346 } | 348 } |
| 347 | 349 |
| 348 _SpreadArgsHelper.fixedCallCount(callback, expectedCalls) { | 350 _SpreadArgsHelper.fixedCallCount(callback, expectedCalls) { |
| 349 _init(callback, _checkCallCount, _allCallsDone, expectedCalls); | 351 _init(callback, _checkCallCount, _allCallsDone, expectedCalls); |
| 350 } | 352 } |
| 351 | 353 |
| 352 _SpreadArgsHelper.variableCallCount(callback, isDone) { | 354 _SpreadArgsHelper.variableCallCount(callback, isDone) { |
| 353 _init(callback, _always, isDone, 1); | 355 _init(callback, _always, isDone, 1); |
| 354 } | 356 } |
| 355 | 357 |
| 358 _SpreadArgsHelper.optionalCalls(callback) { |
| 359 _init(callback, _always, () => false, 0); |
| 360 } |
| 361 |
| 356 _after() { | 362 _after() { |
| 357 if (_isDone()) { | 363 if (_isDone()) { |
| 358 _handleAllCallbacksDone(); | 364 _handleAllCallbacksDone(); |
| 359 } | 365 } |
| 360 } | 366 } |
| 361 | 367 |
| 362 _allCallsDone() => _calls == _expectedCalls; | 368 _allCallsDone() => _calls == _expectedCalls; |
| 363 | 369 |
| 364 _always() { | 370 _always() { |
| 365 // Always run except if the test is done. | 371 // Always run except if the test is done. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 391 } else if (arg4 == _sentinel) { | 397 } else if (arg4 == _sentinel) { |
| 392 return _callback(arg0, arg1, arg2, arg3); | 398 return _callback(arg0, arg1, arg2, arg3); |
| 393 } else { | 399 } else { |
| 394 _testCase.error( | 400 _testCase.error( |
| 395 'unittest lib does not support callbacks with more than' | 401 'unittest lib does not support callbacks with more than' |
| 396 ' 4 arguments.', | 402 ' 4 arguments.', |
| 397 ''); | 403 ''); |
| 398 _state = _UNCAUGHT_ERROR; | 404 _state = _UNCAUGHT_ERROR; |
| 399 } | 405 } |
| 400 }, | 406 }, |
| 401 _after); | 407 _after, _testNum); |
| 402 } | 408 } |
| 403 | 409 |
| 404 invoke0() { | 410 invoke0() { |
| 405 return guardAsync( | 411 return guardAsync( |
| 406 () { | 412 () { |
| 407 ++_calls; | 413 ++_calls; |
| 408 if (_shouldCallBack()) { | 414 if (_shouldCallBack()) { |
| 409 return _callback(); | 415 return _callback(); |
| 410 } | 416 } |
| 411 }, | 417 }, |
| 412 _after); | 418 _after, _testNum); |
| 413 } | 419 } |
| 414 | 420 |
| 415 invoke1(arg1) { | 421 invoke1(arg1) { |
| 416 return guardAsync( | 422 return guardAsync( |
| 417 () { | 423 () { |
| 418 ++_calls; | 424 ++_calls; |
| 419 if (_shouldCallBack()) { | 425 if (_shouldCallBack()) { |
| 420 return _callback(arg1); | 426 return _callback(arg1); |
| 421 } | 427 } |
| 422 }, | 428 }, |
| 423 _after); | 429 _after, _testNum); |
| 424 } | 430 } |
| 425 | 431 |
| 426 invoke2(arg1, arg2) { | 432 invoke2(arg1, arg2) { |
| 427 return guardAsync( | 433 return guardAsync( |
| 428 () { | 434 () { |
| 429 ++_calls; | 435 ++_calls; |
| 430 if (_shouldCallBack()) { | 436 if (_shouldCallBack()) { |
| 431 return _callback(arg1, arg2); | 437 return _callback(arg1, arg2); |
| 432 } | 438 } |
| 433 }, | 439 }, |
| 434 _after); | 440 _after, _testNum); |
| 435 } | 441 } |
| 436 | 442 |
| 437 /** Returns false if we exceded the number of expected calls. */ | 443 /** Returns false if we exceded the number of expected calls. */ |
| 438 bool _checkCallCount() { | 444 bool _checkCallCount() { |
| 439 if (_calls > _expectedCalls) { | 445 if (_calls > _expectedCalls) { |
| 440 _testCase.error( | 446 _testCase.error( |
| 441 'Callback called more times than expected ' | 447 'Callback called more times than expected ' |
| 442 '($_calls > $_expectedCalls).', | 448 '($_calls > $_expectedCalls).', |
| 443 ''); | 449 ''); |
| 444 _state = _UNCAUGHT_ERROR; | 450 _state = _UNCAUGHT_ERROR; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 | 526 |
| 521 /** | 527 /** |
| 522 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments. | 528 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments. |
| 523 */ | 529 */ |
| 524 // TODO(sigmund): deprecate this API when issue 2706 is fixed. | 530 // TODO(sigmund): deprecate this API when issue 2706 is fixed. |
| 525 Function expectAsyncUntil2(Function callback, Function isDone) { | 531 Function expectAsyncUntil2(Function callback, Function isDone) { |
| 526 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke2; | 532 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke2; |
| 527 } | 533 } |
| 528 | 534 |
| 529 /** | 535 /** |
| 536 * Wraps the [callback] in a new function and returns that function. The new |
| 537 * function will be able to handle exceptions by directing them to the correct |
| 538 * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that |
| 539 * might optionally be called but may never be called during the test. |
| 540 * [callback] should take between 0 and 4 positional arguments (named arguments |
| 541 * are not supported). |
| 542 */ |
| 543 Function _protectAsync(Function callback) { |
| 544 return new _SpreadArgsHelper.optionalCalls(callback).invoke; |
| 545 } |
| 546 |
| 547 /** |
| 548 * Wraps the [callback] in a new function and returns that function. The new |
| 549 * function will be able to handle exceptions by directing them to the correct |
| 550 * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that |
| 551 * might optionally be called but may never be called during the test. |
| 552 * [callback] should take 0 positional arguments (named arguments are not |
| 553 * supported). |
| 554 */ |
| 555 // TODO(sigmund): deprecate this API when issue 2706 is fixed. |
| 556 Function protectAsync0(Function callback) { |
| 557 return new _SpreadArgsHelper.optionalCalls(callback).invoke0; |
| 558 } |
| 559 |
| 560 /** |
| 561 * Like [protectAsync0] but [callback] should take 1 positional argument. |
| 562 */ |
| 563 // TODO(sigmund): deprecate this API when issue 2706 is fixed. |
| 564 Function protectAsync1(Function callback) { |
| 565 return new _SpreadArgsHelper.optionalCalls(callback).invoke1; |
| 566 } |
| 567 |
| 568 /** |
| 569 * Like [protectAsync0] but [callback] should take 2 positional arguments. |
| 570 */ |
| 571 // TODO(sigmund): deprecate this API when issue 2706 is fixed. |
| 572 Function protectAsync2(Function callback) { |
| 573 return new _SpreadArgsHelper.optionalCalls(callback).invoke2; |
| 574 } |
| 575 |
| 576 /** |
| 530 * Creates a new named group of tests. Calls to group() or test() within the | 577 * Creates a new named group of tests. Calls to group() or test() within the |
| 531 * body of the function passed to this will inherit this group's description. | 578 * body of the function passed to this will inherit this group's description. |
| 532 */ | 579 */ |
| 533 void group(String description, void body()) { | 580 void group(String description, void body()) { |
| 534 ensureInitialized(); | 581 ensureInitialized(); |
| 535 | 582 |
| 536 // Concatenate the new group. | 583 // Concatenate the new group. |
| 537 final parentGroup = _currentGroup; | 584 final parentGroup = _currentGroup; |
| 538 if (_currentGroup != '') { | 585 if (_currentGroup != '') { |
| 539 // Add a space. | 586 // Add a space. |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 for (var i = 0; i < _tests.length; i++) { | 729 for (var i = 0; i < _tests.length; i++) { |
| 683 _tests[i].callbacks = 0; // Note - won't work with old asyncTests. | 730 _tests[i].callbacks = 0; // Note - won't work with old asyncTests. |
| 684 } | 731 } |
| 685 runTests(); | 732 runTests(); |
| 686 } | 733 } |
| 687 | 734 |
| 688 /** | 735 /** |
| 689 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, update | 736 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, update |
| 690 * the [_currentTest] status accordingly. | 737 * the [_currentTest] status accordingly. |
| 691 */ | 738 */ |
| 692 guardAsync(tryBody, [finallyBody]) { | 739 guardAsync(tryBody, [finallyBody, testNum = -1]) { |
| 740 if (testNum < 0) testNum = _currentTest; |
| 693 try { | 741 try { |
| 694 return tryBody(); | 742 return tryBody(); |
| 695 } catch (var e, var trace) { | 743 } catch (var e, var trace) { |
| 696 registerException(e, trace); | 744 registerException(testNum, e, trace); |
| 697 } finally { | 745 } finally { |
| 698 _state = _READY; | 746 _state = _READY; |
| 699 if (finallyBody != null) finallyBody(); | 747 if (finallyBody != null) finallyBody(); |
| 700 } | 748 } |
| 701 } | 749 } |
| 702 | 750 |
| 703 /** | 751 /** |
| 704 * Registers that an exception was caught for the current test. | 752 * Registers that an exception was caught for the current test. |
| 705 */ | 753 */ |
| 706 registerException(e, [trace]) { | 754 registerException(testNum, e, [trace]) { |
| 707 if (e is ExpectException) { | 755 if (_tests[testNum].result == null) { |
| 708 Expect.isTrue(_currentTest < _tests.length); | 756 if (e is ExpectException) { |
| 709 if (_state != _UNCAUGHT_ERROR) { | 757 _tests[testNum].fail(e.message, trace == null ? '' : trace.toString()); |
| 710 _tests[_currentTest].fail(e.message, | 758 } else { |
| 711 trace == null ? '' : trace.toString()); | 759 _tests[testNum].fail('Caught $e', trace == null ? '' : trace.toString()); |
| 712 } | 760 } |
| 713 } else { | 761 } else { |
| 714 if (_state == _RUNNING_TEST) { | 762 _tests[testNum].error('Caught $e', trace == null ? '' : trace.toString()); |
| 715 // If a random exception is thrown from within a test, we consider that | |
| 716 // a test failure too. A test case implicitly has an expectation that it | |
| 717 // will run to completion without an uncaught exception being thrown. | |
| 718 _tests[_currentTest].fail('Caught $e', | |
| 719 trace == null ? '' : trace.toString()); | |
| 720 } else if (_state != _UNCAUGHT_ERROR) { | |
| 721 _tests[_currentTest].error('Caught $e', | |
| 722 trace == null ? '' : trace.toString()); | |
| 723 } | |
| 724 } | 763 } |
| 725 _nextTestCase(); | 764 if (testNum == _currentTest) { |
| 765 _nextTestCase(); |
| 766 } |
| 726 } | 767 } |
| 727 | 768 |
| 728 /** | 769 /** |
| 729 * Runs a batch of tests, yielding whenever an asynchronous test starts | 770 * Runs a batch of tests, yielding whenever an asynchronous test starts |
| 730 * running. Tests will resume executing when such asynchronous test calls | 771 * running. Tests will resume executing when such asynchronous test calls |
| 731 * [done] or if it fails with an exception. | 772 * [done] or if it fails with an exception. |
| 732 */ | 773 */ |
| 733 _nextBatch() { | 774 _nextBatch() { |
| 734 while (_currentTest < _tests.length) { | 775 while (_currentTest < _tests.length) { |
| 735 final testCase = _tests[_currentTest]; | 776 final testCase = _tests[_currentTest]; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 } | 874 } |
| 834 | 875 |
| 835 /** Enable a test by ID. */ | 876 /** Enable a test by ID. */ |
| 836 void enableTest(int testId) => _setTestEnabledState(testId, true); | 877 void enableTest(int testId) => _setTestEnabledState(testId, true); |
| 837 | 878 |
| 838 /** Disable a test by ID. */ | 879 /** Disable a test by ID. */ |
| 839 void disableTest(int testId) => _setTestEnabledState(testId, false); | 880 void disableTest(int testId) => _setTestEnabledState(testId, false); |
| 840 | 881 |
| 841 /** Signature for a test function. */ | 882 /** Signature for a test function. */ |
| 842 typedef void TestFunction(); | 883 typedef void TestFunction(); |
| OLD | NEW |