| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 * Support for writing Dart unit tests. | 6 * Support for writing Dart unit tests. |
| 7 * | 7 * |
| 8 * For information on installing and importing this library, see the | 8 * For information on installing and importing this library, see the |
| 9 * [unittest package on pub.dartlang.org] | 9 * [unittest package on pub.dartlang.org] |
| 10 * (http://pub.dartlang.org/packages/unittest). | 10 * (http://pub.dartlang.org/packages/unittest). |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 * }); | 76 * }); |
| 77 * }); | 77 * }); |
| 78 * } | 78 * } |
| 79 * | 79 * |
| 80 * Asynchronous tests: if callbacks expect between 0 and 2 positional arguments, | 80 * Asynchronous tests: if callbacks expect between 0 and 2 positional arguments, |
| 81 * depending on the suffix of expectAsyncX(). expectAsyncX() will wrap a | 81 * depending on the suffix of expectAsyncX(). expectAsyncX() will wrap a |
| 82 * function into a new callback and will not consider the test complete until | 82 * function into a new callback and will not consider the test complete until |
| 83 * that callback is run. A count argument can be provided to specify the number | 83 * that callback is run. A count argument can be provided to specify the number |
| 84 * of times the callback should be called (the default is 1). | 84 * of times the callback should be called (the default is 1). |
| 85 * | 85 * |
| 86 * import 'dart:async'; |
| 86 * import 'package:unittest/unittest.dart'; | 87 * import 'package:unittest/unittest.dart'; |
| 87 * import 'dart:isolate'; | 88 * void main() { |
| 88 * main() { | |
| 89 * test('callback is executed once', () { | 89 * test('callback is executed once', () { |
| 90 * // wrap the callback of an asynchronous call with [expectAsync0] if | 90 * // wrap the callback of an asynchronous call with [expectAsync0] if |
| 91 * // the callback takes 0 arguments... | 91 * // the callback takes 0 arguments... |
| 92 * var timer = Timer.run(expectAsync0(() { | 92 * var timer = Timer.run(expectAsync0(() { |
| 93 * int x = 2 + 3; | 93 * int x = 2 + 3; |
| 94 * expect(x, equals(5)); | 94 * expect(x, equals(5)); |
| 95 * })); | 95 * })); |
| 96 * }); | 96 * }); |
| 97 * | 97 * |
| 98 * test('callback is executed twice', () { | 98 * test('callback is executed twice', () { |
| 99 * var callback = expectAsync0(() { | 99 * var callback = expectAsync0(() { |
| 100 * int x = 2 + 3; | 100 * int x = 2 + 3; |
| 101 * expect(x, equals(5)); | 101 * expect(x, equals(5)); |
| 102 * }, count: 2); // <-- we can indicate multiplicity to [expectAsync0] | 102 * }, count: 2); // <-- we can indicate multiplicity to [expectAsync0] |
| 103 * Timer.run(callback); | 103 * Timer.run(callback); |
| 104 * Timer.run(callback); | 104 * Timer.run(callback); |
| 105 * }); | 105 * }); |
| 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 and block the completion of the |
| 109 * exceptions (treated as test failures). There may be times when the number of | 109 * test until the wrapped callback has been called the specified number of times |
| 110 * times a callback should be called is non-deterministic. In this case a dummy | 110 * -- the default is 1. There may be times when the number of times a callback |
| 111 * callback can be created with expectAsync0((){}) and this can be called from | 111 * should be called is non-deterministic. In this case a dummy callback can be |
| 112 * the real callback when it is finally complete. In this case the body of the | 112 * created with expectAsync0((){}) and this can be called from the real callback |
| 113 * callback should be protected within a call to guardAsync(); this will ensure | 113 * when it is finally complete. |
| 114 * that exceptions are properly handled. | |
| 115 * | 114 * |
| 116 * A variation on this is expectAsyncUntilX(), which takes a callback as the | 115 * 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 | 116 * 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 | 117 * time * the callback is called, the predicate function will be called; if it |
| 119 * returns false the test will still be considered incomplete. | 118 * returns false the test will still be considered incomplete. |
| 120 * | 119 * |
| 121 * Test functions can return [Future]s, which provide another way of doing | 120 * Test functions can return [Future]s, which provide another way of doing |
| 122 * asynchronous tests. The test framework will handle exceptions thrown by | 121 * 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. | 122 * 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 | 123 * |
| 125 * test that may be invoked from a top level context (for example, with | 124 * import 'dart:async'; |
| 126 * Timer.run()], as the Future exception handler may not capture exceptions | 125 * import 'package:unittest/unittest.dart'; |
| 127 * in such code. | 126 * void main() { |
| 127 * test('test that time has passed', () { |
| 128 * var duration = const Duration(milliseconds: 200); |
| 129 * var time = new DateTime.now(); |
| 130 * |
| 131 * return new Future.delayed(duration).then((_) { |
| 132 * var delta = new DateTime.now().difference(time); |
| 133 * |
| 134 * expect(delta, greaterThanOrEqualTo(duration)); |
| 135 * }); |
| 136 * }); |
| 137 * } |
| 128 * | 138 * |
| 129 * Note: Due to some language limitations we have to use different functions | 139 * Note: Due to some language limitations we have to use different functions |
| 130 * depending on the number of positional arguments of the callback. In the | 140 * depending on the number of positional arguments of the callback. In the |
| 131 * future, we plan to expose a single `expectAsync` function that can be used | 141 * future, we plan to expose a single `expectAsync` function that can be used |
| 132 * regardless of the number of positional arguments. This requires new langauge | 142 * regardless of the number of positional arguments. This requires new langauge |
| 133 * features or fixes to the current spec (e.g. see | 143 * features or fixes to the current spec (e.g. see |
| 134 * [Issue 2706](http://dartbug.com/2706)). | 144 * [Issue 2706](http://dartbug.com/2706)). |
| 135 */ | 145 */ |
| 136 library unittest; | 146 library unittest; |
| 137 | 147 |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 | 712 |
| 703 if (!filterStacks) return trace; | 713 if (!filterStacks) return trace; |
| 704 | 714 |
| 705 // Format the stack trace by removing everything above TestCase._runTest, | 715 // Format the stack trace by removing everything above TestCase._runTest, |
| 706 // which is usually going to be irrelevant. Also fold together unittest and | 716 // which is usually going to be irrelevant. Also fold together unittest and |
| 707 // core library calls so only the function the user called is visible. | 717 // core library calls so only the function the user called is visible. |
| 708 return new Trace(trace.frames.takeWhile((frame) { | 718 return new Trace(trace.frames.takeWhile((frame) { |
| 709 return frame.package != 'unittest' || frame.member != 'TestCase._runTest'; | 719 return frame.package != 'unittest' || frame.member != 'TestCase._runTest'; |
| 710 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore); | 720 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore); |
| 711 } | 721 } |
| OLD | NEW |