| 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 * A library for writing dart unit tests. | 6 * A library for writing dart unit tests. |
| 7 * | 7 * |
| 8 * To import this library, install the | 8 * To import this library, install the |
| 9 * [unittest package](http://pub.dartlang.org/packages/unittest) via the pub | 9 * [unittest package](http://pub.dartlang.org/packages/unittest) via the pub |
| 10 * package manager. See the [Getting Started](http://pub.dartlang.org/doc) | 10 * package manager. See the [Getting Started](http://pub.dartlang.org/doc) |
| 11 * guide for more details. | 11 * guide for more details. |
| 12 * | 12 * |
| 13 * ##Concepts## | 13 * ##Concepts## |
| 14 * | 14 * |
| 15 * * __Tests__: Tests are specified via the top-level function [test], they can
be | 15 * * __Tests__: Tests are specified via the top-level function [test], they can
be |
| 16 * organized together using [group]. | 16 * organized together using [group]. |
| 17 * * __Checks__: Test expectations can be specified via [expect] | 17 * * __Checks__: Test expectations can be specified via [expect] |
| 18 * * __Matchers__: [expect] assertions are written declaratively using the | 18 * * __Matchers__: [expect] assertions are written declaratively using the |
| 19 * [Matcher] class. | 19 * [Matcher] class. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 */ | 245 */ |
| 246 Map testState = {}; | 246 Map testState = {}; |
| 247 | 247 |
| 248 /** | 248 /** |
| 249 * Creates a new test case with the given description and body. The | 249 * Creates a new test case with the given description and body. The |
| 250 * description will include the descriptions of any surrounding group() | 250 * description will include the descriptions of any surrounding group() |
| 251 * calls. | 251 * calls. |
| 252 */ | 252 */ |
| 253 void test(String spec, TestFunction body) { | 253 void test(String spec, TestFunction body) { |
| 254 ensureInitialized(); | 254 ensureInitialized(); |
| 255 _tests.add(new TestCase(_tests.length + 1, _fullSpec(spec), body, 0)); | 255 _tests.add(new TestCase._internal(_tests.length + 1, _fullSpec(spec), body)); |
| 256 } | 256 } |
| 257 | 257 |
| 258 /** | 258 /** |
| 259 * 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 |
| 260 * description will include the descriptions of any surrounding group() | 260 * description will include the descriptions of any surrounding group() |
| 261 * calls. | 261 * calls. |
| 262 * | 262 * |
| 263 * "solo_" means that this will be the only test that is run. All other tests | 263 * "solo_" means that this will be the only test that is run. All other tests |
| 264 * will be skipped. This is a convenience function to let you quickly isolate | 264 * will be skipped. This is a convenience function to let you quickly isolate |
| 265 * a single test by adding "solo_" before it to temporarily disable all other | 265 * a single test by adding "solo_" before it to temporarily disable all other |
| 266 * tests. | 266 * tests. |
| 267 */ | 267 */ |
| 268 void solo_test(String spec, TestFunction body) { | 268 void solo_test(String spec, TestFunction body) { |
| 269 // TODO(rnystrom): Support multiple solos. If more than one test is solo-ed, | 269 // TODO(rnystrom): Support multiple solos. If more than one test is solo-ed, |
| 270 // all of the solo-ed tests and none of the non-solo-ed ones should run. | 270 // all of the solo-ed tests and none of the non-solo-ed ones should run. |
| 271 if (_soloTest != null) { | 271 if (_soloTest != null) { |
| 272 throw new Exception('Only one test can be soloed right now.'); | 272 throw new Exception('Only one test can be soloed right now.'); |
| 273 } | 273 } |
| 274 | 274 |
| 275 ensureInitialized(); | 275 ensureInitialized(); |
| 276 | 276 |
| 277 _soloTest = new TestCase(_tests.length + 1, _fullSpec(spec), body, 0); | 277 _soloTest = new TestCase._internal(_tests.length + 1, _fullSpec(spec), body); |
| 278 _tests.add(_soloTest); | 278 _tests.add(_soloTest); |
| 279 } | 279 } |
| 280 | 280 |
| 281 /** Sentinel value for [_SpreadArgsHelper]. */ | 281 /** Sentinel value for [_SpreadArgsHelper]. */ |
| 282 class _Sentinel { | 282 class _Sentinel { |
| 283 const _Sentinel(); | 283 const _Sentinel(); |
| 284 } | 284 } |
| 285 | 285 |
| 286 /** Simulates spread arguments using named arguments. */ | 286 /** Simulates spread arguments using named arguments. */ |
| 287 // TODO(sigmund): remove this class and simply use a closure with named | 287 // TODO(sigmund): remove this class and simply use a closure with named |
| (...skipping 25 matching lines...) Expand all Loading... |
| 313 _currentTest < _tests.length && | 313 _currentTest < _tests.length && |
| 314 _tests[_currentTest] != null)) { | 314 _tests[_currentTest] != null)) { |
| 315 print("No valid test, did you forget to run your test inside a call " | 315 print("No valid test, did you forget to run your test inside a call " |
| 316 "to test()?"); | 316 "to test()?"); |
| 317 } | 317 } |
| 318 assert(_currentTest >= 0 && | 318 assert(_currentTest >= 0 && |
| 319 _currentTest < _tests.length && | 319 _currentTest < _tests.length && |
| 320 _tests[_currentTest] != null); | 320 _tests[_currentTest] != null); |
| 321 testCase = _tests[_currentTest]; | 321 testCase = _tests[_currentTest]; |
| 322 if (isDone != null || minExpected > 0) { | 322 if (isDone != null || minExpected > 0) { |
| 323 testCase.callbackFunctionsOutstanding++; | 323 testCase._callbackFunctionsOutstanding++; |
| 324 complete = false; | 324 complete = false; |
| 325 } else { | 325 } else { |
| 326 complete = true; | 326 complete = true; |
| 327 } | 327 } |
| 328 } | 328 } |
| 329 | 329 |
| 330 static _makeCallbackId(String id, Function callback) { | 330 static _makeCallbackId(String id, Function callback) { |
| 331 // Try to create a reasonable id. | 331 // Try to create a reasonable id. |
| 332 if (id != null) { | 332 if (id != null) { |
| 333 return "$id "; | 333 return "$id "; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 } | 369 } |
| 370 | 370 |
| 371 after() { | 371 after() { |
| 372 if (!complete) { | 372 if (!complete) { |
| 373 if (minExpectedCalls > 0 && actualCalls < minExpectedCalls) return; | 373 if (minExpectedCalls > 0 && actualCalls < minExpectedCalls) return; |
| 374 if (isDone != null && !isDone()) return; | 374 if (isDone != null && !isDone()) return; |
| 375 | 375 |
| 376 // Mark this callback as complete and remove it from the testcase | 376 // Mark this callback as complete and remove it from the testcase |
| 377 // oustanding callback count; if that hits zero the testcase is done. | 377 // oustanding callback count; if that hits zero the testcase is done. |
| 378 complete = true; | 378 complete = true; |
| 379 testCase.markCallbackComplete(); | 379 testCase._markCallbackComplete(); |
| 380 } | 380 } |
| 381 } | 381 } |
| 382 | 382 |
| 383 invoke([arg0 = sentinel, arg1 = sentinel, arg2 = sentinel, | 383 invoke([arg0 = sentinel, arg1 = sentinel, arg2 = sentinel, |
| 384 arg3 = sentinel, arg4 = sentinel]) { | 384 arg3 = sentinel, arg4 = sentinel]) { |
| 385 return _guardAsync(() { | 385 return _guardAsync(() { |
| 386 if (!shouldCallBack()) { | 386 if (!shouldCallBack()) { |
| 387 return; | 387 return; |
| 388 } else if (arg0 == sentinel) { | 388 } else if (arg0 == sentinel) { |
| 389 return callback(); | 389 return callback(); |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 * running. Tests will resume executing when such asynchronous test calls | 755 * running. Tests will resume executing when such asynchronous test calls |
| 756 * [done] or if it fails with an exception. | 756 * [done] or if it fails with an exception. |
| 757 */ | 757 */ |
| 758 _nextBatch() { | 758 _nextBatch() { |
| 759 while (true) { | 759 while (true) { |
| 760 if (_currentTest >= _tests.length) { | 760 if (_currentTest >= _tests.length) { |
| 761 _completeTests(); | 761 _completeTests(); |
| 762 break; | 762 break; |
| 763 } | 763 } |
| 764 final testCase = _tests[_currentTest]; | 764 final testCase = _tests[_currentTest]; |
| 765 var f = _guardAsync(testCase.run, null, _currentTest); | 765 var f = _guardAsync(testCase._run, null, _currentTest); |
| 766 if (f != null) { | 766 if (f != null) { |
| 767 f.whenComplete(() { | 767 f.whenComplete(() { |
| 768 _nextTestCase(); // Schedule the next test. | 768 _nextTestCase(); // Schedule the next test. |
| 769 }); | 769 }); |
| 770 break; | 770 break; |
| 771 } | 771 } |
| 772 _currentTest++; | 772 _currentTest++; |
| 773 } | 773 } |
| 774 } | 774 } |
| 775 | 775 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 } | 851 } |
| 852 | 852 |
| 853 /** Enable a test by ID. */ | 853 /** Enable a test by ID. */ |
| 854 void enableTest(int testId) => _setTestEnabledState(testId, true); | 854 void enableTest(int testId) => _setTestEnabledState(testId, true); |
| 855 | 855 |
| 856 /** Disable a test by ID. */ | 856 /** Disable a test by ID. */ |
| 857 void disableTest(int testId) => _setTestEnabledState(testId, false); | 857 void disableTest(int testId) => _setTestEnabledState(testId, false); |
| 858 | 858 |
| 859 /** Signature for a test function. */ | 859 /** Signature for a test function. */ |
| 860 typedef dynamic TestFunction(); | 860 typedef dynamic TestFunction(); |
| OLD | NEW |