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 |