OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview JavaScript unit testing framework for synchronous and | 6 * @fileoverview JavaScript unit testing framework for synchronous and |
7 * asynchronous tests. | 7 * asynchronous tests. |
8 * | 8 * |
9 * This file contains the TestManager and related classes. At the moment it's | 9 * This file contains the TestManager and related classes. At the moment it's |
10 * all collected in a single file since it's reasonably small (=~1k lines), and | 10 * all collected in a single file since it's reasonably small (=~1k lines), and |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 * this suite's testcases. | 325 * this suite's testcases. |
326 * | 326 * |
327 * Any exception here will abort the remainder of the test run. | 327 * Any exception here will abort the remainder of the test run. |
328 * | 328 * |
329 * @param {TestManager.Result} result The result object for the upcoming test. | 329 * @param {TestManager.Result} result The result object for the upcoming test. |
330 * @param {Object} cx The context object for a test run. | 330 * @param {Object} cx The context object for a test run. |
331 */ | 331 */ |
332 TestManager.Suite.prototype.preamble = function(result, cx) {}; | 332 TestManager.Suite.prototype.preamble = function(result, cx) {}; |
333 | 333 |
334 /** | 334 /** |
| 335 * Subclassable method called to do post-test tear-down. |
| 336 * |
| 337 * The default implementation of this method is a no-op. If your test suite |
| 338 * requires some kind of pre-test setup, this is the place to do it. |
| 339 * |
| 340 * This can be used to avoid a bunch of boilerplate setup/teardown code in |
| 341 * this suite's testcases. |
| 342 * |
| 343 * Any exception here will abort the remainder of the test run. |
| 344 * |
| 345 * @param {TestManager.Result} result The result object for the upcoming test. |
| 346 * @param {Object} cx The context object for a test run. |
| 347 */ |
| 348 TestManager.Suite.prototype.postamble = function(result, cx) {}; |
| 349 |
| 350 /** |
335 * Object representing a single test in a test suite. | 351 * Object representing a single test in a test suite. |
336 * | 352 * |
337 * These are created as part of the TestManager.Suite.addTest() method. You | 353 * These are created as part of the TestManager.Suite.addTest() method. You |
338 * should never have to construct one by hand. | 354 * should never have to construct one by hand. |
339 * | 355 * |
340 * @param {TestManager.Suite} suiteClass The test suite class containing this | 356 * @param {TestManager.Suite} suiteClass The test suite class containing this |
341 * test. | 357 * test. |
342 * @param {string} testName The local name of this test case, not including the | 358 * @param {string} testName The local name of this test case, not including the |
343 * test suite name. | 359 * test suite name. |
344 * @param {function(TestManager.Result, Object)} testFunction The function to | 360 * @param {function(TestManager.Result, Object)} testFunction The function to |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 */ | 483 */ |
468 TestManager.TestRun.prototype.ALL_TESTS = new String('<all-tests>'); | 484 TestManager.TestRun.prototype.ALL_TESTS = new String('<all-tests>'); |
469 | 485 |
470 /** | 486 /** |
471 * Add a single test to the test run. | 487 * Add a single test to the test run. |
472 */ | 488 */ |
473 TestManager.TestRun.prototype.selectTest = function(test) { | 489 TestManager.TestRun.prototype.selectTest = function(test) { |
474 this.testQueue_.push(test); | 490 this.testQueue_.push(test); |
475 }; | 491 }; |
476 | 492 |
477 TestManager.TestRun.prototype.selectSuite = function(suiteClass, pattern) { | 493 TestManager.TestRun.prototype.selectSuite = function(suiteClass, opt_pattern) { |
| 494 var pattern = opt_pattern || this.ALL_TESTS; |
478 var selectCount = 0; | 495 var selectCount = 0; |
479 | |
480 var testList = suiteClass.getTestList(); | 496 var testList = suiteClass.getTestList(); |
481 | 497 |
482 for (var j = 0; j < testList.length; j++) { | 498 for (var j = 0; j < testList.length; j++) { |
483 var test = testList[j]; | 499 var test = testList[j]; |
484 // Note that we're using "!==" rather than "!=" so that we're matching | 500 // Note that we're using "!==" rather than "!=" so that we're matching |
485 // the ALL_TESTS String object, rather than the contents of the string. | 501 // the ALL_TESTS String object, rather than the contents of the string. |
486 if (pattern !== this.ALL_TESTS) { | 502 if (pattern !== this.ALL_TESTS) { |
487 if (pattern instanceof RegExp) { | 503 if (pattern instanceof RegExp) { |
488 if (!pattern.test(test.testName)) | 504 if (!pattern.test(test.testName)) |
489 continue; | 505 continue; |
490 } else if (testName != pattern) { | 506 } else if (test.testName != pattern) { |
491 continue; | 507 continue; |
492 } | 508 } |
493 } | 509 } |
494 | 510 |
495 this.selectTest(test); | 511 this.selectTest(test); |
496 selectCount++; | 512 selectCount++; |
497 } | 513 } |
498 | 514 |
499 return selectCount; | 515 return selectCount; |
500 }; | 516 }; |
(...skipping 29 matching lines...) Expand all Loading... |
530 * Hooked up to window.onerror during a test run in order to catch exceptions | 546 * Hooked up to window.onerror during a test run in order to catch exceptions |
531 * that would otherwise go uncaught. | 547 * that would otherwise go uncaught. |
532 */ | 548 */ |
533 TestManager.TestRun.prototype.onUncaughtException_ = function( | 549 TestManager.TestRun.prototype.onUncaughtException_ = function( |
534 message, file, line) { | 550 message, file, line) { |
535 | 551 |
536 if (message.indexOf('Uncaught TestManager.Result.TestComplete') == 0) { | 552 if (message.indexOf('Uncaught TestManager.Result.TestComplete') == 0) { |
537 // This is a result.pass() or result.fail() call from a callback. We're | 553 // This is a result.pass() or result.fail() call from a callback. We're |
538 // already going to deal with it as part of the completeTest_() call | 554 // already going to deal with it as part of the completeTest_() call |
539 // that raised it. We can safely squelch this error message. | 555 // that raised it. We can safely squelch this error message. |
540 return false; | 556 return true; |
541 } | 557 } |
542 | 558 |
543 if (!this.currentResult) | 559 if (!this.currentResult) |
544 return; | 560 return; |
545 | 561 |
546 if (message == 'Uncaught ' + this.currentResult.expectedErrorMessage_) { | 562 if (message == 'Uncaught ' + this.currentResult.expectedErrorMessage_) { |
547 // Test cases may need to raise an unhandled exception as part of the test. | 563 // Test cases may need to raise an unhandled exception as part of the test. |
548 return; | 564 return; |
549 } | 565 } |
550 | 566 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 this.testManager.onTestRunComplete(this); | 614 this.testManager.onTestRunComplete(this); |
599 }; | 615 }; |
600 | 616 |
601 /** | 617 /** |
602 * Called by the TestManager.Result object when a test completes. | 618 * Called by the TestManager.Result object when a test completes. |
603 * | 619 * |
604 * @param {TestManager.Result} result The result object which has just | 620 * @param {TestManager.Result} result The result object which has just |
605 * completed. | 621 * completed. |
606 */ | 622 */ |
607 TestManager.TestRun.prototype.onResultComplete = function(result) { | 623 TestManager.TestRun.prototype.onResultComplete = function(result) { |
| 624 try { |
| 625 result.suite.postamble(); |
| 626 } catch (ex) { |
| 627 this.log.println('Unexpected exception in postamble: ' + |
| 628 (ex.stack ? ex.stack : ex)); |
| 629 this.panic = true; |
| 630 } |
| 631 |
608 this.log.popPrefix(); | 632 this.log.popPrefix(); |
609 this.log.print('} ' + result.status + ', ' + | 633 this.log.print('} ' + result.status + ', ' + |
610 this.msToSeconds_(result.duration)); | 634 this.msToSeconds_(result.duration)); |
611 this.log.flush(); | 635 this.log.flush(); |
612 | 636 |
613 if (result.status == result.FAILED) { | 637 if (result.status == result.FAILED) { |
614 this.failures.push(result); | 638 this.failures.push(result); |
615 this.currentSuite = null; | 639 this.currentSuite = null; |
616 } else if (result.status == result.PASSED) { | 640 } else if (result.status == result.PASSED) { |
617 this.passes.push(result); | 641 this.passes.push(result); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 | 766 |
743 window.onerror = this.onUncaughtException_.bind(this); | 767 window.onerror = this.onUncaughtException_.bind(this); |
744 this.startDate = new Date(); | 768 this.startDate = new Date(); |
745 this.runNextTest_(); | 769 this.runNextTest_(); |
746 }; | 770 }; |
747 | 771 |
748 /** | 772 /** |
749 * Format milliseconds as fractional seconds. | 773 * Format milliseconds as fractional seconds. |
750 */ | 774 */ |
751 TestManager.TestRun.prototype.msToSeconds_ = function(ms) { | 775 TestManager.TestRun.prototype.msToSeconds_ = function(ms) { |
752 var secs = (ms / 100).toFixed(2); | 776 var secs = (ms / 1000).toFixed(2); |
753 return secs + 's'; | 777 return secs + 's'; |
754 }; | 778 }; |
755 | 779 |
756 /** | 780 /** |
757 * Log the current result summary. | 781 * Log the current result summary. |
758 */ | 782 */ |
759 TestManager.TestRun.prototype.summarize = function() { | 783 TestManager.TestRun.prototype.summarize = function() { |
760 if (this.failures.length) { | 784 if (this.failures.length) { |
761 for (var i = 0; i < this.failures.length; i++) { | 785 for (var i = 0; i < this.failures.length; i++) { |
762 this.log.println('FAILED: ' + this.failures[i].test.fullName); | 786 this.log.println('FAILED: ' + this.failures[i].test.fullName); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 * This will throw a TestCompleted exception, causing the current test to stop. | 1046 * This will throw a TestCompleted exception, causing the current test to stop. |
1023 * | 1047 * |
1024 * @param {string} opt_message Optional message to add to the log. | 1048 * @param {string} opt_message Optional message to add to the log. |
1025 */ | 1049 */ |
1026 TestManager.Result.prototype.pass = function(opt_message) { | 1050 TestManager.Result.prototype.pass = function(opt_message) { |
1027 if (arguments.length) | 1051 if (arguments.length) |
1028 this.println(opt_message); | 1052 this.println(opt_message); |
1029 | 1053 |
1030 this.completeTest_(this.PASSED, true); | 1054 this.completeTest_(this.PASSED, true); |
1031 }; | 1055 }; |
OLD | NEW |