| 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, use the pub package manager. | 8 * To import this library, use the pub package manager. |
| 9 * Create a pubspec.yaml file in your project and add | 9 * Create a pubspec.yaml file in your project and add |
| 10 * a dependency on unittest with the following lines: | 10 * a dependency on unittest with the following lines: |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 */ | 195 */ |
| 196 String _currentGroup = ''; | 196 String _currentGroup = ''; |
| 197 | 197 |
| 198 /** Separator used between group names and test names. */ | 198 /** Separator used between group names and test names. */ |
| 199 String groupSep = ' '; | 199 String groupSep = ' '; |
| 200 | 200 |
| 201 /** Tests executed in this suite. */ | 201 /** Tests executed in this suite. */ |
| 202 List<TestCase> _tests; | 202 List<TestCase> _tests; |
| 203 | 203 |
| 204 /** Get the list of tests. */ | 204 /** Get the list of tests. */ |
| 205 get testCases => _tests; | 205 List<TestCase> get testCases => _tests; |
| 206 | 206 |
| 207 /** | 207 /** |
| 208 * Callback used to run tests. Entrypoints can replace this with their own | 208 * Callback used to run tests. Entrypoints can replace this with their own |
| 209 * if they want. | 209 * if they want. |
| 210 */ | 210 */ |
| 211 Function _testRunner; | 211 Function _testRunner; |
| 212 | 212 |
| 213 /** Setup function called before each test in a group */ | 213 /** Setup function called before each test in a group */ |
| 214 Function _testSetup; | 214 Function _testSetup; |
| 215 | 215 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 int actualCalls = 0; | 302 int actualCalls = 0; |
| 303 TestCase testCase; | 303 TestCase testCase; |
| 304 bool complete; | 304 bool complete; |
| 305 static const sentinel = const _Sentinel(); | 305 static const sentinel = const _Sentinel(); |
| 306 | 306 |
| 307 _SpreadArgsHelper(Function callback, int minExpected, int maxExpected, | 307 _SpreadArgsHelper(Function callback, int minExpected, int maxExpected, |
| 308 Function isDone, String id) | 308 Function isDone, String id) |
| 309 : this.callback = callback, | 309 : this.callback = callback, |
| 310 minExpectedCalls = minExpected, | 310 minExpectedCalls = minExpected, |
| 311 maxExpectedCalls = (maxExpected == 0 && minExpected > 0) | 311 maxExpectedCalls = (maxExpected == 0 && minExpected > 0) |
| 312 ? minExpected | 312 ? minExpected |
| 313 : maxExpected, | 313 : maxExpected, |
| 314 this.isDone = isDone, | 314 this.isDone = isDone, |
| 315 testNum = _currentTest, | 315 testNum = _currentTest, |
| 316 this.id = _makeCallbackId(id, callback) { | 316 this.id = _makeCallbackId(id, callback) { |
| 317 ensureInitialized(); | 317 ensureInitialized(); |
| 318 if (!(_currentTest >= 0 && | 318 if (!(_currentTest >= 0 && |
| 319 _currentTest < _tests.length && | 319 _currentTest < _tests.length && |
| 320 _tests[_currentTest] != null)) { | 320 _tests[_currentTest] != null)) { |
| 321 print("No valid test, did you forget to run your test inside a call " | 321 print("No valid test, did you forget to run your test inside a call " |
| 322 "to test()?"); | 322 "to test()?"); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke; | 508 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke; |
| 509 } | 509 } |
| 510 | 510 |
| 511 /** | 511 /** |
| 512 * Indicate that [callback] is expected to be called until [isDone] returns | 512 * Indicate that [callback] is expected to be called until [isDone] returns |
| 513 * true. The unittest framework check [isDone] after each callback and only | 513 * true. The unittest framework check [isDone] after each callback and only |
| 514 * when it returns true will it continue with the following test. Using | 514 * when it returns true will it continue with the following test. Using |
| 515 * [expectAsyncUntil0] will also ensure that errors that occur within | 515 * [expectAsyncUntil0] will also ensure that errors that occur within |
| 516 * [callback] are tracked and reported. [callback] should take 0 positional | 516 * [callback] are tracked and reported. [callback] should take 0 positional |
| 517 * arguments (named arguments are not supported). [id] can be used to | 517 * arguments (named arguments are not supported). [id] can be used to |
| 518 * identify the callback in error messages (for example if it is called | 518 * identify the callback in error messages (for example if it is called |
| 519 * after the test case is complete). | 519 * after the test case is complete). |
| 520 */ | 520 */ |
| 521 // TODO(sigmund): deprecate this API when issue 2706 is fixed. | 521 // TODO(sigmund): deprecate this API when issue 2706 is fixed. |
| 522 Function expectAsyncUntil0(Function callback, Function isDone, {String id}) { | 522 Function expectAsyncUntil0(Function callback, Function isDone, {String id}) { |
| 523 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke0; | 523 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke0; |
| 524 } | 524 } |
| 525 | 525 |
| 526 /** | 526 /** |
| 527 * Like [expectAsyncUntil0] but [callback] should take 1 positional argument. | 527 * Like [expectAsyncUntil0] but [callback] should take 1 positional argument. |
| 528 */ | 528 */ |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 * should not be throwing unexpected exceptions that end up failing test | 669 * should not be throwing unexpected exceptions that end up failing test |
| 670 * cases! Furthermore, we need the final exception to be thrown but not | 670 * cases! Furthermore, we need the final exception to be thrown but not |
| 671 * caught by the test framework if any test cases failed. However, tests | 671 * caught by the test framework if any test cases failed. However, tests |
| 672 * that make use of a similar defer function *should* wrap the callback | 672 * that make use of a similar defer function *should* wrap the callback |
| 673 * (as we do in unitttest_test.dart). | 673 * (as we do in unitttest_test.dart). |
| 674 */ | 674 */ |
| 675 _defer(void callback()) { | 675 _defer(void callback()) { |
| 676 (new Future.immediate(null)).then((_) => callback()); | 676 (new Future.immediate(null)).then((_) => callback()); |
| 677 } | 677 } |
| 678 | 678 |
| 679 rerunTests() { | 679 void rerunTests() { |
| 680 _uncaughtErrorMessage = null; | 680 _uncaughtErrorMessage = null; |
| 681 _initialized = true; // We don't want to reset the test array. | 681 _initialized = true; // We don't want to reset the test array. |
| 682 runTests(); | 682 runTests(); |
| 683 } | 683 } |
| 684 | 684 |
| 685 /** | 685 /** |
| 686 * Filter the tests. [testFilter] can be a [RegExp], a [String] or a | 686 * Filter the tests. [testFilter] can be a [RegExp], a [String] or a |
| 687 * predicate function. This is different to enabling/disabling tests | 687 * predicate function. This is different to enabling/disabling tests |
| 688 * in that it removes the tests completely. | 688 * in that it removes the tests completely. |
| 689 */ | 689 */ |
| 690 void filterTests(testFilter) { | 690 void filterTests(testFilter) { |
| 691 var filterFunction; | 691 var filterFunction; |
| 692 if (testFilter is String) { | 692 if (testFilter is String) { |
| 693 RegExp re = new RegExp(testFilter); | 693 RegExp re = new RegExp(testFilter); |
| 694 filterFunction = (t) => re.hasMatch(t.description); | 694 filterFunction = (t) => re.hasMatch(t.description); |
| 695 } else if (testFilter is RegExp) { | 695 } else if (testFilter is RegExp) { |
| 696 filterFunction = (t) => testFilter.hasMatch(t.description); | 696 filterFunction = (t) => testFilter.hasMatch(t.description); |
| 697 } else if (testFilter is Function) { | 697 } else if (testFilter is Function) { |
| 698 filterFunction = testFilter; | 698 filterFunction = testFilter; |
| 699 } | 699 } |
| 700 _tests.retainMatching(filterFunction); | 700 _tests.retainMatching(filterFunction); |
| 701 } | 701 } |
| 702 | 702 |
| 703 /** Runs all queued tests, one at a time. */ | 703 /** Runs all queued tests, one at a time. */ |
| 704 runTests() { | 704 void runTests() { |
| 705 _currentTest = 0; | 705 _currentTest = 0; |
| 706 _currentGroup = ''; | 706 _currentGroup = ''; |
| 707 | 707 |
| 708 // If we are soloing a test, remove all the others. | 708 // If we are soloing a test, remove all the others. |
| 709 if (_soloTest != null) { | 709 if (_soloTest != null) { |
| 710 filterTests((t) => t == _soloTest); | 710 filterTests((t) => t == _soloTest); |
| 711 } | 711 } |
| 712 | 712 |
| 713 _config.onStart(); | 713 _config.onStart(); |
| 714 | 714 |
| 715 _defer(() { | 715 _defer(() { |
| 716 _testRunner(); | 716 _testRunner(); |
| 717 }); | 717 }); |
| 718 } | 718 } |
| 719 | 719 |
| 720 /** | 720 /** |
| 721 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, update | 721 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, it is |
| 722 * the [_currentTest] status accordingly. | 722 * passed to the corresponding test. |
| 723 * |
| 724 * The value returned by [tryBody] (if any) is returned by [guardAsync]. |
| 723 */ | 725 */ |
| 724 guardAsync(tryBody, [finallyBody, testNum = -1]) { | 726 guardAsync(Function tryBody, [Function finallyBody, int testNum = -1]) { |
| 725 if (testNum < 0) testNum = _currentTest; | 727 if (testNum < 0) testNum = _currentTest; |
| 726 try { | 728 try { |
| 727 return tryBody(); | 729 return tryBody(); |
| 728 } catch (e, trace) { | 730 } catch (e, trace) { |
| 729 _registerException(testNum, e, trace); | 731 _registerException(testNum, e, trace); |
| 730 } finally { | 732 } finally { |
| 731 if (finallyBody != null) finallyBody(); | 733 if (finallyBody != null) finallyBody(); |
| 732 } | 734 } |
| 733 } | 735 } |
| 734 | 736 |
| 735 /** | 737 /** |
| 736 * Registers that an exception was caught for the current test. | 738 * Registers that an exception was caught for the current test. |
| 737 */ | 739 */ |
| 738 registerException(e, [trace]) { | 740 void registerException(e, [trace]) { |
| 739 _registerException(_currentTest, e, trace); | 741 _registerException(_currentTest, e, trace); |
| 740 } | 742 } |
| 741 | 743 |
| 742 /** | 744 /** |
| 743 * Registers that an exception was caught for the current test. | 745 * Registers that an exception was caught for the current test. |
| 744 */ | 746 */ |
| 745 _registerException(testNum, e, [trace]) { | 747 _registerException(testNum, e, [trace]) { |
| 746 trace = trace == null ? '' : trace.toString(); | 748 trace = trace == null ? '' : trace.toString(); |
| 747 String message = (e is TestFailure) ? e.message : 'Caught $e'; | 749 String message = (e is TestFailure) ? e.message : 'Caught $e'; |
| 748 if (_tests[testNum].result == null) { | 750 if (_tests[testNum].result == null) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 } | 798 } |
| 797 | 799 |
| 798 String _fullSpec(String spec) { | 800 String _fullSpec(String spec) { |
| 799 if (spec == null) return '$_currentGroup'; | 801 if (spec == null) return '$_currentGroup'; |
| 800 return _currentGroup != '' ? '$_currentGroup$groupSep$spec' : spec; | 802 return _currentGroup != '' ? '$_currentGroup$groupSep$spec' : spec; |
| 801 } | 803 } |
| 802 | 804 |
| 803 /** | 805 /** |
| 804 * Lazily initializes the test library if not already initialized. | 806 * Lazily initializes the test library if not already initialized. |
| 805 */ | 807 */ |
| 806 ensureInitialized() { | 808 void ensureInitialized() { |
| 807 if (_initialized) { | 809 if (_initialized) { |
| 808 return; | 810 return; |
| 809 } | 811 } |
| 810 _initialized = true; | 812 _initialized = true; |
| 811 // Hook our async guard into the matcher library. | 813 // Hook our async guard into the matcher library. |
| 812 wrapAsync = expectAsync1; | 814 wrapAsync = expectAsync1; |
| 813 | 815 |
| 814 _tests = <TestCase>[]; | 816 _tests = <TestCase>[]; |
| 815 _testRunner = _nextBatch; | 817 _testRunner = _nextBatch; |
| 816 _uncaughtErrorMessage = null; | 818 _uncaughtErrorMessage = null; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 } | 855 } |
| 854 | 856 |
| 855 /** Enable a test by ID. */ | 857 /** Enable a test by ID. */ |
| 856 void enableTest(int testId) => _setTestEnabledState(testId, true); | 858 void enableTest(int testId) => _setTestEnabledState(testId, true); |
| 857 | 859 |
| 858 /** Disable a test by ID. */ | 860 /** Disable a test by ID. */ |
| 859 void disableTest(int testId) => _setTestEnabledState(testId, false); | 861 void disableTest(int testId) => _setTestEnabledState(testId, false); |
| 860 | 862 |
| 861 /** Signature for a test function. */ | 863 /** Signature for a test function. */ |
| 862 typedef dynamic TestFunction(); | 864 typedef dynamic TestFunction(); |
| OLD | NEW |