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 /// Support for writing Dart unit tests. | 5 /// Support for writing Dart unit tests. |
6 /// | 6 /// |
7 /// For information on installing and importing this library, see the | 7 /// For information on installing and importing this library, see the |
8 /// [unittest package on pub.dartlang.org] | 8 /// [unittest package on pub.dartlang.org] |
9 /// (http://pub.dartlang.org/packages/unittest). | 9 /// (http://pub.dartlang.org/packages/unittest). |
10 /// | 10 /// |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 /// expect(delta, greaterThanOrEqualTo(duration)); | 131 /// expect(delta, greaterThanOrEqualTo(duration)); |
132 /// }); | 132 /// }); |
133 /// }); | 133 /// }); |
134 /// } | 134 /// } |
135 library unittest; | 135 library unittest; |
136 | 136 |
137 import 'dart:async'; | 137 import 'dart:async'; |
138 import 'dart:collection'; | 138 import 'dart:collection'; |
139 import 'dart:isolate'; | 139 import 'dart:isolate'; |
140 | 140 |
141 import 'package:matcher/matcher.dart' show DefaultFailureHandler, | 141 import 'package:matcher/matcher.dart' |
142 configureExpectFailureHandler, TestFailure, wrapAsync; | 142 show |
| 143 DefaultFailureHandler, |
| 144 configureExpectFailureHandler, |
| 145 TestFailure, |
| 146 wrapAsync; |
143 export 'package:matcher/matcher.dart'; | 147 export 'package:matcher/matcher.dart'; |
144 | 148 |
145 import 'src/utils.dart'; | 149 import 'src/utils.dart'; |
146 | 150 |
147 import 'src/configuration.dart'; | 151 import 'src/configuration.dart'; |
148 export 'src/configuration.dart'; | 152 export 'src/configuration.dart'; |
149 | 153 |
150 part 'src/simple_configuration.dart'; | 154 part 'src/simple_configuration.dart'; |
151 part 'src/group_context.dart'; | 155 part 'src/group_context.dart'; |
152 part 'src/spread_args_helper.dart'; | 156 part 'src/spread_args_helper.dart'; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 | 216 |
213 /// Tests executed in this suite. | 217 /// Tests executed in this suite. |
214 List<TestCase> get testCases => | 218 List<TestCase> get testCases => |
215 new UnmodifiableListView<TestCase>(_environment.testCases); | 219 new UnmodifiableListView<TestCase>(_environment.testCases); |
216 | 220 |
217 /// Interval (in msecs) after which synchronous tests will insert an async | 221 /// Interval (in msecs) after which synchronous tests will insert an async |
218 /// delay to allow DOM or other updates. | 222 /// delay to allow DOM or other updates. |
219 const int BREATH_INTERVAL = 200; | 223 const int BREATH_INTERVAL = 200; |
220 | 224 |
221 /// [TestCase] currently being executed. | 225 /// [TestCase] currently being executed. |
222 TestCase get currentTestCase => | 226 TestCase get currentTestCase => (_environment.currentTestCaseIndex >= 0 && |
223 (_environment.currentTestCaseIndex >= 0 && | 227 _environment.currentTestCaseIndex < testCases.length) |
224 _environment.currentTestCaseIndex < testCases.length) | 228 ? testCases[_environment.currentTestCaseIndex] |
225 ? testCases[_environment.currentTestCaseIndex] | 229 : null; |
226 : null; | |
227 | 230 |
228 /* Test case result strings. */ | 231 /* Test case result strings. */ |
229 // TODO(gram) we should change these constants to use a different string | 232 // TODO(gram) we should change these constants to use a different string |
230 // (so that writing 'FAIL' in the middle of a test doesn't | 233 // (so that writing 'FAIL' in the middle of a test doesn't |
231 // imply that the test fails). We can't do it without also changing | 234 // imply that the test fails). We can't do it without also changing |
232 // the testrunner and test.dart though. | 235 // the testrunner and test.dart though. |
233 /// Result string for a passing test case. | 236 /// Result string for a passing test case. |
234 const PASS = 'pass'; | 237 const PASS = 'pass'; |
235 /// Result string for a failing test case. | 238 /// Result string for a failing test case. |
236 const FAIL = 'fail'; | 239 const FAIL = 'fail'; |
237 /// Result string for an test case with an error. | 240 /// Result string for an test case with an error. |
238 const ERROR = 'error'; | 241 const ERROR = 'error'; |
239 | 242 |
240 /// Creates a new test case with the given description and body. The | 243 /// Creates a new test case with the given description and body. The |
241 /// description will include the descriptions of any surrounding group() | 244 /// description will include the descriptions of any surrounding group() |
242 /// calls. | 245 /// calls. |
243 void test(String spec, TestFunction body) { | 246 void test(String spec, TestFunction body) { |
244 _requireNotRunning(); | 247 _requireNotRunning(); |
245 ensureInitialized(); | 248 ensureInitialized(); |
246 if (!_environment.soloTestSeen || _environment.soloNestingLevel > 0) { | 249 if (!_environment.soloTestSeen || _environment.soloNestingLevel > 0) { |
247 var testcase = new TestCase._internal(testCases.length + 1, _fullSpec(spec), | 250 var testcase = |
248 body); | 251 new TestCase._internal(testCases.length + 1, _fullSpec(spec), body); |
249 _testCases.add(testcase); | 252 _testCases.add(testcase); |
250 } | 253 } |
251 } | 254 } |
252 | 255 |
253 /// Convenience function for skipping a test. | 256 /// Convenience function for skipping a test. |
254 void skip_test(String spec, TestFunction body) {} | 257 void skip_test(String spec, TestFunction body) {} |
255 | 258 |
256 /// Creates a new test case with the given description and body. The | 259 /// Creates a new test case with the given description and body. The |
257 /// description will include the descriptions of any surrounding group() | 260 /// description will include the descriptions of any surrounding group() |
258 /// calls. | 261 /// calls. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 /// it was already complete). A value of 0 for [max] (the default) will set | 302 /// it was already complete). A value of 0 for [max] (the default) will set |
300 /// the upper bound to the same value as [count]; i.e. the callback should be | 303 /// the upper bound to the same value as [count]; i.e. the callback should be |
301 /// called exactly [count] times. A value of -1 for [max] will mean no upper | 304 /// called exactly [count] times. A value of -1 for [max] will mean no upper |
302 /// bound. | 305 /// bound. |
303 /// | 306 /// |
304 /// [reason] is optional and is typically not supplied, as a reason is generated | 307 /// [reason] is optional and is typically not supplied, as a reason is generated |
305 /// by the unittest package; if reason is included it is appended to the | 308 /// by the unittest package; if reason is included it is appended to the |
306 /// generated reason. | 309 /// generated reason. |
307 Function expectAsync(Function callback, | 310 Function expectAsync(Function callback, |
308 {int count: 1, int max: 0, String id, String reason}) => | 311 {int count: 1, int max: 0, String id, String reason}) => |
309 new _SpreadArgsHelper(callback, count, max, id, reason).func; | 312 new _SpreadArgsHelper(callback, count, max, id, reason).func; |
310 | 313 |
311 /// Indicate that [callback] is expected to be called until [isDone] returns | 314 /// Indicate that [callback] is expected to be called until [isDone] returns |
312 /// true. | 315 /// true. |
313 /// | 316 /// |
314 /// The unittest framework checks [isDone] after each callback and only | 317 /// The unittest framework checks [isDone] after each callback and only |
315 /// when it returns true will it continue with the following test. Using | 318 /// when it returns true will it continue with the following test. Using |
316 /// [expectAsyncUntil] will also ensure that errors that occur within | 319 /// [expectAsyncUntil] will also ensure that errors that occur within |
317 /// [callback] are tracked and reported. [callback] should take 0 positional | 320 /// [callback] are tracked and reported. [callback] should take 0 positional |
318 /// arguments (named arguments are not supported). [id] can be used to | 321 /// arguments (named arguments are not supported). [id] can be used to |
319 /// identify the callback in error messages (for example if it is called | 322 /// identify the callback in error messages (for example if it is called |
320 /// after the test case is complete). | 323 /// after the test case is complete). |
321 /// | 324 /// |
322 /// [reason] is optional and is typically not supplied, as a reason is generated | 325 /// [reason] is optional and is typically not supplied, as a reason is generated |
323 /// by the unittest package; if reason is included it is appended to the | 326 /// by the unittest package; if reason is included it is appended to the |
324 /// generated reason. | 327 /// generated reason. |
325 Function expectAsyncUntil(Function callback, bool isDone(), | 328 Function expectAsyncUntil(Function callback, bool isDone(), |
326 {String id, String reason}) => | 329 {String id, String reason}) => |
327 new _SpreadArgsHelper(callback, 0, -1, id, reason, isDone: isDone).func; | 330 new _SpreadArgsHelper(callback, 0, -1, id, reason, isDone: isDone).func; |
328 | 331 |
329 /// Creates a new named group of tests. | 332 /// Creates a new named group of tests. |
330 /// | 333 /// |
331 /// Calls to group() or test() within the body of the function passed to this | 334 /// Calls to group() or test() within the body of the function passed to this |
332 /// named group will inherit this group's description. | 335 /// named group will inherit this group's description. |
333 void group(String description, void body()) { | 336 void group(String description, void body()) { |
334 ensureInitialized(); | 337 ensureInitialized(); |
335 _requireNotRunning(); | 338 _requireNotRunning(); |
336 _environment.currentContext = | 339 _environment.currentContext = |
337 new _GroupContext(_environment.currentContext, description); | 340 new _GroupContext(_environment.currentContext, description); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 | 496 |
494 /// Publish results on the page and notify controller. | 497 /// Publish results on the page and notify controller. |
495 void _completeTests() { | 498 void _completeTests() { |
496 if (!_environment.initialized) return; | 499 if (!_environment.initialized) return; |
497 int passed = 0; | 500 int passed = 0; |
498 int failed = 0; | 501 int failed = 0; |
499 int errors = 0; | 502 int errors = 0; |
500 | 503 |
501 for (TestCase t in testCases) { | 504 for (TestCase t in testCases) { |
502 switch (t.result) { | 505 switch (t.result) { |
503 case PASS: passed++; break; | 506 case PASS: |
504 case FAIL: failed++; break; | 507 passed++; |
505 case ERROR: errors++; break; | 508 break; |
| 509 case FAIL: |
| 510 failed++; |
| 511 break; |
| 512 case ERROR: |
| 513 errors++; |
| 514 break; |
506 } | 515 } |
507 } | 516 } |
508 _config.onSummary(passed, failed, errors, testCases, | 517 _config.onSummary( |
509 _environment.uncaughtErrorMessage); | 518 passed, failed, errors, testCases, _environment.uncaughtErrorMessage); |
510 _config.onDone(passed > 0 && failed == 0 && errors == 0 && | 519 _config.onDone(passed > 0 && |
| 520 failed == 0 && |
| 521 errors == 0 && |
511 _environment.uncaughtErrorMessage == null); | 522 _environment.uncaughtErrorMessage == null); |
512 _environment.initialized = false; | 523 _environment.initialized = false; |
513 _environment.currentTestCaseIndex = -1; | 524 _environment.currentTestCaseIndex = -1; |
514 } | 525 } |
515 | 526 |
516 String _fullSpec(String spec) { | 527 String _fullSpec(String spec) { |
517 var group = '${_environment.currentContext.fullName}'; | 528 var group = '${_environment.currentContext.fullName}'; |
518 if (spec == null) return group; | 529 if (spec == null) return group; |
519 return group != '' ? '$group$groupSep$spec' : spec; | 530 return group != '' ? '$group$groupSep$spec' : spec; |
520 } | 531 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 /// | 603 /// |
593 /// This allows for multiple invocations of the unittest library in the same | 604 /// This allows for multiple invocations of the unittest library in the same |
594 /// application instance. | 605 /// application instance. |
595 /// This is useful when, for example, creating a test runner application which | 606 /// This is useful when, for example, creating a test runner application which |
596 /// needs to create a new pristine test environment on each invocation to run | 607 /// needs to create a new pristine test environment on each invocation to run |
597 /// a given set of test. | 608 /// a given set of test. |
598 dynamic withTestEnvironment(callback()) { | 609 dynamic withTestEnvironment(callback()) { |
599 return runZoned(callback, | 610 return runZoned(callback, |
600 zoneValues: {_UNITTEST_ENVIRONMENT: new _TestEnvironment()}); | 611 zoneValues: {_UNITTEST_ENVIRONMENT: new _TestEnvironment()}); |
601 } | 612 } |
OLD | NEW |