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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 * } | 106 * } |
107 * | 107 * |
108 * expectAsyncX() will wrap the callback code in a try/catch handler to handle | 108 * expectAsyncX() will wrap the callback code in a try/catch handler to handle |
109 * exceptions (treated as test failures). There may be times when the number of | 109 * exceptions (treated as test failures). There may be times when the number of |
110 * times a callback should be called is non-deterministic. In this case a dummy | 110 * times a callback should be called is non-deterministic. In this case a dummy |
111 * callback can be created with expectAsync0((){}) and this can be called from | 111 * callback can be created with expectAsync0((){}) and this can be called from |
112 * the real callback when it is finally complete. In this case the body of the | 112 * the real callback when it is finally complete. In this case the body of the |
113 * callback should be protected within a call to guardAsync(); this will ensure | 113 * callback should be protected within a call to guardAsync(); this will ensure |
114 * that exceptions are properly handled. | 114 * that exceptions are properly handled. |
115 * | 115 * |
| 116 * A variation on this is expectAsyncUntilX(), which takes a callback as the |
| 117 * first parameter and a predicate function as the second parameter; after each |
| 118 * time * the callback is called, the predicate function will be called; if it |
| 119 * returns false the test will still be considered incomplete. |
| 120 * |
| 121 * Test functions can return [Future]s, which provide another way of doing |
| 122 * asynchronous tests. The test framework will handle exceptions thrown by |
| 123 * the Future, and will advance to the next test when the Future is complete. |
| 124 * It is still important to use expectAsync/guardAsync with any parts of the |
| 125 * test that may be invoked from a top level context (for example, with |
| 126 * Timer.run()], as the Future exception handler may not capture exceptions |
| 127 * in such code. |
| 128 * |
116 * Note: due to some language limitations we have to use different functions | 129 * Note: due to some language limitations we have to use different functions |
117 * depending on the number of positional arguments of the callback. In the | 130 * depending on the number of positional arguments of the callback. In the |
118 * future, we plan to expose a single `expectAsync` function that can be used | 131 * future, we plan to expose a single `expectAsync` function that can be used |
119 * regardless of the number of positional arguments. This requires new langauge | 132 * regardless of the number of positional arguments. This requires new langauge |
120 * features or fixes to the current spec (e.g. see | 133 * features or fixes to the current spec (e.g. see |
121 * [Issue 2706](http://dartbug.com/2706)). | 134 * [Issue 2706](http://dartbug.com/2706)). |
122 * | 135 * |
123 * Meanwhile, we plan to add this alternative API for callbacks of more than 2 | 136 * Meanwhile, we plan to add this alternative API for callbacks of more than 2 |
124 * arguments or that take named parameters. (this is not implemented yet, | 137 * arguments or that take named parameters. (this is not implemented yet, |
125 * but will be coming here soon). | 138 * but will be coming here soon). |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 */ | 684 */ |
672 void _reportTestError(String msg, String trace) { | 685 void _reportTestError(String msg, String trace) { |
673 if (_currentTest < _tests.length) { | 686 if (_currentTest < _tests.length) { |
674 final testCase = _tests[_currentTest]; | 687 final testCase = _tests[_currentTest]; |
675 testCase.error(msg, trace); | 688 testCase.error(msg, trace); |
676 } else { | 689 } else { |
677 _uncaughtErrorMessage = "$msg: $trace"; | 690 _uncaughtErrorMessage = "$msg: $trace"; |
678 } | 691 } |
679 } | 692 } |
680 | 693 |
681 /** Runs [callback] at the end of the event loop. */ | 694 /** |
| 695 * Runs [callback] at the end of the event loop. Note that we don't wrap |
| 696 * the callback in guardAsync; this is for test framework functions which |
| 697 * should not be throwing unexpected exceptions that end up failing test |
| 698 * cases! Furthermore, we need the final exception to be thrown but not |
| 699 * caught by the test framework if any test cases failed. However, tests |
| 700 * that make use of a similar defer function *should* wrap the callback |
| 701 * (as we do in unitttest_test.dart). |
| 702 */ |
682 _defer(void callback()) { | 703 _defer(void callback()) { |
683 // Exploit isolate ports as a platform-independent mechanism to queue a | 704 (new Future.immediate(null)).then((_) => callback()); |
684 // message at the end of the event loop. | |
685 // TODO(sigmund): expose this functionality somewhere in our libraries. | |
686 final port = new ReceivePort(); | |
687 port.receive((msg, reply) { | |
688 callback(); | |
689 port.close(); | |
690 }); | |
691 port.toSendPort().send(null, null); | |
692 } | 705 } |
693 | 706 |
694 rerunTests() { | 707 rerunTests() { |
695 _uncaughtErrorMessage = null; | 708 _uncaughtErrorMessage = null; |
696 _initialized = true; // We don't want to reset the test array. | 709 _initialized = true; // We don't want to reset the test array. |
697 runTests(); | 710 runTests(); |
698 } | 711 } |
699 | 712 |
700 /** | 713 /** |
701 * Filter the tests. [testFilter] can be a [RegExp], a [String] or a | 714 * Filter the tests. [testFilter] can be a [RegExp], a [String] or a |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 */ | 787 */ |
775 _nextBatch() { | 788 _nextBatch() { |
776 while (true) { | 789 while (true) { |
777 if (_currentTest >= _tests.length) { | 790 if (_currentTest >= _tests.length) { |
778 _completeTests(); | 791 _completeTests(); |
779 break; | 792 break; |
780 } | 793 } |
781 final testCase = _tests[_currentTest]; | 794 final testCase = _tests[_currentTest]; |
782 var f = guardAsync(testCase.run, null, _currentTest); | 795 var f = guardAsync(testCase.run, null, _currentTest); |
783 if (f != null) { | 796 if (f != null) { |
784 f.then((_){}) | 797 f.whenComplete(() { |
785 .catchError((e) { | |
786 testCase.error(e.toString(), e.stackTrace); | |
787 }) | |
788 .whenComplete(() { | |
789 _nextTestCase(); // Schedule the next test. | 798 _nextTestCase(); // Schedule the next test. |
790 }); | 799 }); |
791 break; | 800 break; |
792 } | 801 } |
793 _currentTest++; | 802 _currentTest++; |
794 } | 803 } |
795 } | 804 } |
796 | 805 |
797 /** Publish results on the page and notify controller. */ | 806 /** Publish results on the page and notify controller. */ |
798 _completeTests() { | 807 _completeTests() { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 } | 885 } |
877 | 886 |
878 /** Enable a test by ID. */ | 887 /** Enable a test by ID. */ |
879 void enableTest(int testId) => _setTestEnabledState(testId, true); | 888 void enableTest(int testId) => _setTestEnabledState(testId, true); |
880 | 889 |
881 /** Disable a test by ID. */ | 890 /** Disable a test by ID. */ |
882 void disableTest(int testId) => _setTestEnabledState(testId, false); | 891 void disableTest(int testId) => _setTestEnabledState(testId, false); |
883 | 892 |
884 /** Signature for a test function. */ | 893 /** Signature for a test function. */ |
885 typedef void TestFunction(); | 894 typedef void TestFunction(); |
OLD | NEW |