Chromium Code Reviews| 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 Library providing basic test framework functionality. | 6 * @fileoverview Library providing basic test framework functionality. |
| 7 **/ | 7 **/ |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * Namespace for |Test|. | 10 * Namespace for |Test|. |
| 11 * @type {Object} | 11 * @type {Object} |
| 12 **/ | 12 **/ |
| 13 var testing = {}; | 13 var testing = {}; |
| 14 | 14 |
| 15 /** | 15 /** |
| 16 * Hold the currentTestCase across between PreLoad and Run. | 16 * Hold the currentTestCase across between PreLoad and Run. |
| 17 * @type {TestCase} | 17 * @type {TestCase} |
| 18 **/ | 18 **/ |
| 19 var currentTestCase = null; | 19 var currentTestCase = null; |
| 20 | 20 |
| 21 /** | |
| 22 * @type {?string} The string representation of the currently running test | |
| 23 * function. | |
| 24 */ | |
| 25 var currentTestFunction = null; | |
| 26 | |
| 27 /** | |
| 28 * @type {?Array} The arguments of the currently running test. | |
| 29 */ | |
| 30 var currentTestArguments = null; | |
| 31 | |
| 21 (function() { | 32 (function() { |
| 22 // Provide global objects for generation case. | 33 // Provide global objects for generation case. |
| 23 if (this['window'] === undefined) | 34 if (this['window'] === undefined) |
| 24 this['window'] = this; | 35 this['window'] = this; |
| 25 if (this['chrome'] === undefined) { | 36 if (this['chrome'] === undefined) { |
| 26 this['chrome'] = { | 37 this['chrome'] = { |
| 27 send: function() {}, | 38 send: function() {}, |
| 28 }; | 39 }; |
| 29 } | 40 } |
| 30 if (this['console'] === undefined) { | 41 if (this['console'] === undefined) { |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 204 * Overrides {@code chrome.send} for routing messages to javascript | 215 * Overrides {@code chrome.send} for routing messages to javascript |
| 205 * functions. Also fallsback to sending with the original chrome object. | 216 * functions. Also fallsback to sending with the original chrome object. |
| 206 * @param {string} messageName The message to route. | 217 * @param {string} messageName The message to route. |
| 207 **/ | 218 **/ |
| 208 function send(messageName) { | 219 function send(messageName) { |
| 209 var callback = sendCallbacks[messageName]; | 220 var callback = sendCallbacks[messageName]; |
| 210 var args = Array.prototype.slice.call(arguments, 1); | 221 var args = Array.prototype.slice.call(arguments, 1); |
| 211 if (callback != undefined) | 222 if (callback != undefined) |
| 212 callback[1].apply(callback[0], args); | 223 callback[1].apply(callback[0], args); |
| 213 else | 224 else |
| 214 this.__proto__.send.apply(this.__proto__, args); | 225 this.__proto__.send.apply(this.__proto__, args); |
|
Sheridan Rawlins
2011/08/12 18:02:09
Need to include the messageName in the passthrough
| |
| 215 } | 226 } |
| 216 | 227 |
| 217 /** | 228 /** |
| 218 * Provides a mechanism for assert* and expect* methods to fetch the signature | 229 * Provides a mechanism for assert* and expect* methods to fetch the signature |
| 219 * of their caller. Assert* methods should |registerCall| and expect* methods | 230 * of their caller. Assert* methods should |registerCall| and expect* methods |
| 220 * should set |isExpect| and |expectName| properties to indicate that the | 231 * should set |isExpect| and |expectName| properties to indicate that the |
| 221 * interesting caller is one more level up the stack. | 232 * interesting caller is one more level up the stack. |
| 222 **/ | 233 **/ |
| 223 function CallHelper() { | 234 function CallHelper() { |
| 224 this.__proto__ = CallHelper.prototype; | 235 this.__proto__ = CallHelper.prototype; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 return callMessage; | 313 return callMessage; |
| 303 }, | 314 }, |
| 304 }; | 315 }; |
| 305 | 316 |
| 306 /** | 317 /** |
| 307 * Help register calls for better error reporting. | 318 * Help register calls for better error reporting. |
| 308 * @type {CallHelper} | 319 * @type {CallHelper} |
| 309 **/ | 320 **/ |
| 310 var helper = new CallHelper(); | 321 var helper = new CallHelper(); |
| 311 | 322 |
| 323 /** | |
| 324 * true when testDone has been called. | |
| 325 * @type {boolean} | |
| 326 */ | |
| 327 var testIsDone = false; | |
| 328 | |
| 329 /** | |
| 330 * Holds the errors, if any, caught by expects so that the test case can | |
| 331 * fail. Cleared when results are reported from runTest() or testDone(). | |
| 332 * @type {Array.<Error>} | |
| 333 **/ | |
| 334 var errors = []; | |
| 335 | |
| 336 /** | |
| 337 * Notifies the running browser test of the test results. | |
| 338 * @param {Array.<boolean, string>=} result When passed, this is used for the | |
| 339 * testResult message. | |
| 340 **/ | |
| 341 function testDone(result) { | |
| 342 if (!testIsDone) { | |
| 343 testIsDone = true; | |
| 344 chrome.send('testResult', result ? result : testResult()); | |
| 345 errors.splice(0, errors.length); | |
| 346 } | |
| 347 } | |
| 348 | |
| 349 /** | |
| 350 * Returns [success, message] & clears |errors|. | |
| 351 * @return {Array.<boolean, string>} | |
| 352 **/ | |
| 353 function testResult() { | |
| 354 var result = [true, '']; | |
| 355 if (errors.length) { | |
| 356 var message = ''; | |
| 357 for (var i = 0; i < errors.length; ++i) { | |
| 358 message += 'Failed: ' + currentTestFunction + '(' + | |
| 359 currentTestArguments.map(JSON.stringify) + | |
| 360 ')\n' + errors[i].stack; | |
| 361 } | |
| 362 result = [false, message]; | |
| 363 } | |
| 364 return result; | |
| 365 } | |
| 366 | |
| 312 // Asserts. | 367 // Asserts. |
| 313 // Use the following assertions to verify a condition within a test. | 368 // Use the following assertions to verify a condition within a test. |
| 314 // If assertion fails, the C++ backend will be immediately notified. | 369 // If assertion fails, throw an Error with information pertinent to the test. |
| 315 // If assertion passes, no notification will be sent to the C++ backend. | |
| 316 | 370 |
| 317 /** | 371 /** |
| 318 * When |test| !== true, aborts the current test. | 372 * When |test| !== true, aborts the current test. |
| 319 * @param {boolean} test The predicate to check against |expected|. | 373 * @param {boolean} test The predicate to check against |expected|. |
| 320 * @param {string=} message The message to include in the Error thrown. | 374 * @param {string=} message The message to include in the Error thrown. |
| 321 * @throws {Error} upon failure. | 375 * @throws {Error} upon failure. |
| 322 **/ | 376 **/ |
| 323 function assertTrue(test, message) { | 377 function assertTrue(test, message) { |
| 324 helper.registerCall(); | 378 helper.registerCall(); |
| 325 if (test !== true) | 379 if (test !== true) |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 * Always aborts the current test. | 492 * Always aborts the current test. |
| 439 * @param {string=} message The message to include in the Error thrown. | 493 * @param {string=} message The message to include in the Error thrown. |
| 440 * @throws {Error} always. | 494 * @throws {Error} always. |
| 441 **/ | 495 **/ |
| 442 function assertNotReached(message) { | 496 function assertNotReached(message) { |
| 443 helper.registerCall(); | 497 helper.registerCall(); |
| 444 throw new Error(helper.getCallMessage(message)); | 498 throw new Error(helper.getCallMessage(message)); |
| 445 } | 499 } |
| 446 | 500 |
| 447 /** | 501 /** |
| 448 * Holds the errors, if any, caught by expects so that the test case can fail. | |
| 449 * @type {Array.<Error>} | |
| 450 **/ | |
| 451 var errors = []; | |
| 452 | |
| 453 /** | |
| 454 * Creates a function based upon a function that thows an exception on | 502 * Creates a function based upon a function that thows an exception on |
| 455 * failure. The new function stuffs any errors into the |errors| array for | 503 * failure. The new function stuffs any errors into the |errors| array for |
| 456 * checking by runTest. This allows tests to continue running other checks, | 504 * checking by runTest. This allows tests to continue running other checks, |
| 457 * while failing the overal test if any errors occurrred. | 505 * while failing the overall test if any errors occurrred. |
| 458 * @param {Function} assertFunc The function which may throw an Error. | 506 * @param {Function} assertFunc The function which may throw an Error. |
| 459 * @return {Function} A function that applies its arguments to |assertFunc|. | 507 * @return {Function} A function that applies its arguments to |assertFunc|. |
| 460 * @see errors | 508 * @see errors |
| 461 * @see runTest | 509 * @see runTest |
| 462 **/ | 510 **/ |
| 463 function createExpect(assertFunc) { | 511 function createExpect(assertFunc) { |
| 464 var expectFunc = function() { | 512 var expectFunc = function() { |
| 465 try { | 513 try { |
| 466 assertFunc.apply(null, arguments); | 514 assertFunc.apply(null, arguments); |
| 467 } catch (e) { | 515 } catch (e) { |
| 468 errors.push(e); | 516 errors.push(e); |
| 469 } | 517 } |
| 470 }; | 518 }; |
| 471 expectFunc.isExpect = true; | 519 expectFunc.isExpect = true; |
| 472 expectFunc.expectName = assertFunc.name.replace(/^assert/, 'expect'); | 520 expectFunc.expectName = assertFunc.name.replace(/^assert/, 'expect'); |
| 473 return expectFunc; | 521 return expectFunc; |
| 474 } | 522 } |
| 475 | 523 |
| 476 /** | 524 /** |
| 477 * This is the starting point for tests run by WebUIBrowserTest. If an error | 525 * This is the starting point for tests run by WebUIBrowserTest. If an error |
| 478 * occurs, it reports a failure and a message created by joining individual | 526 * occurs, it reports a failure and a message created by joining individual |
| 479 * error messages. | 527 * error messages. This supports sync tests and async tests by calling |
| 528 * testDone() when |isAsync| is not true, relying on async tests to call | |
| 529 * testDone() when they complete. | |
| 530 * @param {boolean} isAsync When false, call testDone() with the test result. | |
| 480 * @param {string} testFunction The function name to call. | 531 * @param {string} testFunction The function name to call. |
| 481 * @param {Array} testArguments The arguments to call |testFunction| with. | 532 * @param {Array} testArguments The arguments to call |testFunction| with. |
| 482 * @return {Array.<boolean, string>} [test-succeeded, message-if-failed] | 533 * @return {boolean} true always to signal successful execution (but not |
| 534 * necessarily successful results) of this test. | |
| 483 * @see errors | 535 * @see errors |
| 484 * @see runTestFunction | 536 * @see runTestFunction |
| 485 **/ | 537 **/ |
| 486 function runTest(testFunction, testArguments) { | 538 function runTest(isAsync, testFunction, testArguments) { |
| 487 // Avoid eval() if at all possible, since it will not work on pages | 539 // Avoid eval() if at all possible, since it will not work on pages |
| 488 // that have enabled content-security-policy. | 540 // that have enabled content-security-policy. |
| 489 var testBody = this[testFunction]; // global object -- not a method. | 541 var testBody = this[testFunction]; // global object -- not a method. |
| 490 if (typeof testBody === "undefined") | 542 var testName = testFunction; |
| 543 if (typeof testBody === "undefined") { | |
| 491 testBody = eval(testFunction); | 544 testBody = eval(testFunction); |
| 545 testName = testBody.toString(); | |
| 546 } | |
| 492 if (testBody != RUN_TEST_F) { | 547 if (testBody != RUN_TEST_F) { |
| 493 var testName = | |
| 494 testFunction.name ? testFunction.name : testBody.toString(); | |
| 495 console.log('Running test ' + testName); | 548 console.log('Running test ' + testName); |
| 496 } | 549 } |
| 497 return runTestFunction(testFunction, testBody, testArguments); | 550 var result = runTestFunction(testFunction, testBody, testArguments); |
| 551 if (!isAsync) | |
| 552 testDone(result); | |
| 553 return true; | |
| 498 } | 554 } |
| 499 | 555 |
| 500 /** | 556 /** |
| 501 * This is the guts of WebUIBrowserTest. It clears |errors|, runs the | 557 * This is the guts of WebUIBrowserTest. It runs the test surrounded by an |
| 502 * test surrounded by an expect to catch Errors. If |errors| is | 558 * expect to catch Errors. If |errors| is non-empty, it reports a failure and |
| 503 * non-empty, it reports a failure and a message by joining |errors|. | 559 * a message by joining |errors|. Consumers can use this to use assert/expect |
| 504 * Consumers can use this to use assert/expect functions asynchronously, | 560 * functions asynchronously, but are then responsible for reporting errors to |
| 505 * but are then responsible for reporting errors to the browser themselves. | 561 * the browser themselves through testDone(). |
| 506 * @param {string} testFunction The function name to report on failure. | 562 * @param {string} testFunction The function name to report on failure. |
| 507 * @param {Function} testBody The function to call. | 563 * @param {Function} testBody The function to call. |
| 508 * @param {Array} testArguments The arguments to call |testBody| with. | 564 * @param {Array} testArguments The arguments to call |testBody| with. |
| 509 * @return {Array.<boolean, string>} [test-succeeded, message-if-failed] | 565 * @return {Array.<boolean, string>} [test-succeeded, message-if-failed] |
| 510 * @see errors | |
| 511 * @see createExpect | 566 * @see createExpect |
| 567 * @see testDone | |
| 512 **/ | 568 **/ |
| 513 function runTestFunction(testFunction, testBody, testArguments) { | 569 function runTestFunction(testFunction, testBody, testArguments) { |
| 514 errors.splice(0, errors.length); | 570 currentTestFunction = testFunction; |
| 571 currentTestArguments = testArguments; | |
| 515 createExpect(testBody).apply(null, testArguments); | 572 createExpect(testBody).apply(null, testArguments); |
| 516 | 573 return testResult(); |
| 517 var result = [true]; | |
| 518 if (errors.length) { | |
| 519 var message = ''; | |
| 520 for (var i = 0; i < errors.length; ++i) { | |
| 521 message += 'Failed: ' + testFunction + '(' + | |
| 522 testArguments.map(JSON.stringify) + | |
| 523 ')\n' + errors[i].stack; | |
| 524 } | |
| 525 errors.splice(0, errors.length); | |
| 526 result = [false, message]; | |
| 527 } | |
| 528 return result; | |
| 529 } | 574 } |
| 530 | 575 |
| 531 /** | 576 /** |
| 532 * Creates a new test case for the given |testFixture| and |testName|. Assumes | 577 * Creates a new test case for the given |testFixture| and |testName|. Assumes |
| 533 * |testFixture| describes a globally available subclass of type Test. | 578 * |testFixture| describes a globally available subclass of type Test. |
| 534 * @param {string} testFixture The fixture for this test case. | 579 * @param {string} testFixture The fixture for this test case. |
| 535 * @param {string} testName The name for this test case. | 580 * @param {string} testName The name for this test case. |
| 536 * @return {TestCase} A newly created TestCase. | 581 * @return {TestCase} A newly created TestCase. |
| 537 **/ | 582 **/ |
| 538 function createTestCase(testFixture, testName) { | 583 function createTestCase(testFixture, testName) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 703 * @return {string} description of the matcher for this argument. | 748 * @return {string} description of the matcher for this argument. |
| 704 **/ | 749 **/ |
| 705 describe: function() { | 750 describe: function() { |
| 706 return 'SaveArguments(' + | 751 return 'SaveArguments(' + |
| 707 this.realMatcher_.describe.call(this.realMatcher_) + ')'; | 752 this.realMatcher_.describe.call(this.realMatcher_) + ')'; |
| 708 }, | 753 }, |
| 709 }; | 754 }; |
| 710 | 755 |
| 711 // Exports. | 756 // Exports. |
| 712 testing.Test = Test; | 757 testing.Test = Test; |
| 758 window.testDone = testDone; | |
| 713 window.assertTrue = assertTrue; | 759 window.assertTrue = assertTrue; |
| 714 window.assertFalse = assertFalse; | 760 window.assertFalse = assertFalse; |
| 715 window.assertGE = assertGE; | 761 window.assertGE = assertGE; |
| 716 window.assertGT = assertGT; | 762 window.assertGT = assertGT; |
| 717 window.assertEquals = assertEquals; | 763 window.assertEquals = assertEquals; |
| 718 window.assertLE = assertLE; | 764 window.assertLE = assertLE; |
| 719 window.assertLT = assertLT; | 765 window.assertLT = assertLT; |
| 720 window.assertNotEquals = assertNotEquals; | 766 window.assertNotEquals = assertNotEquals; |
| 721 window.assertNotReached = assertNotReached; | 767 window.assertNotReached = assertNotReached; |
| 722 window.callFunction = callFunction; | 768 window.callFunction = callFunction; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 735 window.runTest = runTest; | 781 window.runTest = runTest; |
| 736 window.runTestFunction = runTestFunction; | 782 window.runTestFunction = runTestFunction; |
| 737 window.SaveArgumentsMatcher = SaveArgumentsMatcher; | 783 window.SaveArgumentsMatcher = SaveArgumentsMatcher; |
| 738 window.TEST = TEST; | 784 window.TEST = TEST; |
| 739 window.TEST_F = TEST_F; | 785 window.TEST_F = TEST_F; |
| 740 window.GEN = GEN; | 786 window.GEN = GEN; |
| 741 | 787 |
| 742 // Import the Mock4JS helpers. | 788 // Import the Mock4JS helpers. |
| 743 Mock4JS.addMockSupport(window); | 789 Mock4JS.addMockSupport(window); |
| 744 })(); | 790 })(); |
| OLD | NEW |