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

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
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 String id;
295 Function _shouldCallBack; 301 int actualCalls = 0;
296 Function _isDone; 302 TestCase testCase;
297 String _id; 303 int testNum;
Siggi Cherem (dart-lang) 2013/02/28 23:31:53 can this be final too?
gram 2013/03/04 19:51:25 Done.
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) :
Siggi Cherem (dart-lang) 2013/02/28 23:31:53 constructor style nits: * indent this line only +
gram 2013/03/04 19:51:25 Done.
309 this.callback = callback,
310 this.minExpectedCalls = minExpected,
Siggi Cherem (dart-lang) 2013/02/28 23:31:53 remove 'this' (it is only necessary if the name is
gram 2013/03/04 19:51:25 Done.
311 this.maxExpectedCalls = (maxExpected == 0 && minExpected > 0) ? minExpected : maxExpected,
Siggi Cherem (dart-lang) 2013/02/28 23:31:53 long line: wrap after before '?'
gram 2013/03/04 19:51:25 Done.
312 this.isDone = isDone {
302 ensureInitialized(); 313 ensureInitialized();
303 if (!(_currentTest >= 0 && 314 if (!(_currentTest >= 0 &&
304 _currentTest < _tests.length && 315 _currentTest < _tests.length &&
305 _tests[_currentTest] != null)) { 316 _tests[_currentTest] != null)) {
306 print("No valid test, did you forget to run your test inside a call " 317 print("No valid test, did you forget to run your test inside a call "
307 "to test()?"); 318 "to test()?");
308 } 319 }
309 assert(_currentTest >= 0 && 320 assert(_currentTest >= 0 &&
310 _currentTest < _tests.length && 321 _currentTest < _tests.length &&
311 _tests[_currentTest] != null); 322 _tests[_currentTest] != null);
312 _callback = callback; 323 testNum = _currentTest;
313 _shouldCallBack = shouldCallBack; 324 testCase = _tests[_currentTest];
314 _isDone = isDone; 325 if (isDone != null || minExpected > 0) {
315 _expectedCalls = expectedCalls; 326 testCase.callbackFunctionsOutstanding++;
316 _testNum = _currentTest; 327 complete = false;
317 _testCase = _tests[_currentTest]; 328 } else {
318 if (expectedCalls > 0) { 329 complete = true;
319 _testCase.callbackFunctionsOutstanding++;
320 } 330 }
321 _id = ''; 331
322 // If the callback is not an anonymous closure, try to get the 332 // Try to create a reasonable id.
Siggi Cherem (dart-lang) 2013/02/28 23:31:53 by moving this code to a static private function,
gram 2013/03/04 19:51:25 Done.
323 // name. 333 this.id = '';
324 var fname = callback.toString(); 334 if (id != null) {
325 var prefix = "Function '"; 335 this.id = "$id ";
326 var pos = fname.indexOf(prefix); 336 } else {
327 if (pos > 0) { 337 // If the callback is not an anonymous closure, try to get the
328 pos += prefix.length; 338 // name.
329 var epos = fname.indexOf("'", pos); 339 var fname = callback.toString();
330 if (epos > 0) { 340 var prefix = "Function '";
331 _id = "${fname.substring(pos, epos)} "; 341 var pos = fname.indexOf(prefix);
342 if (pos > 0) {
343 pos += prefix.length;
344 var epos = fname.indexOf("'", pos);
345 if (epos > 0) {
346 this.id = "${fname.substring(pos, epos)} ";
347 }
332 } 348 }
333 } 349 }
334 } 350 }
335 351
336 _SpreadArgsHelper(callback, shouldCallBack, isDone) { 352 shouldCallBack() {
337 _init(callback, shouldCallBack, isDone); 353 ++actualCalls;
354 if (testCase.isComplete) {
355 // Don't run if the test is done. We don't throw here as this is not
356 // the current test, but we do mark the old test as having an error
357 // if it previously passed.
358 if (testCase.result == PASS) {
359 testCase.error(
360 'Callback ${id}called after test case ${testCase.description} '
361 'has already been marked as done.',
362 '');
Siggi Cherem (dart-lang) 2013/02/28 23:31:53 nit: move this to the previous line.
gram 2013/03/04 19:51:25 Done.
363 }
364 return false;
365 } else if (maxExpectedCalls >= 0 && actualCalls > maxExpectedCalls) {
366 throw new TestFailure('Callback ${id}called more times than expected '
367 '($maxExpectedCalls).');
368 }
369 return true;
338 } 370 }
339 371
340 _SpreadArgsHelper.fixedCallCount(callback, expectedCalls, id) { 372 after() {
341 _init(callback, _checkCallCount, _allCallsDone, expectedCalls); 373 if (!complete) {
342 if (id != null) { 374 if (minExpectedCalls > 0 && actualCalls < minExpectedCalls) {
Siggi Cherem (dart-lang) 2013/02/28 23:31:53 nit: if it fits in one line, do the fast-exit patt
gram 2013/03/04 19:51:25 Done.
343 _id = "$id "; 375 return;
376 }
377 if (isDone != null && !isDone()) {
378 return;
379 }
380 // Mark this callback as complete and remove it from the testcase
381 // oustanding callback count; if that hits zero the testcase is done.
382 complete = true;
383 if (--testCase.callbackFunctionsOutstanding == 0 &&
384 !testCase.isComplete) {
385 testCase.pass();
386 }
344 } 387 }
345 } 388 }
346 389
347 _SpreadArgsHelper.variableCallCount(callback, isDone) { 390 invoke([arg0 = sentinel, arg1 = sentinel, arg2 = sentinel,
348 _init(callback, _always, isDone, 1); 391 arg3 = sentinel, arg4 = sentinel]) {
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(() { 392 return guardAsync(() {
379 ++_actualCalls; 393 if (!shouldCallBack()) {
380 if (!_shouldCallBack()) {
381 return; 394 return;
382 } else if (arg0 == _sentinel) { 395 } else if (arg0 == sentinel) {
383 return _callback(); 396 return callback();
384 } else if (arg1 == _sentinel) { 397 } else if (arg1 == sentinel) {
385 return _callback(arg0); 398 return callback(arg0);
386 } else if (arg2 == _sentinel) { 399 } else if (arg2 == sentinel) {
387 return _callback(arg0, arg1); 400 return callback(arg0, arg1);
388 } else if (arg3 == _sentinel) { 401 } else if (arg3 == sentinel) {
389 return _callback(arg0, arg1, arg2); 402 return callback(arg0, arg1, arg2);
390 } else if (arg4 == _sentinel) { 403 } else if (arg4 == sentinel) {
391 return _callback(arg0, arg1, arg2, arg3); 404 return callback(arg0, arg1, arg2, arg3);
392 } else { 405 } else {
393 _testCase.error( 406 testCase.error(
394 'unittest lib does not support callbacks with more than' 407 'unittest lib does not support callbacks with more than'
395 ' 4 arguments.', 408 ' 4 arguments.',
396 ''); 409 '');
397 } 410 }
398 }, 411 },
399 _after, _testNum); 412 after, testNum);
400 } 413 }
401 414
402 invoke0() { 415 invoke0() {
403 return guardAsync( 416 return guardAsync(
404 () { 417 () {
405 ++_actualCalls; 418 if (shouldCallBack()) {
406 if (_shouldCallBack()) { 419 return callback();
407 return _callback();
408 } 420 }
409 }, 421 },
410 _after, _testNum); 422 after, testNum);
411 } 423 }
412 424
413 invoke1(arg1) { 425 invoke1(arg1) {
414 return guardAsync( 426 return guardAsync(
415 () { 427 () {
416 ++_actualCalls; 428 if (shouldCallBack()) {
417 if (_shouldCallBack()) { 429 return callback(arg1);
418 return _callback(arg1);
419 } 430 }
420 }, 431 },
421 _after, _testNum); 432 after, testNum);
422 } 433 }
423 434
424 invoke2(arg1, arg2) { 435 invoke2(arg1, arg2) {
425 return guardAsync( 436 return guardAsync(
426 () { 437 () {
427 ++_actualCalls; 438 if (shouldCallBack()) {
428 if (_shouldCallBack()) { 439 return callback(arg1, arg2);
429 return _callback(arg1, arg2);
430 } 440 }
431 }, 441 },
432 _after, _testNum); 442 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 } 443 }
444 } 444 }
445 445
446 /** 446 /**
447 * Indicate that [callback] is expected to be called a [count] number of times 447 * 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 448 * (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 449 * specified [count] times before it continues with the following test. Using
450 * [_expectAsync] will also ensure that errors that occur within [callback] are 450 * [_expectAsync] will also ensure that errors that occur within [callback] are
451 * tracked and reported. [callback] should take between 0 and 4 positional 451 * tracked and reported. [callback] should take between 0 and 4 positional
452 * arguments (named arguments are not supported here). [id] can be used 452 * arguments (named arguments are not supported here). [id] can be used
453 * to provide more descriptive error messages if the callback is called more 453 * to provide more descriptive error messages if the callback is called more
454 * often than expected. 454 * often than expected.
455 */ 455 */
456 Function _expectAsync(Function callback, {int count: 1, String id}) { 456 Function _expectAsync(Function callback,
457 return new _SpreadArgsHelper. 457 {int count: 1, int max: 0, String id}) {
458 fixedCallCount(callback, count, id).invoke; 458 return new _SpreadArgsHelper(callback, count, max, null, id).invoke;
459 } 459 }
460 460
461 /** 461 /**
462 * Indicate that [callback] is expected to be called a [count] number of times 462 * 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 463 * (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 464 * specified [count] times before it continues with the following test. Using
465 * [expectAsync0] will also ensure that errors that occur within [callback] are 465 * [expectAsync0] will also ensure that errors that occur within [callback] are
466 * tracked and reported. [callback] should take 0 positional arguments (named 466 * tracked and reported. [callback] should take 0 positional arguments (named
467 * arguments are not supported). [id] can be used to provide more 467 * arguments are not supported). [id] can be used to provide more
468 * descriptive error messages if the callback is called more often than 468 * descriptive error messages if the callback is called more often than
469 * expected. 469 * expected. [max] can be used to specify an upper bound on the number of
470 * calls; if this is exceeded the test will fail (or be marked as in error if
471 * it was already complete). A value of 0 for [max] (the default) will set
472 * the upper bound to the same value as [count]; i.e. the callback should be
473 * called exactly [count] times. A value of -1 for [max] will mean no upper
Siggi Cherem (dart-lang) 2013/02/28 23:31:53 thanks =)
gram 2013/03/04 19:51:25 Done.
474 * bound.
470 */ 475 */
471 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 476 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
472 Function expectAsync0(Function callback, {int count: 1, String id}) { 477 Function expectAsync0(Function callback,
473 return new _SpreadArgsHelper. 478 {int count: 1, int max: 0, String id}) {
474 fixedCallCount(callback, count, id).invoke0; 479 return new _SpreadArgsHelper(callback, count, max, null, id).invoke0;
475 } 480 }
476 481
477 /** Like [expectAsync0] but [callback] should take 1 positional argument. */ 482 /** Like [expectAsync0] but [callback] should take 1 positional argument. */
478 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 483 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
479 Function expectAsync1(Function callback, {int count: 1, String id}) { 484 Function expectAsync1(Function callback,
480 return new _SpreadArgsHelper. 485 {int count: 1, int max: 0, String id}) {
481 fixedCallCount(callback, count, id).invoke1; 486 return new _SpreadArgsHelper(callback, count, max, null, id).invoke1;
482 } 487 }
483 488
484 /** Like [expectAsync0] but [callback] should take 2 positional arguments. */ 489 /** Like [expectAsync0] but [callback] should take 2 positional arguments. */
485 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 490 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
486 Function expectAsync2(Function callback, {int count: 1, String id}) { 491 Function expectAsync2(Function callback,
487 return new _SpreadArgsHelper. 492 {int count: 1, int max: 0, String id}) {
488 fixedCallCount(callback, count, id).invoke2; 493 return new _SpreadArgsHelper(callback, count, max, null, id).invoke2;
489 } 494 }
490 495
491 /** 496 /**
492 * Indicate that [callback] is expected to be called until [isDone] returns 497 * Indicate that [callback] is expected to be called until [isDone] returns
493 * true. The unittest framework checks [isDone] after each callback and only 498 * true. The unittest framework checks [isDone] after each callback and only
494 * when it returns true will it continue with the following test. Using 499 * when it returns true will it continue with the following test. Using
495 * [expectAsyncUntil] will also ensure that errors that occur within 500 * [expectAsyncUntil] will also ensure that errors that occur within
496 * [callback] are tracked and reported. [callback] should take between 0 and 501 * [callback] are tracked and reported. [callback] should take between 0 and
497 * 4 positional arguments (named arguments are not supported). 502 * 4 positional arguments (named arguments are not supported). [id] can be
503 * used to identify the callback in error messages (for example if it is called
504 * after the test case is complete).
498 */ 505 */
499 Function _expectAsyncUntil(Function callback, Function isDone) { 506 Function _expectAsyncUntil(Function callback, Function isDone, {String id}) {
500 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke; 507 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke;
501 } 508 }
502 509
503 /** 510 /**
504 * Indicate that [callback] is expected to be called until [isDone] returns 511 * Indicate that [callback] is expected to be called until [isDone] returns
505 * true. The unittest framework check [isDone] after each callback and only 512 * true. The unittest framework check [isDone] after each callback and only
506 * when it returns true will it continue with the following test. Using 513 * when it returns true will it continue with the following test. Using
507 * [expectAsyncUntil0] will also ensure that errors that occur within 514 * [expectAsyncUntil0] will also ensure that errors that occur within
508 * [callback] are tracked and reported. [callback] should take 0 positional 515 * [callback] are tracked and reported. [callback] should take 0 positional
509 * arguments (named arguments are not supported). 516 * arguments (named arguments are not supported). [id] can be used to
517 * identify the callback in error messages (for example if it is called
518 * after the test case is complete).
510 */ 519 */
511 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 520 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
512 Function expectAsyncUntil0(Function callback, Function isDone) { 521 Function expectAsyncUntil0(Function callback, Function isDone, {String id}) {
513 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke0; 522 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke0;
514 } 523 }
515 524
516 /** 525 /**
517 * Like [expectAsyncUntil0] but [callback] should take 1 positional argument. 526 * Like [expectAsyncUntil0] but [callback] should take 1 positional argument.
518 */ 527 */
519 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 528 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
520 Function expectAsyncUntil1(Function callback, Function isDone) { 529 Function expectAsyncUntil1(Function callback, Function isDone, {String id}) {
521 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke1; 530 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke1;
522 } 531 }
523 532
524 /** 533 /**
525 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments. 534 * Like [expectAsyncUntil0] but [callback] should take 2 positional arguments.
526 */ 535 */
527 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 536 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
528 Function expectAsyncUntil2(Function callback, Function isDone) { 537 Function expectAsyncUntil2(Function callback, Function isDone, {String id}) {
529 return new _SpreadArgsHelper.variableCallCount(callback, isDone).invoke2; 538 return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke2;
530 } 539 }
531 540
532 /** 541 /**
533 * Wraps the [callback] in a new function and returns that function. The new 542 * 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 543 * 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 544 * 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. 545 * might optionally be called but may never be called during the test.
537 * [callback] should take between 0 and 4 positional arguments (named arguments 546 * [callback] should take between 0 and 4 positional arguments (named arguments
538 * are not supported). 547 * are not supported). [id] can be used to identify the callback in error
548 * messages (for example if it is called after the test case is complete).
539 */ 549 */
540 Function _protectAsync(Function callback) { 550 Function _protectAsync(Function callback, {String id}) {
541 return new _SpreadArgsHelper.optionalCalls(callback).invoke; 551 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke;
542 } 552 }
543 553
544 /** 554 /**
545 * Wraps the [callback] in a new function and returns that function. The new 555 * 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 556 * 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 557 * 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. 558 * might optionally be called but may never be called during the test.
549 * [callback] should take 0 positional arguments (named arguments are not 559 * [callback] should take 0 positional arguments (named arguments are not
550 * supported). 560 * supported). [id] can be used to identify the callback in error
561 * messages (for example if it is called after the test case is complete).
551 */ 562 */
552 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 563 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
553 Function protectAsync0(Function callback) { 564 Function protectAsync0(Function callback, {String id}) {
554 return new _SpreadArgsHelper.optionalCalls(callback).invoke0; 565 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke0;
555 } 566 }
556 567
557 /** 568 /**
558 * Like [protectAsync0] but [callback] should take 1 positional argument. 569 * Like [protectAsync0] but [callback] should take 1 positional argument.
559 */ 570 */
560 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 571 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
561 Function protectAsync1(Function callback) { 572 Function protectAsync1(Function callback, {String id}) {
562 return new _SpreadArgsHelper.optionalCalls(callback).invoke1; 573 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke1;
563 } 574 }
564 575
565 /** 576 /**
566 * Like [protectAsync0] but [callback] should take 2 positional arguments. 577 * Like [protectAsync0] but [callback] should take 2 positional arguments.
567 */ 578 */
568 // TODO(sigmund): deprecate this API when issue 2706 is fixed. 579 // TODO(sigmund): deprecate this API when issue 2706 is fixed.
569 Function protectAsync2(Function callback) { 580 Function protectAsync2(Function callback, {String id}) {
570 return new _SpreadArgsHelper.optionalCalls(callback).invoke2; 581 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke2;
571 } 582 }
572 583
573 /** 584 /**
574 * Creates a new named group of tests. Calls to group() or test() within the 585 * 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. 586 * body of the function passed to this will inherit this group's description.
576 */ 587 */
577 void group(String description, void body()) { 588 void group(String description, void body()) {
578 ensureInitialized(); 589 ensureInitialized();
579 // Concatenate the new group. 590 // Concatenate the new group.
580 final parentGroup = _currentGroup; 591 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 634 * 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. 635 * are nested only the most locally scoped [teardownTest] function will be run.
625 * [setUp] and [tearDown] should be called within the [group] before any 636 * [setUp] and [tearDown] should be called within the [group] before any
626 * calls to [test]. The [teardownTest] function can be asynchronous; in this 637 * calls to [test]. The [teardownTest] function can be asynchronous; in this
627 * case it must return a [Future]. 638 * case it must return a [Future].
628 */ 639 */
629 void tearDown(Function teardownTest) { 640 void tearDown(Function teardownTest) {
630 _testTeardown = teardownTest; 641 _testTeardown = teardownTest;
631 } 642 }
632 643
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. */ 644 /** Advance to the next test case. */
666 void _nextTestCase() { 645 void _nextTestCase() {
667 _defer(() { 646 _defer(() {
668 _currentTest++; 647 _currentTest++;
669 _testRunner(); 648 _testRunner();
670 }); 649 });
671 } 650 }
672 651
673 /** 652 /**
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 653 * Utility function that can be used to notify the test framework that an
683 * error was caught outside of this library. 654 * error was caught outside of this library.
684 */ 655 */
685 void _reportTestError(String msg, String trace) { 656 void _reportTestError(String msg, String trace) {
686 if (_currentTest < _tests.length) { 657 if (_currentTest < _tests.length) {
687 final testCase = _tests[_currentTest]; 658 final testCase = _tests[_currentTest];
688 testCase.error(msg, trace); 659 testCase.error(msg, trace);
689 } else { 660 } else {
690 _uncaughtErrorMessage = "$msg: $trace"; 661 _uncaughtErrorMessage = "$msg: $trace";
691 } 662 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 */ 736 */
766 registerException(e, [trace]) { 737 registerException(e, [trace]) {
767 _registerException(_currentTest, e, trace); 738 _registerException(_currentTest, e, trace);
768 } 739 }
769 740
770 /** 741 /**
771 * Registers that an exception was caught for the current test. 742 * Registers that an exception was caught for the current test.
772 */ 743 */
773 _registerException(testNum, e, [trace]) { 744 _registerException(testNum, e, [trace]) {
774 trace = trace == null ? '' : trace.toString(); 745 trace = trace == null ? '' : trace.toString();
746 String message = (e is TestFailure) ? e.message : 'Caught $e';
775 if (_tests[testNum].result == null) { 747 if (_tests[testNum].result == null) {
776 String message = (e is TestFailure) ? e.message : 'Caught $e';
777 _tests[testNum].fail(message, trace); 748 _tests[testNum].fail(message, trace);
778 } else { 749 } else {
779 _tests[testNum].error('Caught $e', trace); 750 _tests[testNum].error(message, trace);
780 } 751 }
781 } 752 }
782 753
783 /** 754 /**
784 * Runs a batch of tests, yielding whenever an asynchronous test starts 755 * Runs a batch of tests, yielding whenever an asynchronous test starts
785 * running. Tests will resume executing when such asynchronous test calls 756 * running. Tests will resume executing when such asynchronous test calls
786 * [done] or if it fails with an exception. 757 * [done] or if it fails with an exception.
787 */ 758 */
788 _nextBatch() { 759 _nextBatch() {
789 while (true) { 760 while (true) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 } 852 }
882 853
883 /** Enable a test by ID. */ 854 /** Enable a test by ID. */
884 void enableTest(int testId) => _setTestEnabledState(testId, true); 855 void enableTest(int testId) => _setTestEnabledState(testId, true);
885 856
886 /** Disable a test by ID. */ 857 /** Disable a test by ID. */
887 void disableTest(int testId) => _setTestEnabledState(testId, false); 858 void disableTest(int testId) => _setTestEnabledState(testId, false);
888 859
889 /** Signature for a test function. */ 860 /** Signature for a test function. */
890 typedef dynamic TestFunction(); 861 typedef dynamic TestFunction();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698