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 |