| 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 |