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

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

Issue 10545167: Some unit test fixes: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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
« no previous file with comments | « lib/unittest/core_matchers.dart ('k') | tests/isolate/v2_unresolved_ports_negative_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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, specify the relative path to 8 * To import this library, specify the relative path to
9 * lib/unittest/unittest.dart. 9 * lib/unittest/unittest.dart.
10 * 10 *
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 289
290 // TODO(sigmund): make a singleton const field when frog supports passing those 290 // TODO(sigmund): make a singleton const field when frog supports passing those
291 // as default values to named arguments. 291 // as default values to named arguments.
292 final _sentinel = const _Sentinel(); 292 final _sentinel = const _Sentinel();
293 293
294 /** Simulates spread arguments using named arguments. */ 294 /** Simulates spread arguments using named arguments. */
295 // TODO(sigmund): remove this class and simply use a closure with named 295 // TODO(sigmund): remove this class and simply use a closure with named
296 // arguments inside [_expectAsync], once bug 282 is fixed or frog is replaced by 296 // arguments inside [_expectAsync], once bug 282 is fixed or frog is replaced by
297 // dart2js. 297 // dart2js.
298 class _SpreadArgsHelper { 298 class _SpreadArgsHelper {
299 Function callback; 299 Function _callback;
300 int expectedCalls; 300 int _expectedCalls = 0;
301 int calls = 0; 301 int _calls = 0;
302 TestCase testCase; 302 TestCase _testCase;
303 _SpreadArgsHelper(this.callback, this.expectedCalls) { 303 Function _shouldCallBack;
304 Expect.isTrue(_currentTest < _tests.length); 304 Function _isDone;
305 testCase = _tests[_currentTest]; 305
306 testCase.callbacks++; 306 _Init(Function callback, Function shouldCallBack, Function isDone,
Bob Nystrom 2012/06/14 01:00:49 _init
307 [expectedCalls = 0]) {
308 assert(_currentTest < _tests.length);
309 _callback = callback;
310 _shouldCallBack = shouldCallBack;
311 _isDone = isDone;
312 _expectedCalls = expectedCalls;
313 _testCase = _tests[_currentTest];
314 _testCase.callbacks++;
315 }
316
317 _SpreadArgsHelper(callback, shouldCallBack, isDone) {
318 _Init(callback, shouldCallBack, isDone);
319 }
320
321 _SpreadArgsHelper.fixedCallCount(callback, expectedCalls) {
322 _Init(callback, _checkCallCount, _allCallsDone, expectedCalls);
323 }
324
325 _SpreadArgsHelper.variableCallCount(callback, isDone) {
326 _Init(callback, _always, isDone);
327 }
328
329 _after() {
330 if (_isDone()) {
331 _handleAllCallbacksDone();
332 }
333 }
334
335 _allCallsDone() => _calls == _expectedCalls;
336
337 _always() {
338 // Always run except if the test is done.
339 if (_testCase.isComplete) {
340 _testCase.error(
341 'Callback called after already being marked as done ($_calls)',
342 '');
343 _state = _UNCAUGHT_ERROR;
344 return false;
345 } else {
346 return true;
347 }
307 } 348 }
308 349
309 invoke([arg0 = _sentinel, arg1 = _sentinel, arg2 = _sentinel, 350 invoke([arg0 = _sentinel, arg1 = _sentinel, arg2 = _sentinel,
310 arg3 = _sentinel, arg4 = _sentinel]) { 351 arg3 = _sentinel, arg4 = _sentinel]) {
311 return guardAsync(() { 352 return guardAsync(() {
312 if (!_incrementCall()) { 353 ++_calls;
354 if (!_shouldCallBack()) {
313 return; 355 return;
314 } else if (arg0 == _sentinel) { 356 } else if (arg0 == _sentinel) {
315 return callback(); 357 return _callback();
316 } else if (arg1 == _sentinel) { 358 } else if (arg1 == _sentinel) {
317 return callback(arg0); 359 return _callback(arg0);
318 } else if (arg2 == _sentinel) { 360 } else if (arg2 == _sentinel) {
319 return callback(arg0, arg1); 361 return _callback(arg0, arg1);
320 } else if (arg3 == _sentinel) { 362 } else if (arg3 == _sentinel) {
321 return callback(arg0, arg1, arg2); 363 return _callback(arg0, arg1, arg2);
322 } else if (arg4 == _sentinel) { 364 } else if (arg4 == _sentinel) {
323 return callback(arg0, arg1, arg2, arg3); 365 return _callback(arg0, arg1, arg2, arg3);
324 } else { 366 } else {
325 testCase.error( 367 _testCase.error(
326 'unittest lib does not support callbacks with more than 4 arguments', 368 'unittest lib does not support callbacks with more than 4 arguments',
327 ''); 369 '');
328 _state = _UNCAUGHT_ERROR; 370 _state = _UNCAUGHT_ERROR;
329 } 371 }
330 }, () { if (calls == expectedCalls) callbackDone(); }); 372 },
373 _after);
331 } 374 }
332 375
333 invoke0() { 376 invoke0() {
334 return guardAsync( 377 return guardAsync(
335 () => _incrementCall() ? callback() : null, 378 () { if (_shouldCallBack()) _callback(); },
336 () { if (calls == expectedCalls) callbackDone(); }); 379 _after);
337 } 380 }
338 381
339 invoke1(arg1) { 382 invoke1(arg1) {
340 return guardAsync( 383 return guardAsync(
341 () => _incrementCall() ? callback(arg1) : null, 384 () { if (_shouldCallBack()) _callback(arg1); },
342 () { if (calls == expectedCalls) callbackDone(); }); 385 _after);
343 } 386 }
344 387
345 invoke2(arg1, arg2) { 388 invoke2(arg1, arg2) {
346 return guardAsync( 389 return guardAsync(
347 () => _incrementCall() ? callback(arg1, arg2) : null, 390 () { if (_shouldCallBack()) _callback(arg1, arg2); },
348 () { if (calls == expectedCalls) callbackDone(); }); 391 _after);
349 } 392 }
350 393
351 /** Returns false if we exceded the number of expected calls. */ 394 /** Returns false if we exceded the number of expected calls. */
352 bool _incrementCall() { 395 bool _checkCallCount() {
353 calls++; 396 if (_calls > _expectedCalls) {
354 if (calls > expectedCalls) { 397 _testCase.error(
355 testCase.error( 398 'Callback called more times than expected '
356 'Callback called more times than expected ($calls > $expectedCalls)', 399 '($_calls > $_expectedCalls)',
357 ''); 400 '');
358 _state = _UNCAUGHT_ERROR; 401 _state = _UNCAUGHT_ERROR;
359 return false; 402 return false;
360 } 403 }
361 return true; 404 return true;
362 } 405 }
363 } 406 }
364 407
365 /** 408 /**
366 * Indicate that [callback] is expected to be called a [count] number of times 409 * Indicate that [callback] is expected to be called a [count] number of times
367 * (by default 1). The unittest framework will wait for the callback to run the 410 * (by default 1). The unittest framework will wait for the callback to run the
368 * specified [count] times before it continues with the following test. Using 411 * specified [count] times before it continues with the following test. Using
369 * [_expectAsync] will also ensure that errors that occur within [callback] are 412 * [_expectAsync] will also ensure that errors that occur within [callback] are
370 * tracked and reported. [callback] should take between 0 and 4 positional 413 * tracked and reported. [callback] should take between 0 and 4 positional
371 * arguments (named arguments are not supported here). 414 * arguments (named arguments are not supported here).
372 */ 415 */
373 Function _expectAsync(Function callback, [int count = 1]) { 416 Function _expectAsync(Function callback, [int count = 1]) {
374 return new _SpreadArgsHelper(callback, count).invoke; 417 return new _SpreadArgsHelper.fixedCallCount(callback, count).invoke;
375 } 418 }
376 419
377 /** 420 /**
378 * Indicate that [callback] is expected to be called a [count] number of times 421 * Indicate that [callback] is expected to be called a [count] number of times
379 * (by default 1). The unittest framework will wait for the callback to run the 422 * (by default 1). The unittest framework will wait for the callback to run the
380 * specified [count] times before it continues with the following test. Using 423 * specified [count] times before it continues with the following test. Using
381 * [expectAsync0] will also ensure that errors that occur within [callback] are 424 * [expectAsync0] will also ensure that errors that occur within [callback] are
382 * tracked and reported. [callback] should take 0 positional arguments (named 425 * tracked and reported. [callback] should take 0 positional arguments (named
383 * arguments are not supported). 426 * arguments are not supported).
384 */ 427 */
385 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 428 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
386 Function expectAsync0(Function callback, [int count = 1]) { 429 Function expectAsync0(Function callback, [int count = 1]) {
387 return new _SpreadArgsHelper(callback, count).invoke0; 430 return new _SpreadArgsHelper.fixedCallCount(callback, count).invoke0;
388 } 431 }
389 432
390 /** Like [expectAsync0] but [callback] should take 1 positional argument. */ 433 /** Like [expectAsync0] but [callback] should take 1 positional argument. */
391 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 434 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
392 Function expectAsync1(Function callback, [int count = 1]) { 435 Function expectAsync1(Function callback, [int count = 1]) {
393 return new _SpreadArgsHelper(callback, count).invoke1; 436 return new _SpreadArgsHelper.fixedCallCount(callback, count).invoke1;
394 } 437 }
395 438
396 /** Like [expectAsync0] but [callback] should take 2 positional arguments. */ 439 /** Like [expectAsync0] but [callback] should take 2 positional arguments. */
397 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 440 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
398 Function expectAsync2(Function callback, [int count = 1]) { 441 Function expectAsync2(Function callback, [int count = 1]) {
399 return new _SpreadArgsHelper(callback, count).invoke2; 442 return new _SpreadArgsHelper.fixedCallCount(callback, count).invoke2;
443 }
444
445 /**
446 * Indicate that [callback] is expected to be called until [isDone] returns
447 * true. The unittest framework checks [isDone] after each callback and only
448 * when it returns true will it continue with the following test. Using
449 * [expectAsyncUntil] will also ensure that errors that occur within
450 * [callback] are tracked and reported. [callback] should take between 0 and
451 * 4 positional arguments (named arguments are not supported).
452 */
453 Function _expectAsyncUntil(Function callback, Function isDone) {
454 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke;
455 }
456
457 /**
458 * Indicate that [callback] is expected to be called until [isDone] returns
459 * true. The unittest framework check [isDone] after each callback and only
460 * when it returns true will it continue with the following test. Using
461 * [expectAsyncUntil0] will also ensure that errors that occur within
462 * [callback] are tracked and reported. [callback] should take 0 positional
463 * arguments (named arguments are not supported).
464 */
465 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
466 Function expectAsyncUntil0(Function callback, Function isDone) {
467 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke0;
468 }
469
470 /**
471 * Like [expectAsyncUntil0] but [callback] should take 1 positional argument.
472 */
473 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
474 Function expectAsyncUntil1(Function callback, Function isDone) {
475 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke1;
476 }
477
478 /**
479 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments.
480 */
481 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
482 Function expectAsyncUntil2(Function callback, Function isDone) {
483 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke2;
400 } 484 }
401 485
402 /** 486 /**
403 * Creates a new named group of tests. Calls to group() or test() within the 487 * Creates a new named group of tests. Calls to group() or test() within the
404 * body of the function passed to this will inherit this group's description. 488 * body of the function passed to this will inherit this group's description.
405 */ 489 */
406 void group(String description, void body()) { 490 void group(String description, void body()) {
407 ensureInitialized(); 491 ensureInitialized();
408 492
409 // Concatenate the new group. 493 // Concatenate the new group.
410 final oldGroup = _currentGroup; 494 final oldGroup = _currentGroup;
411 if (_currentGroup != '') { 495 if (_currentGroup != '') {
412 // Add a space. 496 // Add a space.
413 _currentGroup = '$_currentGroup $description'; 497 _currentGroup = '$_currentGroup $description';
414 } else { 498 } else {
415 // The first group. 499 // The first group.
416 _currentGroup = description; 500 _currentGroup = description;
417 } 501 }
418 502
419 try { 503 try {
420 body(); 504 body();
421 } finally { 505 } finally {
422 // Now that the group is over, restore the previous one. 506 // Now that the group is over, restore the previous one.
423 _currentGroup = oldGroup; 507 _currentGroup = oldGroup;
424 } 508 }
425 } 509 }
426 510
427 /** Called by subclasses to indicate that an asynchronous test completed. */ 511 /** Called by subclasses to indicate that an asynchronous test completed. */
428 void callbackDone() { 512 void _handleAllCallbacksDone() {
429 // TODO (gram): we defer this to give the nextBatch recursive 513 // TODO (gram): we defer this to give the nextBatch recursive
430 // stack a chance to unwind. This is a temporary hack but 514 // stack a chance to unwind. This is a temporary hack but
431 // really a bunch of code here needs to be fixed. We have a 515 // really a bunch of code here needs to be fixed. We have a
432 // single array that is being iterated through by nextBatch(), 516 // single array that is being iterated through by nextBatch(),
433 // which is recursively invoked in the case of async tests that 517 // which is recursively invoked in the case of async tests that
434 // run synchronously. Bad things can then happen. 518 // run synchronously. Bad things can then happen.
435 _defer(() { 519 _defer(() {
436 _callbacksCalled++; 520 _callbacksCalled++;
437 if (_currentTest < _tests.length) { 521 if (_currentTest < _tests.length) {
438 final testCase = _tests[_currentTest]; 522 final testCase = _tests[_currentTest];
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 * Runs a batch of tests, yielding whenever an asynchronous test starts 618 * Runs a batch of tests, yielding whenever an asynchronous test starts
535 * running. Tests will resume executing when such asynchronous test calls 619 * running. Tests will resume executing when such asynchronous test calls
536 * [done] or if it fails with an exception. 620 * [done] or if it fails with an exception.
537 */ 621 */
538 _nextBatch() { 622 _nextBatch() {
539 while (_currentTest < _tests.length) { 623 while (_currentTest < _tests.length) {
540 final testCase = _tests[_currentTest]; 624 final testCase = _tests[_currentTest];
541 guardAsync(() { 625 guardAsync(() {
542 _callbacksCalled = 0; 626 _callbacksCalled = 0;
543 _state = _RUNNING_TEST; 627 _state = _RUNNING_TEST;
544
545 testCase.test(); 628 testCase.test();
546 629
547 if (_state != _UNCAUGHT_ERROR) { 630 if (_state != _UNCAUGHT_ERROR) {
548 if (testCase.callbacks == _callbacksCalled) { 631 if (testCase.callbacks == _callbacksCalled) {
549 testCase.pass(); 632 testCase.pass();
550 } 633 }
551 } 634 }
552 }); 635 });
553 636
554 if (!testCase.isComplete && testCase.callbacks > 0) return; 637 if (!testCase.isComplete && testCase.callbacks > 0) return;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 throw new ExpectException(message); 671 throw new ExpectException(message);
589 } 672 }
590 673
591 /** 674 /**
592 * Lazily initializes the test library if not already initialized. 675 * Lazily initializes the test library if not already initialized.
593 */ 676 */
594 ensureInitialized() { 677 ensureInitialized() {
595 if (_state != _UNINITIALIZED) return; 678 if (_state != _UNINITIALIZED) return;
596 679
597 _tests = <TestCase>[]; 680 _tests = <TestCase>[];
681 _uncaughtErrorMessage = null;
682 _currentTest = 0;
598 _currentGroup = ''; 683 _currentGroup = '';
599 _state = _READY; 684 _state = _READY;
600 _testRunner = _nextBatch; 685 _testRunner = _nextBatch;
601 686
602 if (_config == null) { 687 if (_config == null) {
603 _config = new Configuration(); 688 _config = new Configuration();
604 } 689 }
605 _config.onInit(); 690 _config.onInit();
606 691
607 // Immediately queue the suite up. It will run after a timeout (i.e. after 692 // Immediately queue the suite up. It will run after a timeout (i.e. after
608 // main() has returned). 693 // main() has returned).
609 _defer(_runTests); 694 _defer(_runTests);
610 } 695 }
611 696
612 /** Signature for a test function. */ 697 /** Signature for a test function. */
613 typedef void TestFunction(); 698 typedef void TestFunction();
OLDNEW
« no previous file with comments | « lib/unittest/core_matchers.dart ('k') | tests/isolate/v2_unresolved_ports_negative_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698