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

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

Issue 12366004: When we have excess callbacks, throw instead of calling error() so that we (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: 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
« no previous file with comments | « pkg/unittest/lib/src/test_case.dart ('k') | pkg/unittest/test/unittest_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, 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:
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 Function _testRunner; 211 Function _testRunner;
212 212
213 /** Setup function called before each test in a group */ 213 /** Setup function called before each test in a group */
214 Function _testSetup; 214 Function _testSetup;
215 215
216 /** Teardown function called after each test in a group */ 216 /** Teardown function called after each test in a group */
217 Function _testTeardown; 217 Function _testTeardown;
218 218
219 /** Current test being executed. */ 219 /** Current test being executed. */
220 int _currentTest = 0; 220 int _currentTest = 0;
221 TestCase _currentTestCase;
222
223 TestCase get currentTestCase =>
224 (_currentTest >= 0 && _currentTest < _tests.length)
225 ? _tests[_currentTest]
226 : null;
221 227
222 /** Whether the framework is in an initialized state. */ 228 /** Whether the framework is in an initialized state. */
223 bool _initialized = false; 229 bool _initialized = false;
224 230
225 String _uncaughtErrorMessage = null; 231 String _uncaughtErrorMessage = null;
226 232
227 /** Test case result strings. */ 233 /** Test case result strings. */
228 // TODO(gram) we should change these constants to use a different string 234 // TODO(gram) we should change these constants to use a different string
229 // (so that writing 'FAIL' in the middle of a test doesn't 235 // (so that writing 'FAIL' in the middle of a test doesn't
230 // imply that the test fails). We can't do it without also changing 236 // imply that the test fails). We can't do it without also changing
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 286
281 /** Sentinel value for [_SpreadArgsHelper]. */ 287 /** Sentinel value for [_SpreadArgsHelper]. */
282 class _Sentinel { 288 class _Sentinel {
283 const _Sentinel(); 289 const _Sentinel();
284 } 290 }
285 291
286 /** Simulates spread arguments using named arguments. */ 292 /** Simulates spread arguments using named arguments. */
287 // 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
288 // arguments (if still applicable). 294 // arguments (if still applicable).
289 class _SpreadArgsHelper { 295 class _SpreadArgsHelper {
290 Function _callback; 296 final Function callback;
291 int _expectedCalls; 297 final int minExpectedCalls;
292 int _actualCalls = 0; 298 final int maxExpectedCalls;
293 int _testNum; 299 final Function isDone;
294 TestCase _testCase; 300 final int testNum;
295 Function _shouldCallBack; 301 final String id;
296 Function _isDone; 302 int actualCalls = 0;
297 String _id; 303 TestCase testCase;
298 static const _sentinel = const _Sentinel(); 304 bool complete;
305 static const sentinel = const _Sentinel();
299 306
300 _init(Function callback, Function shouldCallBack, Function isDone, 307 _SpreadArgsHelper(Function callback, int minExpected, int maxExpected,
301 [expectedCalls = 0]) { 308 Function isDone, String id)
309 : this.callback = callback,
310 minExpectedCalls = minExpected,
311 maxExpectedCalls = (maxExpected == 0 && minExpected > 0)
312 ? minExpected
313 : maxExpected,
314 this.isDone = isDone,
315 testNum = _currentTest,
316 this.id = _makeCallbackId(id, callback) {
302 ensureInitialized(); 317 ensureInitialized();
303 if (!(_currentTest >= 0 && 318 if (!(_currentTest >= 0 &&
304 _currentTest < _tests.length && 319 _currentTest < _tests.length &&
305 _tests[_currentTest] != null)) { 320 _tests[_currentTest] != null)) {
306 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 "
307 "to test()?"); 322 "to test()?");
308 } 323 }
309 assert(_currentTest >= 0 && 324 assert(_currentTest >= 0 &&
310 _currentTest < _tests.length && 325 _currentTest < _tests.length &&
311 _tests[_currentTest] != null); 326 _tests[_currentTest] != null);
312 _callback = callback; 327 testCase = _tests[_currentTest];
313 _shouldCallBack = shouldCallBack; 328 if (isDone != null || minExpected > 0) {
314 _isDone = isDone; 329 testCase.callbackFunctionsOutstanding++;
315 _expectedCalls = expectedCalls; 330 complete = false;
316 _testNum = _currentTest; 331 } else {
317 _testCase = _tests[_currentTest]; 332 complete = true;
318 if (expectedCalls > 0) {
319 _testCase.callbackFunctionsOutstanding++;
320 } 333 }
321 _id = ''; 334 }
322 // If the callback is not an anonymous closure, try to get the 335
323 // name. 336 static _makeCallbackId(String id, Function callback) {
324 var fname = callback.toString(); 337 // Try to create a reasonable id.
325 var prefix = "Function '"; 338 if (id != null) {
326 var pos = fname.indexOf(prefix); 339 return "$id ";
327 if (pos > 0) { 340 } else {
328 pos += prefix.length; 341 // If the callback is not an anonymous closure, try to get the
329 var epos = fname.indexOf("'", pos); 342 // name.
330 if (epos > 0) { 343 var fname = callback.toString();
331 _id = "${fname.substring(pos, epos)} "; 344 var prefix = "Function '";
345 var pos = fname.indexOf(prefix);
346 if (pos > 0) {
347 pos += prefix.length;
348 var epos = fname.indexOf("'", pos);
349 if (epos > 0) {
350 return "${fname.substring(pos, epos)} ";
351 }
352 }
353 }
354 return '';
355 }
356
357 shouldCallBack() {
358 ++actualCalls;
359 if (testCase.isComplete) {
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
362 // if it previously passed.
363 if (testCase.result == PASS) {
364 testCase.error(
365 'Callback ${id}called after test case ${testCase.description} '
366 'has already been marked as done.', '');
367 }
368 return false;
369 } else if (maxExpectedCalls >= 0 && actualCalls > maxExpectedCalls) {
370 throw new TestFailure('Callback ${id}called more times than expected '
371 '($maxExpectedCalls).');
372 }
373 return true;
374 }
375
376 after() {
377 if (!complete) {
378 if (minExpectedCalls > 0 && actualCalls < minExpectedCalls) return;
379 if (isDone != null && !isDone()) return;
380
381 // Mark this callback as complete and remove it from the testcase
382 // oustanding callback count; if that hits zero the testcase is done.
383 complete = true;
384 if (--testCase.callbackFunctionsOutstanding == 0 &&
385 !testCase.isComplete) {
386 testCase.pass();
332 } 387 }
333 } 388 }
334 } 389 }
335 390
336 _SpreadArgsHelper(callback, shouldCallBack, isDone) { 391 invoke([arg0 = sentinel, arg1 = sentinel, arg2 = sentinel,
337 _init(callback, shouldCallBack, isDone); 392 arg3 = sentinel, arg4 = sentinel]) {
338 }
339
340 _SpreadArgsHelper.fixedCallCount(callback, expectedCalls, id) {
341 _init(callback, _checkCallCount, _allCallsDone, expectedCalls);
342 if (id != null) {
343 _id = "$id ";
344 }
345 }
346
347 _SpreadArgsHelper.variableCallCount(callback, isDone) {
348 _init(callback, _always, isDone, 1);
349 }
350
351 _SpreadArgsHelper.optionalCalls(callback) {
352 _init(callback, _always, () => false, 0);
353 }
354
355 _after() {
356 if (_isDone()) {
357 _handleCallbackFunctionComplete(_testNum, _id);
358 }
359 }
360
361 _allCallsDone() => _actualCalls == _expectedCalls;
362
363 _always() {
364 // Always run except if the test is done.
365 if (_testCase.isComplete) {
366 _testCase.error(
367 'Callback ${_id}called after already being marked '
368 'as done ($_actualCalls).',
369 '');
370 return false;
371 } else {
372 return true;
373 }
374 }
375
376 invoke([arg0 = _sentinel, arg1 = _sentinel, arg2 = _sentinel,
377 arg3 = _sentinel, arg4 = _sentinel]) {
378 return guardAsync(() { 393 return guardAsync(() {
379 ++_actualCalls; 394 if (!shouldCallBack()) {
380 if (!_shouldCallBack()) {
381 return; 395 return;
382 } else if (arg0 == _sentinel) { 396 } else if (arg0 == sentinel) {
383 return _callback(); 397 return callback();
384 } else if (arg1 == _sentinel) { 398 } else if (arg1 == sentinel) {
385 return _callback(arg0); 399 return callback(arg0);
386 } else if (arg2 == _sentinel) { 400 } else if (arg2 == sentinel) {
387 return _callback(arg0, arg1); 401 return callback(arg0, arg1);
388 } else if (arg3 == _sentinel) { 402 } else if (arg3 == sentinel) {
389 return _callback(arg0, arg1, arg2); 403 return callback(arg0, arg1, arg2);
390 } else if (arg4 == _sentinel) { 404 } else if (arg4 == sentinel) {
391 return _callback(arg0, arg1, arg2, arg3); 405 return callback(arg0, arg1, arg2, arg3);
392 } else { 406 } else {
393 _testCase.error( 407 testCase.error(
394 'unittest lib does not support callbacks with more than' 408 'unittest lib does not support callbacks with more than'
395 ' 4 arguments.', 409 ' 4 arguments.',
396 ''); 410 '');
397 } 411 }
398 }, 412 },
399 _after, _testNum); 413 after, testNum);
400 } 414 }
401 415
402 invoke0() { 416 invoke0() {
403 return guardAsync( 417 return guardAsync(
404 () { 418 () {
405 ++_actualCalls; 419 if (shouldCallBack()) {
406 if (_shouldCallBack()) { 420 return callback();
407 return _callback();
408 } 421 }
409 }, 422 },
410 _after, _testNum); 423 after, testNum);
411 } 424 }
412 425
413 invoke1(arg1) { 426 invoke1(arg1) {
414 return guardAsync( 427 return guardAsync(
415 () { 428 () {
416 ++_actualCalls; 429 if (shouldCallBack()) {
417 if (_shouldCallBack()) { 430 return callback(arg1);
418 return _callback(arg1);
419 } 431 }
420 }, 432 },
421 _after, _testNum); 433 after, testNum);
422 } 434 }
423 435
424 invoke2(arg1, arg2) { 436 invoke2(arg1, arg2) {
425 return guardAsync( 437 return guardAsync(
426 () { 438 () {
427 ++_actualCalls; 439 if (shouldCallBack()) {
428 if (_shouldCallBack()) { 440 return callback(arg1, arg2);
429 return _callback(arg1, arg2);
430 } 441 }
431 }, 442 },
432 _after, _testNum); 443 after, testNum);
433 }
434
435 /** Returns false if we exceded the number of expected calls. */
436 bool _checkCallCount() {
437 if (_actualCalls > _expectedCalls) {
438 _testCase.error('Callback ${_id}called more times than expected '
439 '($_actualCalls > $_expectedCalls).', '');
440 return false;
441 }
442 return true;
443 } 444 }
444 } 445 }
445 446
446 /** 447 /**
447 * Indicate that [callback] is expected to be called a [count] number of times 448 * Indicate that [callback] is expected to be called a [count] number of times
448 * (by default 1). The unittest framework will wait for the callback to run the 449 * (by default 1). The unittest framework will wait for the callback to run the
449 * specified [count] times before it continues with the following test. Using 450 * specified [count] times before it continues with the following test. Using
450 * [_expectAsync] will also ensure that errors that occur within [callback] are 451 * [_expectAsync] will also ensure that errors that occur within [callback] are
451 * tracked and reported. [callback] should take between 0 and 4 positional 452 * tracked and reported. [callback] should take between 0 and 4 positional
452 * arguments (named arguments are not supported here). [id] can be used 453 * arguments (named arguments are not supported here). [id] can be used
453 * to provide more descriptive error messages if the callback is called more 454 * to provide more descriptive error messages if the callback is called more
454 * often than expected. 455 * often than expected.
455 */ 456 */
456 Function _expectAsync(Function callback, {int count: 1, String id}) { 457 Function _expectAsync(Function callback,
457 return new _SpreadArgsHelper. 458 {int count: 1, int max: 0, String id}) {
458 fixedCallCount(callback, count, id).invoke; 459 return new _SpreadArgsHelper(callback, count, max, null, id).invoke;
459 } 460 }
460 461
461 /** 462 /**
462 * Indicate that [callback] is expected to be called a [count] number of times 463 * Indicate that [callback] is expected to be called a [count] number of times
463 * (by default 1). The unittest framework will wait for the callback to run the 464 * (by default 1). The unittest framework will wait for the callback to run the
464 * specified [count] times before it continues with the following test. Using 465 * specified [count] times before it continues with the following test. Using
465 * [expectAsync0] will also ensure that errors that occur within [callback] are 466 * [expectAsync0] will also ensure that errors that occur within [callback] are
466 * tracked and reported. [callback] should take 0 positional arguments (named 467 * tracked and reported. [callback] should take 0 positional arguments (named
467 * arguments are not supported). [id] can be used to provide more 468 * arguments are not supported). [id] can be used to provide more
468 * descriptive error messages if the callback is called more often than 469 * descriptive error messages if the callback is called more often than
469 * expected. 470 * expected. [max] can be used to specify an upper bound on the number of
471 * calls; if this is exceeded the test will fail (or be marked as in error if
472 * it was already complete). A value of 0 for [max] (the default) will set
473 * the upper bound to the same value as [count]; i.e. the callback should be
474 * called exactly [count] times. A value of -1 for [max] will mean no upper
475 * bound.
470 */ 476 */
471 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 477 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
472 Function expectAsync0(Function callback, {int count: 1, String id}) { 478 Function expectAsync0(Function callback,
473 return new _SpreadArgsHelper. 479 {int count: 1, int max: 0, String id}) {
474 fixedCallCount(callback, count, id).invoke0; 480 return new _SpreadArgsHelper(callback, count, max, null, id).invoke0;
475 } 481 }
476 482
477 /** Like [expectAsync0] but [callback] should take 1 positional argument. */ 483 /** Like [expectAsync0] but [callback] should take 1 positional argument. */
478 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 484 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
479 Function expectAsync1(Function callback, {int count: 1, String id}) { 485 Function expectAsync1(Function callback,
480 return new _SpreadArgsHelper. 486 {int count: 1, int max: 0, String id}) {
481 fixedCallCount(callback, count, id).invoke1; 487 return new _SpreadArgsHelper(callback, count, max, null, id).invoke1;
482 } 488 }
483 489
484 /** Like [expectAsync0] but [callback] should take 2 positional arguments. */ 490 /** Like [expectAsync0] but [callback] should take 2 positional arguments. */
485 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 491 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
486 Function expectAsync2(Function callback, {int count: 1, String id}) { 492 Function expectAsync2(Function callback,
487 return new _SpreadArgsHelper. 493 {int count: 1, int max: 0, String id}) {
488 fixedCallCount(callback, count, id).invoke2; 494 return new _SpreadArgsHelper(callback, count, max, null, id).invoke2;
489 } 495 }
490 496
491 /** 497 /**
492 * Indicate that [callback] is expected to be called until [isDone] returns 498 * Indicate that [callback] is expected to be called until [isDone] returns
493 * true. The unittest framework checks [isDone] after each callback and only 499 * true. The unittest framework checks [isDone] after each callback and only
494 * when it returns true will it continue with the following test. Using 500 * when it returns true will it continue with the following test. Using
495 * [expectAsyncUntil] will also ensure that errors that occur within 501 * [expectAsyncUntil] will also ensure that errors that occur within
496 * [callback] are tracked and reported. [callback] should take between 0 and 502 * [callback] are tracked and reported. [callback] should take between 0 and
497 * 4 positional arguments (named arguments are not supported). 503 * 4 positional arguments (named arguments are not supported). [id] can be
504 * used to identify the callback in error messages (for example if it is called
505 * after the test case is complete).
498 */ 506 */
499 Function _expectAsyncUntil(Function callback, Function isDone) { 507 Function _expectAsyncUntil(Function callback, Function isDone, {String id}) {
500 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke; 508 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke;
501 } 509 }
502 510
503 /** 511 /**
504 * Indicate that [callback] is expected to be called until [isDone] returns 512 * Indicate that [callback] is expected to be called until [isDone] returns
505 * true. The unittest framework check [isDone] after each callback and only 513 * true. The unittest framework check [isDone] after each callback and only
506 * when it returns true will it continue with the following test. Using 514 * when it returns true will it continue with the following test. Using
507 * [expectAsyncUntil0] will also ensure that errors that occur within 515 * [expectAsyncUntil0] will also ensure that errors that occur within
508 * [callback] are tracked and reported. [callback] should take 0 positional 516 * [callback] are tracked and reported. [callback] should take 0 positional
509 * arguments (named arguments are not supported). 517 * arguments (named arguments are not supported). [id] can be used to
518 * identify the callback in error messages (for example if it is called
519 * after the test case is complete).
510 */ 520 */
511 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 521 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
512 Function expectAsyncUntil0(Function callback, Function isDone) { 522 Function expectAsyncUntil0(Function callback, Function isDone, {String id}) {
513 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke0; 523 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke0;
514 } 524 }
515 525
516 /** 526 /**
517 * Like [expectAsyncUntil0] but [callback] should take 1 positional argument. 527 * Like [expectAsyncUntil0] but [callback] should take 1 positional argument.
518 */ 528 */
519 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 529 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
520 Function expectAsyncUntil1(Function callback, Function isDone) { 530 Function expectAsyncUntil1(Function callback, Function isDone, {String id}) {
521 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke1; 531 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke1;
522 } 532 }
523 533
524 /** 534 /**
525 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments. 535 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments.
526 */ 536 */
527 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 537 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
528 Function expectAsyncUntil2(Function callback, Function isDone) { 538 Function expectAsyncUntil2(Function callback, Function isDone, {String id}) {
529 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke2; 539 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke2;
530 } 540 }
531 541
532 /** 542 /**
533 * Wraps the [callback] in a new function and returns that function. The new 543 * Wraps the [callback] in a new function and returns that function. The new
534 * function will be able to handle exceptions by directing them to the correct 544 * function will be able to handle exceptions by directing them to the correct
535 * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that 545 * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that
536 * might optionally be called but may never be called during the test. 546 * might optionally be called but may never be called during the test.
537 * [callback] should take between 0 and 4 positional arguments (named arguments 547 * [callback] should take between 0 and 4 positional arguments (named arguments
538 * are not supported). 548 * are not supported). [id] can be used to identify the callback in error
549 * messages (for example if it is called after the test case is complete).
539 */ 550 */
540 Function _protectAsync(Function callback) { 551 Function _protectAsync(Function callback, {String id}) {
541 return new _SpreadArgsHelper.optionalCalls(callback).invoke; 552 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke;
542 } 553 }
543 554
544 /** 555 /**
545 * Wraps the [callback] in a new function and returns that function. The new 556 * Wraps the [callback] in a new function and returns that function. The new
546 * function will be able to handle exceptions by directing them to the correct 557 * function will be able to handle exceptions by directing them to the correct
547 * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that 558 * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that
548 * might optionally be called but may never be called during the test. 559 * might optionally be called but may never be called during the test.
549 * [callback] should take 0 positional arguments (named arguments are not 560 * [callback] should take 0 positional arguments (named arguments are not
550 * supported). 561 * supported). [id] can be used to identify the callback in error
562 * messages (for example if it is called after the test case is complete).
551 */ 563 */
552 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 564 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
553 Function protectAsync0(Function callback) { 565 Function protectAsync0(Function callback, {String id}) {
554 return new _SpreadArgsHelper.optionalCalls(callback).invoke0; 566 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke0;
555 } 567 }
556 568
557 /** 569 /**
558 * Like [protectAsync0] but [callback] should take 1 positional argument. 570 * Like [protectAsync0] but [callback] should take 1 positional argument.
559 */ 571 */
560 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 572 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
561 Function protectAsync1(Function callback) { 573 Function protectAsync1(Function callback, {String id}) {
562 return new _SpreadArgsHelper.optionalCalls(callback).invoke1; 574 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke1;
563 } 575 }
564 576
565 /** 577 /**
566 * Like [protectAsync0] but [callback] should take 2 positional arguments. 578 * Like [protectAsync0] but [callback] should take 2 positional arguments.
567 */ 579 */
568 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 580 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
569 Function protectAsync2(Function callback) { 581 Function protectAsync2(Function callback, {String id}) {
570 return new _SpreadArgsHelper.optionalCalls(callback).invoke2; 582 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke2;
571 } 583 }
572 584
573 /** 585 /**
574 * Creates a new named group of tests. Calls to group() or test() within the 586 * Creates a new named group of tests. Calls to group() or test() within the
575 * body of the function passed to this will inherit this group's description. 587 * body of the function passed to this will inherit this group's description.
576 */ 588 */
577 void group(String description, void body()) { 589 void group(String description, void body()) {
578 ensureInitialized(); 590 ensureInitialized();
579 // Concatenate the new group. 591 // Concatenate the new group.
580 final parentGroup = _currentGroup; 592 final parentGroup = _currentGroup;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 * be called after each test in the group is run. Note that if groups 635 * be called after each test in the group is run. Note that if groups
624 * are nested only the most locally scoped [teardownTest] function will be run. 636 * are nested only the most locally scoped [teardownTest] function will be run.
625 * [setUp] and [tearDown] should be called within the [group] before any 637 * [setUp] and [tearDown] should be called within the [group] before any
626 * calls to [test]. The [teardownTest] function can be asynchronous; in this 638 * calls to [test]. The [teardownTest] function can be asynchronous; in this
627 * case it must return a [Future]. 639 * case it must return a [Future].
628 */ 640 */
629 void tearDown(Function teardownTest) { 641 void tearDown(Function teardownTest) {
630 _testTeardown = teardownTest; 642 _testTeardown = teardownTest;
631 } 643 }
632 644
633 /**
634 * Called when one of the callback functions is done with all expected
635 * calls.
636 */
637 void _handleCallbackFunctionComplete(testNum, [id = '']) {
638 // TODO (gram): we defer this to give the nextBatch recursive
639 // stack a chance to unwind. This is a temporary hack but
640 // really a bunch of code here needs to be fixed. We have a
641 // single array that is being iterated through by nextBatch(),
642 // which is recursively invoked in the case of async tests that
643 // run synchronously. Bad things can then happen.
644 _defer(() {
645 if (_currentTest != testNum) {
646 if (_tests[testNum].result == PASS) {
647 _tests[testNum].error("${id}Unexpected extra callbacks", '');
648 }
649 } else if (_currentTest < _tests.length) {
650 final testCase = _tests[_currentTest];
651 --testCase.callbackFunctionsOutstanding;
652 if (testCase.callbackFunctionsOutstanding < 0) {
653 // TODO(gram): Check: Can this even happen?
654 testCase.error(
655 'More calls to _handleCallbackFunctionComplete() than expected.',
656 '');
657 } else if (testCase.callbackFunctionsOutstanding == 0 &&
658 !testCase.isComplete) {
659 testCase.pass();
660 }
661 }
662 });
663 }
664
665 /** Advance to the next test case. */ 645 /** Advance to the next test case. */
666 void _nextTestCase() { 646 void _nextTestCase() {
667 _defer(() { 647 _defer(() {
668 _currentTest++; 648 _currentTest++;
669 _testRunner(); 649 _testRunner();
670 }); 650 });
671 } 651 }
672 652
673 /** 653 /**
674 * Temporary hack: expose old API.
675 * TODO(gram) remove this when WebKit tests are working with new framework
676 */
677 void callbackDone() {
678 _handleCallbackFunctionComplete(_currentTest);
679 }
680
681 /**
682 * Utility function that can be used to notify the test framework that an 654 * Utility function that can be used to notify the test framework that an
683 * error was caught outside of this library. 655 * error was caught outside of this library.
684 */ 656 */
685 void _reportTestError(String msg, String trace) { 657 void _reportTestError(String msg, String trace) {
686 if (_currentTest < _tests.length) { 658 if (_currentTest < _tests.length) {
687 final testCase = _tests[_currentTest]; 659 final testCase = _tests[_currentTest];
688 testCase.error(msg, trace); 660 testCase.error(msg, trace);
689 } else { 661 } else {
690 _uncaughtErrorMessage = "$msg: $trace"; 662 _uncaughtErrorMessage = "$msg: $trace";
691 } 663 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 */ 737 */
766 registerException(e, [trace]) { 738 registerException(e, [trace]) {
767 _registerException(_currentTest, e, trace); 739 _registerException(_currentTest, e, trace);
768 } 740 }
769 741
770 /** 742 /**
771 * Registers that an exception was caught for the current test. 743 * Registers that an exception was caught for the current test.
772 */ 744 */
773 _registerException(testNum, e, [trace]) { 745 _registerException(testNum, e, [trace]) {
774 trace = trace == null ? '' : trace.toString(); 746 trace = trace == null ? '' : trace.toString();
747 String message = (e is TestFailure) ? e.message : 'Caught $e';
775 if (_tests[testNum].result == null) { 748 if (_tests[testNum].result == null) {
776 String message = (e is TestFailure) ? e.message : 'Caught $e';
777 _tests[testNum].fail(message, trace); 749 _tests[testNum].fail(message, trace);
778 } else { 750 } else {
779 _tests[testNum].error('Caught $e', trace); 751 _tests[testNum].error(message, trace);
780 } 752 }
781 } 753 }
782 754
783 /** 755 /**
784 * Runs a batch of tests, yielding whenever an asynchronous test starts 756 * Runs a batch of tests, yielding whenever an asynchronous test starts
785 * running. Tests will resume executing when such asynchronous test calls 757 * running. Tests will resume executing when such asynchronous test calls
786 * [done] or if it fails with an exception. 758 * [done] or if it fails with an exception.
787 */ 759 */
788 _nextBatch() { 760 _nextBatch() {
789 while (true) { 761 while (true) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 } 853 }
882 854
883 /** Enable a test by ID. */ 855 /** Enable a test by ID. */
884 void enableTest(int testId) => _setTestEnabledState(testId, true); 856 void enableTest(int testId) => _setTestEnabledState(testId, true);
885 857
886 /** Disable a test by ID. */ 858 /** Disable a test by ID. */
887 void disableTest(int testId) => _setTestEnabledState(testId, false); 859 void disableTest(int testId) => _setTestEnabledState(testId, false);
888 860
889 /** Signature for a test function. */ 861 /** Signature for a test function. */
890 typedef dynamic TestFunction(); 862 typedef dynamic TestFunction();
OLDNEW
« no previous file with comments | « pkg/unittest/lib/src/test_case.dart ('k') | pkg/unittest/test/unittest_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698