Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(766)

Side by Side Diff: pkg/unittest/lib/unittest.dart

Issue 12452004: pkg/unittest: locking down TestCase (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fixed up dartdoc on TestCase and updated copyright year Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, 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, 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:
11 * dependencies: 11 * dependencies:
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 */ 251 */
252 Map testState = {}; 252 Map testState = {};
253 253
254 /** 254 /**
255 * Creates a new test case with the given description and body. The 255 * Creates a new test case with the given description and body. The
256 * description will include the descriptions of any surrounding group() 256 * description will include the descriptions of any surrounding group()
257 * calls. 257 * calls.
258 */ 258 */
259 void test(String spec, TestFunction body) { 259 void test(String spec, TestFunction body) {
260 ensureInitialized(); 260 ensureInitialized();
261 _tests.add(new TestCase(_tests.length + 1, _fullSpec(spec), body, 0)); 261 _tests.add(new TestCase._internal(_tests.length + 1, _fullSpec(spec), body));
262 } 262 }
263 263
264 /** 264 /**
265 * Creates a new test case with the given description and body. The 265 * Creates a new test case with the given description and body. The
266 * description will include the descriptions of any surrounding group() 266 * description will include the descriptions of any surrounding group()
267 * calls. 267 * calls.
268 * 268 *
269 * "solo_" means that this will be the only test that is run. All other tests 269 * "solo_" means that this will be the only test that is run. All other tests
270 * will be skipped. This is a convenience function to let you quickly isolate 270 * will be skipped. This is a convenience function to let you quickly isolate
271 * a single test by adding "solo_" before it to temporarily disable all other 271 * a single test by adding "solo_" before it to temporarily disable all other
272 * tests. 272 * tests.
273 */ 273 */
274 void solo_test(String spec, TestFunction body) { 274 void solo_test(String spec, TestFunction body) {
275 // TODO(rnystrom): Support multiple solos. If more than one test is solo-ed, 275 // TODO(rnystrom): Support multiple solos. If more than one test is solo-ed,
276 // all of the solo-ed tests and none of the non-solo-ed ones should run. 276 // all of the solo-ed tests and none of the non-solo-ed ones should run.
277 if (_soloTest != null) { 277 if (_soloTest != null) {
278 throw new Exception('Only one test can be soloed right now.'); 278 throw new Exception('Only one test can be soloed right now.');
279 } 279 }
280 280
281 ensureInitialized(); 281 ensureInitialized();
282 282
283 _soloTest = new TestCase(_tests.length + 1, _fullSpec(spec), body, 0); 283 _soloTest = new TestCase._internal(_tests.length + 1, _fullSpec(spec), body);
284 _tests.add(_soloTest); 284 _tests.add(_soloTest);
285 } 285 }
286 286
287 /** Sentinel value for [_SpreadArgsHelper]. */ 287 /** Sentinel value for [_SpreadArgsHelper]. */
288 class _Sentinel { 288 class _Sentinel {
289 const _Sentinel(); 289 const _Sentinel();
290 } 290 }
291 291
292 /** Simulates spread arguments using named arguments. */ 292 /** Simulates spread arguments using named arguments. */
293 // TODO(sigmund): remove this class and simply use a closure with named 293 // TODO(sigmund): remove this class and simply use a closure with named
(...skipping 25 matching lines...) Expand all
319 _currentTest < _tests.length && 319 _currentTest < _tests.length &&
320 _tests[_currentTest] != null)) { 320 _tests[_currentTest] != null)) {
321 print("No valid test, did you forget to run your test inside a call " 321 print("No valid test, did you forget to run your test inside a call "
322 "to test()?"); 322 "to test()?");
323 } 323 }
324 assert(_currentTest >= 0 && 324 assert(_currentTest >= 0 &&
325 _currentTest < _tests.length && 325 _currentTest < _tests.length &&
326 _tests[_currentTest] != null); 326 _tests[_currentTest] != null);
327 testCase = _tests[_currentTest]; 327 testCase = _tests[_currentTest];
328 if (isDone != null || minExpected > 0) { 328 if (isDone != null || minExpected > 0) {
329 testCase.callbackFunctionsOutstanding++; 329 testCase._callbackFunctionsOutstanding++;
330 complete = false; 330 complete = false;
331 } else { 331 } else {
332 complete = true; 332 complete = true;
333 } 333 }
334 } 334 }
335 335
336 static _makeCallbackId(String id, Function callback) { 336 static _makeCallbackId(String id, Function callback) {
337 // Try to create a reasonable id. 337 // Try to create a reasonable id.
338 if (id != null) { 338 if (id != null) {
339 return "$id "; 339 return "$id ";
(...skipping 14 matching lines...) Expand all
354 return ''; 354 return '';
355 } 355 }
356 356
357 shouldCallBack() { 357 shouldCallBack() {
358 ++actualCalls; 358 ++actualCalls;
359 if (testCase.isComplete) { 359 if (testCase.isComplete) {
360 // Don't run if the test is done. We don't throw here as this is not 360 // Don't run if the test is done. We don't throw here as this is not
361 // the current test, but we do mark the old test as having an error 361 // the current test, but we do mark the old test as having an error
362 // if it previously passed. 362 // if it previously passed.
363 if (testCase.result == PASS) { 363 if (testCase.result == PASS) {
364 testCase.error( 364 testCase._error(
365 'Callback ${id}called ($actualCalls) after test case ' 365 'Callback ${id}called ($actualCalls) after test case '
366 '${testCase.description} has already been marked as ' 366 '${testCase.description} has already been marked as '
367 '${testCase.result}.', ''); 367 '${testCase.result}.', '');
368 } 368 }
369 return false; 369 return false;
370 } else if (maxExpectedCalls >= 0 && actualCalls > maxExpectedCalls) { 370 } else if (maxExpectedCalls >= 0 && actualCalls > maxExpectedCalls) {
371 throw new TestFailure('Callback ${id}called more times than expected ' 371 throw new TestFailure('Callback ${id}called more times than expected '
372 '($maxExpectedCalls).'); 372 '($maxExpectedCalls).');
373 } 373 }
374 return true; 374 return true;
375 } 375 }
376 376
377 after() { 377 after() {
378 if (!complete) { 378 if (!complete) {
379 if (minExpectedCalls > 0 && actualCalls < minExpectedCalls) return; 379 if (minExpectedCalls > 0 && actualCalls < minExpectedCalls) return;
380 if (isDone != null && !isDone()) return; 380 if (isDone != null && !isDone()) return;
381 381
382 // Mark this callback as complete and remove it from the testcase 382 // Mark this callback as complete and remove it from the testcase
383 // oustanding callback count; if that hits zero the testcase is done. 383 // oustanding callback count; if that hits zero the testcase is done.
384 complete = true; 384 complete = true;
385 testCase.markCallbackComplete(); 385 testCase._markCallbackComplete();
386 } 386 }
387 } 387 }
388 388
389 invoke([arg0 = sentinel, arg1 = sentinel, arg2 = sentinel, 389 invoke([arg0 = sentinel, arg1 = sentinel, arg2 = sentinel,
390 arg3 = sentinel, arg4 = sentinel]) { 390 arg3 = sentinel, arg4 = sentinel]) {
391 return _guardAsync(() { 391 return _guardAsync(() {
392 if (!shouldCallBack()) { 392 if (!shouldCallBack()) {
393 return; 393 return;
394 } else if (arg0 == sentinel) { 394 } else if (arg0 == sentinel) {
395 return callback(); 395 return callback();
396 } else if (arg1 == sentinel) { 396 } else if (arg1 == sentinel) {
397 return callback(arg0); 397 return callback(arg0);
398 } else if (arg2 == sentinel) { 398 } else if (arg2 == sentinel) {
399 return callback(arg0, arg1); 399 return callback(arg0, arg1);
400 } else if (arg3 == sentinel) { 400 } else if (arg3 == sentinel) {
401 return callback(arg0, arg1, arg2); 401 return callback(arg0, arg1, arg2);
402 } else if (arg4 == sentinel) { 402 } else if (arg4 == sentinel) {
403 return callback(arg0, arg1, arg2, arg3); 403 return callback(arg0, arg1, arg2, arg3);
404 } else { 404 } else {
405 testCase.error( 405 testCase._error(
406 'unittest lib does not support callbacks with more than' 406 'unittest lib does not support callbacks with more than'
407 ' 4 arguments.', 407 ' 4 arguments.',
408 ''); 408 '');
409 } 409 }
410 }, 410 },
411 after, testNum); 411 after, testNum);
412 } 412 }
413 413
414 invoke0() { 414 invoke0() {
415 return _guardAsync( 415 return _guardAsync(
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 }); 648 });
649 } 649 }
650 650
651 /** 651 /**
652 * Utility function that can be used to notify the test framework that an 652 * Utility function that can be used to notify the test framework that an
653 * error was caught outside of this library. 653 * error was caught outside of this library.
654 */ 654 */
655 void _reportTestError(String msg, String trace) { 655 void _reportTestError(String msg, String trace) {
656 if (_currentTest < _tests.length) { 656 if (_currentTest < _tests.length) {
657 final testCase = _tests[_currentTest]; 657 final testCase = _tests[_currentTest];
658 testCase.error(msg, trace); 658 testCase._error(msg, trace);
659 } else { 659 } else {
660 _uncaughtErrorMessage = "$msg: $trace"; 660 _uncaughtErrorMessage = "$msg: $trace";
661 } 661 }
662 } 662 }
663 663
664 /** 664 /**
665 * Runs [callback] at the end of the event loop. Note that we don't wrap 665 * Runs [callback] at the end of the event loop. Note that we don't wrap
666 * the callback in guardAsync; this is for test framework functions which 666 * the callback in guardAsync; this is for test framework functions which
667 * should not be throwing unexpected exceptions that end up failing test 667 * should not be throwing unexpected exceptions that end up failing test
668 * cases! Furthermore, we need the final exception to be thrown but not 668 * cases! Furthermore, we need the final exception to be thrown but not
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 _registerException(_currentTest, e, trace); 743 _registerException(_currentTest, e, trace);
744 } 744 }
745 745
746 /** 746 /**
747 * Registers that an exception was caught for the current test. 747 * Registers that an exception was caught for the current test.
748 */ 748 */
749 _registerException(testNum, e, [trace]) { 749 _registerException(testNum, e, [trace]) {
750 trace = trace == null ? '' : trace.toString(); 750 trace = trace == null ? '' : trace.toString();
751 String message = (e is TestFailure) ? e.message : 'Caught $e'; 751 String message = (e is TestFailure) ? e.message : 'Caught $e';
752 if (_tests[testNum].result == null) { 752 if (_tests[testNum].result == null) {
753 _tests[testNum].fail(message, trace); 753 _tests[testNum]._fail(message, trace);
754 } else { 754 } else {
755 _tests[testNum].error(message, trace); 755 _tests[testNum]._error(message, trace);
756 } 756 }
757 } 757 }
758 758
759 /** 759 /**
760 * Runs a batch of tests, yielding whenever an asynchronous test starts 760 * Runs a batch of tests, yielding whenever an asynchronous test starts
761 * running. Tests will resume executing when such asynchronous test calls 761 * running. Tests will resume executing when such asynchronous test calls
762 * [done] or if it fails with an exception. 762 * [done] or if it fails with an exception.
763 */ 763 */
764 _nextBatch() { 764 _nextBatch() {
765 while (true) { 765 while (true) {
766 if (_currentTest >= _tests.length) { 766 if (_currentTest >= _tests.length) {
767 _completeTests(); 767 _completeTests();
768 break; 768 break;
769 } 769 }
770 final testCase = _tests[_currentTest]; 770 final testCase = _tests[_currentTest];
771 var f = _guardAsync(testCase.run, null, _currentTest); 771 var f = _guardAsync(testCase._run, null, _currentTest);
772 if (f != null) { 772 if (f != null) {
773 f.whenComplete(() { 773 f.whenComplete(() {
774 _nextTestCase(); // Schedule the next test. 774 _nextTestCase(); // Schedule the next test.
775 }); 775 });
776 break; 776 break;
777 } 777 }
778 _currentTest++; 778 _currentTest++;
779 } 779 }
780 } 780 }
781 781
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 _soloTest = _tests[i]; 838 _soloTest = _tests[i];
839 break; 839 break;
840 } 840 }
841 } 841 }
842 } 842 }
843 843
844 /** Enable/disable a test by ID. */ 844 /** Enable/disable a test by ID. */
845 void _setTestEnabledState(int testId, bool state) { 845 void _setTestEnabledState(int testId, bool state) {
846 // Try fast path first. 846 // Try fast path first.
847 if (_tests.length > testId && _tests[testId].id == testId) { 847 if (_tests.length > testId && _tests[testId].id == testId) {
848 _tests[testId].enabled = state; 848 _tests[testId]._enabled = state;
849 } else { 849 } else {
850 for (var i = 0; i < _tests.length; i++) { 850 for (var i = 0; i < _tests.length; i++) {
851 if (_tests[i].id == testId) { 851 if (_tests[i].id == testId) {
852 _tests[i].enabled = state; 852 _tests[i]._enabled = state;
853 break; 853 break;
854 } 854 }
855 } 855 }
856 } 856 }
857 } 857 }
858 858
859 /** Enable a test by ID. */ 859 /** Enable a test by ID. */
860 void enableTest(int testId) => _setTestEnabledState(testId, true); 860 void enableTest(int testId) => _setTestEnabledState(testId, true);
861 861
862 /** Disable a test by ID. */ 862 /** Disable a test by ID. */
863 void disableTest(int testId) => _setTestEnabledState(testId, false); 863 void disableTest(int testId) => _setTestEnabledState(testId, false);
864 864
865 /** Signature for a test function. */ 865 /** Signature for a test function. */
866 typedef dynamic TestFunction(); 866 typedef dynamic TestFunction();
OLDNEW
« pkg/unittest/lib/src/test_case.dart ('K') | « pkg/unittest/lib/src/test_case.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698