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 (function(window) { |
| 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 | |
| 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 | |
| 32 (function() { | |
| 33 // Provide global objects for generation case. | |
| 34 if (this['window'] === undefined) | |
| 35 this['window'] = this; | |
| 36 if (this['chrome'] === undefined) { | |
| 37 this['chrome'] = { | |
| 38 send: function() {}, | |
| 39 }; | |
| 40 } | |
| 41 if (this['console'] === undefined) { | |
| 42 this['console'] = { | |
| 43 log: print, | |
| 44 }; | |
| 45 } | |
| 46 | 20 |
| 47 /** | 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 | |
| 32 /** | |
| 48 * This class will be exported as testing.Test, and is provided to hold the | 33 * This class will be exported as testing.Test, and is provided to hold the |
| 49 * fixture's configuration and callback methods for the various phases of | 34 * fixture's configuration and callback methods for the various phases of |
| 50 * invoking a test. It is called "Test" rather than TestFixture to roughly | 35 * invoking a test. It is called "Test" rather than TestFixture to roughly |
| 51 * mimic the gtest's class names. | 36 * mimic the gtest's class names. |
| 52 * @constructor | 37 * @constructor |
| 53 **/ | 38 */ |
| 54 function Test() {} | 39 function Test() {} |
| 55 | 40 |
| 56 Test.prototype = { | 41 Test.prototype = { |
| 57 /** | 42 /** |
| 58 * The name of the test. | 43 * The name of the test. |
| 59 **/ | 44 */ |
| 60 name: null, | 45 name: null, |
| 61 | 46 |
| 62 /** | 47 /** |
| 63 * When set to a string value representing a url, generate BrowsePreload | 48 * When set to a string value representing a url, generate BrowsePreload |
| 64 * call, which will browse to the url and call fixture.PreLoad of the | 49 * call, which will browse to the url and call fixture.preLoad of the |
| 65 * currentTestCase. | 50 * currentTestCase. |
| 66 * @type {string} | 51 * @type {string} |
| 67 **/ | 52 */ |
| 68 browsePreload: null, | 53 browsePreload: null, |
| 69 | 54 |
| 70 /** | 55 /** |
| 71 * When set to a string value representing an html page in the test | 56 * When set to a string value representing an html page in the test |
| 72 * directory, generate BrowsePrintPreload call, which will browse to a url | 57 * directory, generate BrowsePrintPreload call, which will browse to a url |
| 73 * representing the file, cause print, and call fixture.PreLoad of the | 58 * representing the file, cause print, and call fixture.preLoad of the |
| 74 * currentTestCase. | 59 * currentTestCase. |
| 75 * @type {string} | 60 * @type {string} |
| 76 **/ | 61 */ |
| 77 browsePrintPreload: null, | 62 browsePrintPreload: null, |
| 78 | 63 |
| 79 /** | 64 /** |
| 80 * When set to a function, will be called in the context of the test | 65 * When set to a function, will be called in the context of the test |
| 81 * generation inside the function, and before any generated C++. | 66 * generation inside the function, and before any generated C++. |
| 82 * @type {function(string,string)} | 67 * @type {function(string,string)} |
| 83 **/ | 68 */ |
| 84 testGenPreamble: null, | 69 testGenPreamble: null, |
| 85 | 70 |
| 86 /** | 71 /** |
| 87 * When set to a function, will be called in the context of the test | 72 * When set to a function, will be called in the context of the test |
| 88 * generation inside the function, and after any generated C++. | 73 * generation inside the function, and after any generated C++. |
| 89 * @type {function(string,string)} | 74 * @type {function(string,string)} |
| 90 **/ | 75 */ |
| 91 testGenPostamble: null, | 76 testGenPostamble: null, |
| 92 | 77 |
| 93 /** | 78 /** |
| 94 * When set to a non-null string, auto-generate typedef before generating | 79 * When set to a non-null string, auto-generate typedef before generating |
| 95 * TEST*: {@code typedef typedefCppFixture testFixture}. | 80 * TEST*: {@code typedef typedefCppFixture testFixture}. |
| 96 * @type {string} | 81 * @type {string} |
| 97 **/ | 82 */ |
| 98 typedefCppFixture: 'WebUIBrowserTest', | 83 typedefCppFixture: 'WebUIBrowserTest', |
| 99 | 84 |
| 100 /** | 85 /** |
| 101 * This should be initialized by the test fixture and can be referenced | 86 * This should be initialized by the test fixture and can be referenced |
| 102 * during the test run. | 87 * during the test run. It holds any mocked handler methods. |
| 103 * @type {Mock4JS.Mock} | 88 * @type {?Mock4JS.Mock} |
| 104 **/ | 89 */ |
| 105 mockHandler: null, | 90 mockHandler: null, |
| 106 | 91 |
| 107 /** | 92 /** |
| 93 * This should be initialized by the test fixture and can be referenced | |
| 94 * during the test run. It holds any mocked global functions. | |
| 95 * @type {?Mock4JS.Mock} | |
| 96 */ | |
| 97 mockGlobals: null, | |
| 98 | |
| 99 /** | |
| 100 * Value is passed through call to C++ RunJavascriptF to invoke this test. | |
| 101 * @type {boolean} | |
| 102 */ | |
| 103 isAsync: false, | |
| 104 | |
| 105 /** | |
| 108 * Override this method to perform initialization during preload (such as | 106 * Override this method to perform initialization during preload (such as |
| 109 * creating mocks and registering handlers). | 107 * creating mocks and registering handlers). |
| 110 * @type {Function} | 108 * @type {Function} |
| 111 **/ | 109 */ |
| 112 PreLoad: function() {}, | 110 preLoad: function() {}, |
| 113 | 111 |
| 114 /** | 112 /** |
| 115 * Override this method to perform tasks before running your test. | 113 * Override this method to perform tasks before running your test. |
| 116 * @type {Function} | 114 * @type {Function} |
| 117 **/ | 115 */ |
| 118 SetUp: function() {}, | 116 setUp: function() {}, |
| 119 | 117 |
| 120 /** | 118 /** |
| 121 * Override this method to perform tasks after running your test. If you | 119 * Override this method to perform tasks after running your test. If you |
| 122 * create a mock class, you must call Mock4JS.verifyAllMocks() in this | 120 * create a mock class, you must call Mock4JS.verifyAllMocks() in this |
| 123 * phase. | 121 * phase. |
| 124 * @type {Function} | 122 * @type {Function} |
| 125 **/ | 123 */ |
| 126 TearDown: function() { | 124 tearDown: function() { |
| 127 Mock4JS.verifyAllMocks(); | 125 Mock4JS.verifyAllMocks(); |
| 128 } | 126 }, |
| 127 | |
| 128 /** | |
| 129 * Called to run the body from the perspective of this fixture. | |
| 130 * @type {Function} | |
| 131 */ | |
| 132 runTest: function(testBody) { | |
| 133 testBody.call(this); | |
| 134 }, | |
| 135 | |
| 136 /** | |
| 137 * Create a closure function for continuing the test at a later time. May be | |
| 138 * used as a listener function. | |
| 139 * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate | |
| 140 * time. | |
| 141 * @param {Function} completion The function to call to complete the test. | |
| 142 * @param {...*} var_args Arguments to pass when calling completionAction. | |
| 143 * @return {function(): void} Return a function, bound to this test fixture, | |
| 144 * which continues the test. | |
| 145 */ | |
| 146 continueTest: function(whenTestDone, completion) { | |
| 147 var savedArgs = new SaveMockArguments(); | |
| 148 var completionAction = new CallFunctionAction( | |
| 149 this, savedArgs, completion, | |
| 150 Array.prototype.slice.call(arguments, 2)); | |
| 151 if (whenTestDone === WhenTestDone.DEFAULT) | |
| 152 whenTestDone = WhenTestDone.ASSERT; | |
| 153 var runAll = new RunAllAction( | |
| 154 true, whenTestDone, [completionAction]); | |
| 155 return function() { | |
| 156 savedArgs.arguments = Array.prototype.slice.call(arguments); | |
| 157 runAll.invoke(); | |
| 158 }; | |
| 159 }, | |
| 160 | |
| 161 /** | |
| 162 * Call this during setUp to defer the call to runTest() until later. The | |
| 163 * caller must call the returned function at some point to run the test. | |
| 164 * @type {Function} | |
| 165 * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate | |
| 166 * time. | |
| 167 * @param {...*} var_args Arguments to pass when running the | |
| 168 * |currentTestCase|. | |
| 169 * @return {function(): void} A function which will run the current body of | |
| 170 * the currentTestCase. | |
| 171 */ | |
| 172 deferRunTest: function(whenTestDone) { | |
| 173 if (whenTestDone === WhenTestDone.DEFAULT) | |
| 174 whenTestDone = WhenTestDone.ALWAYS; | |
| 175 | |
| 176 return currentTestCase.deferRunTest.apply( | |
| 177 currentTestCase, [whenTestDone].concat( | |
| 178 Array.prototype.slice.call(arguments, 1))); | |
| 179 }, | |
| 129 }; | 180 }; |
| 130 | 181 |
| 131 /** | 182 /** |
| 132 * This class is not exported and is available to hold the state of the | 183 * This class is not exported and is available to hold the state of the |
| 133 * |currentTestCase| throughout preload and test run. | 184 * |currentTestCase| throughout preload and test run. |
| 134 * @param {string} name The name of the test case. | 185 * @param {string} name The name of the test case. |
| 135 * @param {Test} fixture The fixture object for this test case. | 186 * @param {Test} fixture The fixture object for this test case. |
| 136 * @param {Function} body The code to run for the test. | 187 * @param {Function} body The code to run for the test. |
| 137 * @constructor | 188 * @constructor |
| 138 **/ | 189 */ |
| 139 function TestCase(name, fixture, body) { | 190 function TestCase(name, fixture, body) { |
| 140 this.name = name; | 191 this.name = name; |
| 141 this.fixture = fixture; | 192 this.fixture = fixture; |
| 142 this.body = body; | 193 this.body = body; |
| 143 } | 194 } |
| 144 | 195 |
| 145 TestCase.prototype = { | 196 TestCase.prototype = { |
| 197 /** | |
| 198 * The name of this test. | |
| 199 * @type {string} | |
| 200 */ | |
| 146 name: null, | 201 name: null, |
| 202 | |
| 203 /** | |
| 204 * The test fixture to set |this| to when running the test |body|. | |
| 205 * @type {testing.Test} | |
| 206 */ | |
| 147 fixture: null, | 207 fixture: null, |
| 208 | |
| 209 /** | |
| 210 * The test body to execute in runTest(). | |
| 211 * @type {Function} | |
| 212 */ | |
| 148 body: null, | 213 body: null, |
| 149 | 214 |
| 150 /** | 215 /** |
| 216 * True when the test fixture will run the test later. | |
| 217 * @type {boolean} | |
| 218 * @private | |
| 219 */ | |
| 220 deferred_: false, | |
| 221 | |
| 222 /** | |
| 151 * Called at preload time, proxies to the fixture. | 223 * Called at preload time, proxies to the fixture. |
| 152 * @type {Function} | 224 * @type {Function} |
| 153 **/ | 225 */ |
| 154 PreLoad: function(name) { | 226 preLoad: function(name) { |
| 155 if (this.fixture) | 227 if (this.fixture) |
| 156 this.fixture.PreLoad(); | 228 this.fixture.preLoad(); |
| 157 }, | 229 }, |
| 158 | 230 |
| 159 /** | 231 /** |
| 232 * Called before a test runs. | |
| 233 */ | |
| 234 setUp: function() { | |
| 235 if (this.fixture) | |
| 236 this.fixture.setUp(); | |
| 237 }, | |
| 238 | |
| 239 /** | |
| 240 * Called before a test is torn down (by testDone()). | |
| 241 */ | |
| 242 tearDown: function() { | |
| 243 if (this.fixture) | |
| 244 this.fixture.tearDown(); | |
| 245 }, | |
| 246 | |
| 247 /** | |
| 248 * Called to run this test's body. | |
| 249 */ | |
| 250 runTest: function() { | |
| 251 if (this.body && this.fixture) | |
| 252 this.fixture.runTest(this.body); | |
| 253 }, | |
| 254 | |
| 255 /** | |
| 160 * Runs this test case with |this| set to the |fixture|. | 256 * Runs this test case with |this| set to the |fixture|. |
| 161 * | 257 * |
| 162 * Note: Tests created with TEST_F may depend upon |this| being set to an | 258 * Note: Tests created with TEST_F may depend upon |this| being set to an |
| 163 * instance of this.fixture. The current implementation of TEST creates a | 259 * instance of this.fixture. The current implementation of TEST creates a |
| 164 * dummy constructor, but tests created with TEST should not rely on |this| | 260 * dummy constructor, but tests created with TEST should not rely on |this| |
| 165 * being set. | 261 * being set. |
| 166 * @type {Function} | 262 * @type {Function} |
| 167 **/ | 263 */ |
| 168 Run: function() { | 264 run: function() { |
| 169 if (this.fixture) | 265 try { |
| 170 this.fixture.SetUp(); | 266 this.setUp(); |
| 171 if (this.body) | 267 } catch(e) { |
| 172 this.body.call(this.fixture); | 268 console.error(e.stack); |
| 173 if (this.fixture) | 269 } |
| 174 this.fixture.TearDown(); | 270 |
| 271 if (!this.deferred_) | |
| 272 this.runTest(); | |
| 273 | |
| 274 // tearDown called by testDone(). | |
| 175 }, | 275 }, |
| 276 | |
| 277 /** | |
| 278 * Cause this TestCase to be deferred (don't call runTest()) until the | |
| 279 * returned function is called. | |
| 280 * @type {Function} | |
| 281 * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate | |
| 282 * time. | |
| 283 * @param {...*} var_args Arguments to pass when running the | |
| 284 * |currentTestCase|. | |
| 285 * @return {function(): void} A function thatwill run this TestCase when | |
| 286 * called. | |
| 287 */ | |
| 288 deferRunTest: function(whenTestDone) { | |
| 289 this.deferred_ = true; | |
| 290 var savedArgs = new SaveMockArguments(); | |
| 291 var completionAction = new CallFunctionAction( | |
| 292 this, savedArgs, this.runTest, | |
| 293 Array.prototype.slice.call(arguments, 1)); | |
| 294 var runAll = new RunAllAction( | |
| 295 true, whenTestDone, [completionAction]); | |
| 296 return function() { | |
| 297 savedArgs.arguments = Array.prototype.slice.call(arguments); | |
| 298 runAll.invoke(); | |
| 299 }; | |
| 300 }, | |
| 301 | |
| 176 }; | 302 }; |
| 177 | 303 |
| 178 /** | 304 /** |
| 179 * Registry of javascript-defined callbacks for {@code chrome.send}. | 305 * Registry of javascript-defined callbacks for {@code chrome.send}. |
| 180 * @type {Object} | 306 * @type {Object} |
| 181 **/ | 307 */ |
| 182 var sendCallbacks = {}; | 308 var sendCallbacks = {}; |
| 183 | 309 |
| 184 /** | 310 /** |
| 185 * Registers the message, object and callback for {@code chrome.send} | 311 * Registers the message, object and callback for {@code chrome.send} |
| 186 * @param {string} name The name of the message to route to this |callback|. | 312 * @param {string} name The name of the message to route to this |callback|. |
| 187 * @param {Object} messageHAndler Pass as |this| when calling the |callback|. | 313 * @param {Object} messageHandler Pass as |this| when calling the |callback|. |
| 188 * @param {function(...)} callback Called by {@code chrome.send}. | 314 * @param {function(...)} callback Called by {@code chrome.send}. |
| 189 * @see sendCallbacks | 315 * @see sendCallbacks |
| 190 **/ | 316 */ |
| 191 function registerMessageCallback(name, messageHandler, callback) { | 317 function registerMessageCallback(name, messageHandler, callback) { |
| 192 sendCallbacks[name] = [messageHandler, callback]; | 318 sendCallbacks[name] = [messageHandler, callback]; |
| 193 } | 319 } |
| 194 | 320 |
| 195 /** | 321 /** |
| 196 * Register all methods of {@code mockClass.prototype} with messages of the | 322 * Register all methods of {@code mockClass.prototype} with messages of the |
| 197 * same name as the method, using the proxy of the |mockObject| as the | 323 * same name as the method, using the proxy of the |mockObject| as the |
| 198 * |messageHandler| when registering. | 324 * |messageHandler| when registering. |
| 199 * @param {Mock4JS.Mock} mockObject The mock to register callbacks against. | 325 * @param {Mock4JS.Mock} mockObject The mock to register callbacks against. |
| 200 * @param {function(new:Object)} mockClAss Constructor for the mocked class. | 326 * @param {function(new:Object)} mockClAss Constructor for the mocked class. |
| 201 * @see registerMessageCallback | 327 * @see registerMessageCallback |
| 202 **/ | 328 */ |
| 203 function registerMockMessageCallbacks(mockObject, mockClass) { | 329 function registerMockMessageCallbacks(mockObject, mockClass) { |
| 204 var mockProxy = mockObject.proxy(); | 330 var mockProxy = mockObject.proxy(); |
| 205 for (func in mockClass.prototype) { | 331 for (var func in mockClass.prototype) { |
| 206 if (typeof(mockClass.prototype[func]) == 'function') { | 332 if (typeof mockClass.prototype[func] == 'function') { |
| 207 registerMessageCallback(func, | 333 registerMessageCallback(func, mockProxy, mockProxy[func]); |
| 208 mockProxy, | |
| 209 mockProxy[func]); | |
| 210 } | 334 } |
| 211 } | 335 } |
| 212 } | 336 } |
| 337 | |
| 338 /** | |
| 339 * Holds the mapping of name -> global override information. | |
| 340 * @type {Object} | |
| 341 */ | |
| 342 var globalOverrides = {}; | |
| 343 | |
| 344 /** | |
| 345 * Registers the global function name, object and callback. | |
|
mmenke
2011/08/24 15:27:50
Important: Add a comment that this can only be ca
Sheridan Rawlins
2011/08/24 21:15:45
How 'bout this instead - I made it possible to moc
mmenke
2011/08/24 21:33:30
Sounds like a better idea to me.
| |
| 346 * @param {string} name The name of the message to route to this |callback|. | |
| 347 * @param {Object} object Pass as |this| when calling the |callback|. | |
| 348 * @param {function(...)} callback Called by {@code chrome.send}. | |
| 349 */ | |
| 350 function registerMockGlobal(name, object, callback) { | |
| 351 assertEquals(undefined, globalOverrides[name]); | |
| 352 globalOverrides[name] = { | |
| 353 object: object, | |
| 354 callback: callback, | |
| 355 }; | |
| 356 } | |
| 357 | |
| 358 /** | |
| 359 * Register all methods of {@code mockClass.prototype} as overrides to global | |
| 360 * functions of the same name as the method, using the proxy of the | |
| 361 * |mockObject| to handle the functions. | |
| 362 * @param {Mock4JS.Mock} mockObject The mock to register callbacks against. | |
| 363 * @param {function(new:Object)} mockClAss Constructor for the mocked class. | |
| 364 * @see registerMessageCallback | |
| 365 */ | |
| 366 function registerMockGlobals(mockObject, mockClass) { | |
| 367 var mockProxy = mockObject.proxy(); | |
| 368 for (var func in mockClass.prototype) { | |
| 369 if (typeof(mockClass.prototype[func]) == 'function') { | |
| 370 registerMockGlobal(func, mockProxy, mockProxy[func]); | |
| 371 } | |
| 372 } | |
| 373 } | |
| 213 | 374 |
| 214 /** | 375 /** |
| 215 * Overrides {@code chrome.send} for routing messages to javascript | 376 * Overrides {@code chrome.send} for routing messages to javascript |
| 216 * functions. Also falls back to sending with the original chrome object. | 377 * functions. Also falls back to sending with the original chrome object. |
| 217 * @param {string} messageName The message to route. | 378 * @param {string} messageName The message to route. |
| 218 **/ | 379 */ |
| 219 function send(messageName) { | 380 function send(messageName) { |
| 220 var callback = sendCallbacks[messageName]; | 381 var callback = sendCallbacks[messageName]; |
| 221 if (callback != undefined) | 382 if (callback != undefined) |
| 222 callback[1].apply(callback[0], Array.prototype.slice.call(arguments, 1)); | 383 callback[1].apply(callback[0], arguments[1]); |
| 223 else | 384 else |
| 224 this.__proto__.send.apply(this.__proto__, arguments); | 385 this.__proto__.send.apply(this.__proto__, arguments); |
| 225 } | 386 } |
| 226 | 387 |
| 227 /** | 388 /** |
| 228 * Provides a mechanism for assert* and expect* methods to fetch the signature | 389 * Provides a mechanism for assert* and expect* methods to fetch the signature |
| 229 * of their caller. Assert* methods should |registerCall| and expect* methods | 390 * of their caller. Assert* methods should |registerCall| and expect* methods |
| 230 * should set |isExpect| and |expectName| properties to indicate that the | 391 * should set |isExpect| and |expectName| properties to indicate that the |
| 231 * interesting caller is one more level up the stack. | 392 * interesting caller is one more level up the stack. |
| 232 **/ | 393 */ |
| 233 function CallHelper() { | 394 function CallHelper() { |
| 234 this.__proto__ = CallHelper.prototype; | 395 this.__proto__ = CallHelper.prototype; |
| 235 } | 396 } |
| 236 | 397 |
| 237 CallHelper.prototype = { | 398 CallHelper.prototype = { |
| 238 /** | 399 /** |
| 239 * Holds the mapping of (callerCallerString, callerName) -> count of times | 400 * Holds the mapping of (callerCallerString, callerName) -> count of times |
| 240 * called. | 401 * called. |
| 241 * @type {Object.<string, Object.<string, number>>} | 402 * @type {Object.<string, Object.<string, number>>} |
| 242 **/ | 403 */ |
| 243 counts_: {}, | 404 counts_: {}, |
| 244 | 405 |
| 245 /** | 406 /** |
| 246 * This information about the caller is needed from most of the following | 407 * This information about the caller is needed from most of the following |
| 247 * routines. | 408 * routines. |
| 248 * @param {Function} caller the caller of the assert* routine. | 409 * @param {Function} caller the caller of the assert* routine. |
| 249 * @return {{callerName: string, callercallerString: string}} stackInfo | 410 * @return {{callerName: string, callercallerString: string}} stackInfo |
| 250 * @private | 411 * @private |
| 251 **/ | 412 */ |
| 252 getCallerInfo_: function(caller) { | 413 getCallerInfo_: function(caller) { |
| 253 var callerName = caller.name; | 414 var callerName = caller.name; |
| 254 var callerCaller = caller.caller; | 415 var callerCaller = caller.caller; |
| 255 if (callerCaller['isExpect']) { | 416 if (callerCaller['isExpect']) { |
| 256 callerName = callerCaller.expectName; | 417 callerName = callerCaller.expectName; |
| 257 callerCaller = callerCaller.caller; | 418 callerCaller = callerCaller.caller; |
| 258 } | 419 } |
| 259 var callerCallerString = callerCaller.toString(); | 420 var callerCallerString = callerCaller.toString(); |
| 260 return { | 421 return { |
| 261 callerName: callerName, | 422 callerName: callerName, |
| 262 callerCallerString: callerCallerString, | 423 callerCallerString: callerCallerString, |
| 263 }; | 424 }; |
| 264 }, | 425 }, |
| 265 | 426 |
| 266 /** | 427 /** |
| 267 * Register a call to an assertion class. | 428 * Register a call to an assertion class. |
| 268 **/ | 429 */ |
| 269 registerCall: function() { | 430 registerCall: function() { |
| 270 var stackInfo = this.getCallerInfo_(arguments.callee.caller); | 431 var stackInfo = this.getCallerInfo_(arguments.callee.caller); |
| 271 if (!(stackInfo.callerCallerString in this.counts_)) | 432 if (!(stackInfo.callerCallerString in this.counts_)) |
| 272 this.counts_[stackInfo.callerCallerString] = {}; | 433 this.counts_[stackInfo.callerCallerString] = {}; |
| 273 if (!(stackInfo.callerName in this.counts_[stackInfo.callerCallerString])) | 434 if (!(stackInfo.callerName in this.counts_[stackInfo.callerCallerString])) |
| 274 this.counts_[stackInfo.callerCallerString][stackInfo.callerName] = 0; | 435 this.counts_[stackInfo.callerCallerString][stackInfo.callerName] = 0; |
| 275 ++this.counts_[stackInfo.callerCallerString][stackInfo.callerName]; | 436 ++this.counts_[stackInfo.callerCallerString][stackInfo.callerName]; |
| 276 }, | 437 }, |
| 277 | 438 |
| 278 /** | 439 /** |
| 279 * Get the call signature of this instance of the caller's call to this | 440 * Get the call signature of this instance of the caller's call to this |
| 280 * function. | 441 * function. |
| 281 * @param {Function} caller The caller of the assert* routine. | 442 * @param {Function} caller The caller of the assert* routine. |
| 282 * @return {String} Call signature. | 443 * @return {String} Call signature. |
| 283 * @private | 444 * @private |
| 284 **/ | 445 */ |
| 285 getCall_: function(caller) { | 446 getCall_: function(caller) { |
| 286 var stackInfo = this.getCallerInfo_(caller); | 447 var stackInfo = this.getCallerInfo_(caller); |
| 287 var count = | 448 var count = |
| 288 this.counts_[stackInfo.callerCallerString][stackInfo.callerName]; | 449 this.counts_[stackInfo.callerCallerString][stackInfo.callerName]; |
| 289 | 450 |
| 290 // Allow pattern to match multiple lines for text wrapping. | 451 // Allow pattern to match multiple lines for text wrapping. |
| 291 var callerRegExp = | 452 var callerRegExp = |
| 292 new RegExp(stackInfo.callerName + '\\((.|\\n)*?\\);', 'g'); | 453 new RegExp(stackInfo.callerName + '\\((.|\\n)*?\\);', 'g'); |
| 293 | 454 |
| 294 // Find all matches allowing wrap around such as when a helper function | 455 // Find all matches allowing wrap around such as when a helper function |
| 295 // calls assert/expect calls and that helper function is called multiple | 456 // calls assert/expect calls and that helper function is called multiple |
| 296 // times. | 457 // times. |
| 297 var matches = stackInfo.callerCallerString.match(callerRegExp); | 458 var matches = stackInfo.callerCallerString.match(callerRegExp); |
| 298 var match = matches[(count - 1) % matches.length]; | 459 var match = matches[(count - 1) % matches.length]; |
| 299 | 460 |
| 300 // Chop off the trailing ';'. | 461 // Chop off the trailing ';'. |
| 301 return match.substring(0, match.length-1); | 462 return match.substring(0, match.length-1); |
| 302 }, | 463 }, |
| 303 | 464 |
| 304 /** | 465 /** |
| 305 * Returns the text of the call signature and any |message|. | 466 * Returns the text of the call signature and any |message|. |
| 306 * @param {string=} message Addtional message text from caller. | 467 * @param {string=} message Addtional message text from caller. |
| 307 **/ | 468 */ |
| 308 getCallMessage: function(message) { | 469 getCallMessage: function(message) { |
| 309 var callMessage = this.getCall_(arguments.callee.caller); | 470 var callMessage = this.getCall_(arguments.callee.caller); |
| 310 if (message) | 471 if (message) |
| 311 callMessage += ': ' + message; | 472 callMessage += ': ' + message; |
| 312 return callMessage; | 473 return callMessage; |
| 313 }, | 474 }, |
| 314 }; | 475 }; |
| 315 | 476 |
| 316 /** | 477 /** |
| 317 * Help register calls for better error reporting. | 478 * Help register calls for better error reporting. |
| 318 * @type {CallHelper} | 479 * @type {CallHelper} |
| 319 **/ | 480 */ |
| 320 var helper = new CallHelper(); | 481 var helper = new CallHelper(); |
| 321 | 482 |
| 322 /** | 483 /** |
| 323 * true when testDone has been called. | 484 * true when testDone has been called. |
| 324 * @type {boolean} | 485 * @type {boolean} |
| 325 */ | 486 */ |
| 326 var testIsDone = false; | 487 var testIsDone = false; |
| 327 | 488 |
| 328 /** | 489 /** |
| 329 * Holds the errors, if any, caught by expects so that the test case can | 490 * Holds the errors, if any, caught by expects so that the test case can |
| 330 * fail. Cleared when results are reported from runTest() or testDone(). | 491 * fail. Cleared when results are reported from runTest() or testDone(). |
| 331 * @type {Array.<Error>} | 492 * @type {Array.<Error>} |
| 332 **/ | 493 */ |
| 333 var errors = []; | 494 var errors = []; |
| 334 | 495 |
| 335 /** | 496 /** |
| 497 * URL to dummy WebUI page for testing framework. | |
| 498 * @type {string} | |
| 499 */ | |
| 500 var DUMMY_URL = 'http://DummyURL'; | |
| 501 | |
| 502 /** | |
| 336 * Resets test state by clearing |errors| and |testIsDone| flags. | 503 * Resets test state by clearing |errors| and |testIsDone| flags. |
| 337 **/ | 504 */ |
| 338 function resetTestState() { | 505 function resetTestState() { |
| 339 errors.splice(0, errors.length); | 506 errors.splice(0, errors.length); |
| 340 testIsDone = false; | 507 testIsDone = false; |
| 341 } | 508 } |
| 342 | 509 |
| 343 /** | 510 /** |
| 344 * Notifies the running browser test of the test results. Clears |errors|. | 511 * Notifies the running browser test of the test results. Clears |errors|. |
| 345 * @param {Array.<boolean, string>=} result When passed, this is used for the | 512 * @param {Array.<boolean, string>=} result When passed, this is used for the |
| 346 * testResult message. | 513 * testResult message. |
| 347 **/ | 514 */ |
| 348 function testDone(result) { | 515 function testDone(result) { |
| 349 if (!testIsDone) { | 516 if (!testIsDone) { |
| 350 testIsDone = true; | 517 testIsDone = true; |
| 518 if (currentTestCase) { | |
| 519 currentTestCase.tearDown(); | |
| 520 currentTestCase = null; | |
| 521 } | |
| 351 chrome.send('testResult', result ? result : testResult()); | 522 chrome.send('testResult', result ? result : testResult()); |
| 352 errors.splice(0, errors.length); | 523 errors.splice(0, errors.length); |
| 353 } else { | 524 } else { |
| 354 console.warn('testIsDone already'); | 525 console.warn('testIsDone already'); |
| 355 } | 526 } |
| 356 } | 527 } |
| 357 | 528 |
| 358 /** | 529 /** |
| 359 * Returns [success, message] & clears |errors|. | 530 * Returns [success, message] & clears |errors|. |
| 360 * @return {Array.<boolean, string>} | 531 * @return {Array.<boolean, string>} |
| 361 **/ | 532 */ |
| 362 function testResult() { | 533 function testResult() { |
| 363 var result = [true, '']; | 534 var result = [true, '']; |
| 364 if (errors.length) { | 535 if (errors.length) { |
| 365 var message = ''; | 536 var message = ''; |
| 366 for (var i = 0; i < errors.length; ++i) { | 537 for (var i = 0; i < errors.length; ++i) { |
| 367 message += 'Failed: ' + currentTestFunction + '(' + | 538 message += 'Failed: ' + currentTestFunction + '(' + |
| 368 currentTestArguments.map(JSON.stringify) + | 539 currentTestArguments.map(JSON.stringify) + |
| 369 ')\n' + errors[i].stack; | 540 ')\n' + errors[i].stack; |
| 370 } | 541 } |
| 371 result = [false, message]; | 542 result = [false, message]; |
| 372 } | 543 } |
| 373 return result; | 544 return result; |
| 374 } | 545 } |
| 375 | 546 |
| 376 // Asserts. | 547 // Asserts. |
| 377 // Use the following assertions to verify a condition within a test. | 548 // Use the following assertions to verify a condition within a test. |
| 378 // If assertion fails, throw an Error with information pertinent to the test. | 549 // If assertion fails, throw an Error with information pertinent to the test. |
| 379 | 550 |
| 380 /** | 551 /** |
| 381 * When |test| !== true, aborts the current test. | 552 * When |test| !== true, aborts the current test. |
| 382 * @param {boolean} test The predicate to check against |expected|. | 553 * @param {boolean} test The predicate to check against |expected|. |
| 383 * @param {string=} message The message to include in the Error thrown. | 554 * @param {string=} message The message to include in the Error thrown. |
| 384 * @throws {Error} upon failure. | 555 * @throws {Error} upon failure. |
| 385 **/ | 556 */ |
| 386 function assertTrue(test, message) { | 557 function assertTrue(test, message) { |
| 387 helper.registerCall(); | 558 helper.registerCall(); |
| 388 if (test !== true) | 559 if (test !== true) |
| 389 throw new Error( | 560 throw new Error( |
| 390 'Test Error ' + helper.getCallMessage(message) + ': ' + test); | 561 'Test Error ' + helper.getCallMessage(message) + ': ' + test); |
| 391 } | 562 } |
| 392 | 563 |
| 393 /** | 564 /** |
| 394 * When |test| !== false, aborts the current test. | 565 * When |test| !== false, aborts the current test. |
| 395 * @param {boolean} test The predicate to check against |expected|. | 566 * @param {boolean} test The predicate to check against |expected|. |
| 396 * @param {string=} message The message to include in the Error thrown. | 567 * @param {string=} message The message to include in the Error thrown. |
| 397 * @throws {Error} upon failure. | 568 * @throws {Error} upon failure. |
| 398 **/ | 569 */ |
| 399 function assertFalse(test, message) { | 570 function assertFalse(test, message) { |
| 400 helper.registerCall(); | 571 helper.registerCall(); |
| 401 if (test !== false) | 572 if (test !== false) |
| 402 throw new Error( | 573 throw new Error( |
| 403 'Test Error ' + helper.getCallMessage(message) + ': ' + test); | 574 'Test Error ' + helper.getCallMessage(message) + ': ' + test); |
| 404 } | 575 } |
| 405 | 576 |
| 406 /** | 577 /** |
| 407 * When |val1| < |val2|, aborts the current test. | 578 * When |val1| < |val2|, aborts the current test. |
| 408 * @param {number} val1 The number expected to be >= |val2|. | 579 * @param {number} val1 The number expected to be >= |val2|. |
| 409 * @param {number} val2 The number expected to be < |val1|. | 580 * @param {number} val2 The number expected to be < |val1|. |
| 410 * @param {string=} message The message to include in the Error thrown. | 581 * @param {string=} message The message to include in the Error thrown. |
| 411 **/ | 582 */ |
| 412 function assertGE(val1, val2, message) { | 583 function assertGE(val1, val2, message) { |
| 413 helper.registerCall(); | 584 helper.registerCall(); |
| 414 if (val1 < val2) { | 585 if (val1 < val2) { |
| 415 throw new Error( | 586 throw new Error( |
| 416 'Test Error ' + helper.getCallMessage(message) + val1 + '<' + val2); | 587 'Test Error ' + helper.getCallMessage(message) + val1 + '<' + val2); |
| 417 } | 588 } |
| 418 } | 589 } |
| 419 | 590 |
| 420 /** | 591 /** |
| 421 * When |val1| <= |val2|, aborts the current test. | 592 * When |val1| <= |val2|, aborts the current test. |
| 422 * @param {number} val1 The number expected to be > |val2|. | 593 * @param {number} val1 The number expected to be > |val2|. |
| 423 * @param {number} val2 The number expected to be <= |val1|. | 594 * @param {number} val2 The number expected to be <= |val1|. |
| 424 * @param {string=} message The message to include in the Error thrown. | 595 * @param {string=} message The message to include in the Error thrown. |
| 425 **/ | 596 */ |
| 426 function assertGT(val1, val2, message) { | 597 function assertGT(val1, val2, message) { |
| 427 helper.registerCall(); | 598 helper.registerCall(); |
| 428 if (val1 <= val2) { | 599 if (val1 <= val2) { |
| 429 throw new Error( | 600 throw new Error( |
| 430 'Test Error ' + helper.getCallMessage(message) + val1 + '<=' + val2); | 601 'Test Error ' + helper.getCallMessage(message) + val1 + '<=' + val2); |
| 431 } | 602 } |
| 432 } | 603 } |
| 433 | 604 |
| 434 /** | 605 /** |
| 435 * When |expected| !== |actual|, aborts the current test. | 606 * When |expected| !== |actual|, aborts the current test. |
| 436 * @param {*} expected The expected value of |actual|. | 607 * @param {*} expected The expected value of |actual|. |
| 437 * @param {*} actual The predicate to check against |expected|. | 608 * @param {*} actual The predicate to check against |expected|. |
| 438 * @param {string=} message The message to include in the Error thrown. | 609 * @param {string=} message The message to include in the Error thrown. |
| 439 * @throws {Error} upon failure. | 610 * @throws {Error} upon failure. |
| 440 **/ | 611 */ |
| 441 function assertEquals(expected, actual, message) { | 612 function assertEquals(expected, actual, message) { |
| 442 helper.registerCall(); | 613 helper.registerCall(); |
| 443 if (expected != actual) { | 614 if (expected != actual) { |
| 444 throw new Error( | 615 throw new Error( |
| 445 'Test Error ' + helper.getCallMessage(message) + | 616 'Test Error ' + helper.getCallMessage(message) + |
| 446 '\nActual: ' + actual + '\nExpected: ' + expected); | 617 '\nActual: ' + actual + '\nExpected: ' + expected); |
| 447 } | 618 } |
| 448 if (typeof expected != typeof actual) { | 619 if (typeof expected != typeof actual) { |
| 449 throw new Error( | 620 throw new Error( |
| 450 'Test Error (type mismatch) ' + helper.getCallMessage(message) + | 621 'Test Error (type mismatch) ' + helper.getCallMessage(message) + |
| 451 '\nActual Type: ' + typeof actual + | 622 '\nActual Type: ' + typeof actual + |
| 452 '\nExpected Type:' + typeof expected); | 623 '\nExpected Type:' + typeof expected); |
| 453 } | 624 } |
| 454 } | 625 } |
| 455 | 626 |
| 456 /** | 627 /** |
| 457 * When |val1| > |val2|, aborts the current test. | 628 * When |val1| > |val2|, aborts the current test. |
| 458 * @param {number} val1 The number expected to be <= |val2|. | 629 * @param {number} val1 The number expected to be <= |val2|. |
| 459 * @param {number} val2 The number expected to be > |val1|. | 630 * @param {number} val2 The number expected to be > |val1|. |
| 460 * @param {string=} message The message to include in the Error thrown. | 631 * @param {string=} message The message to include in the Error thrown. |
| 461 **/ | 632 */ |
| 462 function assertLE(val1, val2, message) { | 633 function assertLE(val1, val2, message) { |
| 463 helper.registerCall(); | 634 helper.registerCall(); |
| 464 if (val1 > val2) { | 635 if (val1 > val2) { |
| 465 throw new Error( | 636 throw new Error( |
| 466 'Test Error ' + helper.getCallMessage(message) + val1 + '>' + val2); | 637 'Test Error ' + helper.getCallMessage(message) + val1 + '>' + val2); |
| 467 } | 638 } |
| 468 } | 639 } |
| 469 | 640 |
| 470 /** | 641 /** |
| 471 * When |val1| >= |val2|, aborts the current test. | 642 * When |val1| >= |val2|, aborts the current test. |
| 472 * @param {number} val1 The number expected to be < |val2|. | 643 * @param {number} val1 The number expected to be < |val2|. |
| 473 * @param {number} val2 The number expected to be >= |val1|. | 644 * @param {number} val2 The number expected to be >= |val1|. |
| 474 * @param {string=} message The message to include in the Error thrown. | 645 * @param {string=} message The message to include in the Error thrown. |
| 475 **/ | 646 */ |
| 476 function assertLT(val1, val2, message) { | 647 function assertLT(val1, val2, message) { |
| 477 helper.registerCall(); | 648 helper.registerCall(); |
| 478 if (val1 >= val2) { | 649 if (val1 >= val2) { |
| 479 throw new Error( | 650 throw new Error( |
| 480 'Test Error ' + helper.getCallMessage(message) + val1 + '>=' + val2); | 651 'Test Error ' + helper.getCallMessage(message) + val1 + '>=' + val2); |
| 481 } | 652 } |
| 482 } | 653 } |
| 483 | 654 |
| 484 /** | 655 /** |
| 485 * When |notExpected| === |actual|, aborts the current test. | 656 * When |notExpected| === |actual|, aborts the current test. |
| 486 * @param {*} notExpected The expected value of |actual|. | 657 * @param {*} notExpected The expected value of |actual|. |
| 487 * @param {*} actual The predicate to check against |notExpected|. | 658 * @param {*} actual The predicate to check against |notExpected|. |
| 488 * @param {string=} message The message to include in the Error thrown. | 659 * @param {string=} message The message to include in the Error thrown. |
| 489 * @throws {Error} upon failure. | 660 * @throws {Error} upon failure. |
| 490 **/ | 661 */ |
| 491 function assertNotEquals(notExpected, actual, message) { | 662 function assertNotEquals(notExpected, actual, message) { |
| 492 helper.registerCall(); | 663 helper.registerCall(); |
| 493 if (notExpected === actual) { | 664 if (notExpected === actual) { |
| 494 throw new Error( | 665 throw new Error( |
| 495 'Test Error ' + helper.getCallMessage(message) + | 666 'Test Error ' + helper.getCallMessage(message) + |
| 496 '\nActual: ' + actual + '\nnotExpected: ' + notExpected); | 667 '\nActual: ' + actual + '\nnotExpected: ' + notExpected); |
| 497 } | 668 } |
| 498 } | 669 } |
| 499 | 670 |
| 500 /** | 671 /** |
| 501 * Always aborts the current test. | 672 * Always aborts the current test. |
| 502 * @param {string=} message The message to include in the Error thrown. | 673 * @param {string=} message The message to include in the Error thrown. |
| 503 * @throws {Error} always. | 674 * @throws {Error} always. |
| 504 **/ | 675 */ |
| 505 function assertNotReached(message) { | 676 function assertNotReached(message) { |
| 506 helper.registerCall(); | 677 helper.registerCall(); |
| 507 throw new Error(helper.getCallMessage(message)); | 678 throw new Error(helper.getCallMessage(message)); |
| 508 } | 679 } |
| 509 | 680 |
| 510 /** | 681 /** |
| 511 * Creates a function based upon a function that thows an exception on | 682 * Creates a function based upon a function that thows an exception on |
| 512 * failure. The new function stuffs any errors into the |errors| array for | 683 * failure. The new function stuffs any errors into the |errors| array for |
| 513 * checking by runTest. This allows tests to continue running other checks, | 684 * checking by runTest. This allows tests to continue running other checks, |
| 514 * while failing the overall test if any errors occurrred. | 685 * while failing the overall test if any errors occurrred. |
| 515 * @param {Function} assertFunc The function which may throw an Error. | 686 * @param {Function} assertFunc The function which may throw an Error. |
| 516 * @return {Function} A function that applies its arguments to |assertFunc|. | 687 * @return {Function} A function that applies its arguments to |assertFunc|. |
| 517 * @see errors | 688 * @see errors |
| 518 * @see runTest | 689 * @see runTest |
| 519 **/ | 690 */ |
| 520 function createExpect(assertFunc) { | 691 function createExpect(assertFunc) { |
| 521 var expectFunc = function() { | 692 var expectFunc = function() { |
| 522 try { | 693 try { |
| 523 assertFunc.apply(null, arguments); | 694 assertFunc.apply(null, arguments); |
| 524 } catch (e) { | 695 } catch (e) { |
| 525 errors.push(e); | 696 errors.push(e); |
| 526 } | 697 } |
| 527 }; | 698 }; |
| 528 expectFunc.isExpect = true; | 699 expectFunc.isExpect = true; |
| 529 expectFunc.expectName = assertFunc.name.replace(/^assert/, 'expect'); | 700 expectFunc.expectName = assertFunc.name.replace(/^assert/, 'expect'); |
| 530 return expectFunc; | 701 return expectFunc; |
| 531 } | 702 } |
| 532 | 703 |
| 533 /** | 704 /** |
| 534 * This is the starting point for tests run by WebUIBrowserTest. If an error | 705 * This is the starting point for tests run by WebUIBrowserTest. If an error |
| 535 * occurs, it reports a failure and a message created by joining individual | 706 * occurs, it reports a failure and a message created by joining individual |
| 536 * error messages. This supports sync tests and async tests by calling | 707 * error messages. This supports sync tests and async tests by calling |
| 537 * testDone() when |isAsync| is not true, relying on async tests to call | 708 * testDone() when |isAsync| is not true, relying on async tests to call |
| 538 * testDone() when they complete. | 709 * testDone() when they complete. |
| 539 * @param {boolean} isAsync When false, call testDone() with the test result. | 710 * @param {boolean} isAsync When false, call testDone() with the test result. |
| 540 * @param {string} testFunction The function name to call. | 711 * @param {string} testFunction The function name to call. |
| 541 * @param {Array} testArguments The arguments to call |testFunction| with. | 712 * @param {Array} testArguments The arguments to call |testFunction| with. |
| 542 * @return {boolean} true always to signal successful execution (but not | 713 * @return {boolean} true always to signal successful execution (but not |
| 543 * necessarily successful results) of this test. | 714 * necessarily successful results) of this test. |
| 544 * @see errors | 715 * @see errors |
| 545 * @see runTestFunction | 716 * @see runTestFunction |
| 546 **/ | 717 */ |
| 547 function runTest(isAsync, testFunction, testArguments) { | 718 function runTest(isAsync, testFunction, testArguments) { |
| 548 // Avoid eval() if at all possible, since it will not work on pages | 719 // Avoid eval() if at all possible, since it will not work on pages |
| 549 // that have enabled content-security-policy. | 720 // that have enabled content-security-policy. |
| 550 var testBody = this[testFunction]; // global object -- not a method. | 721 var testBody = this[testFunction]; // global object -- not a method. |
| 551 var testName = testFunction; | 722 var testName = testFunction; |
| 552 if (typeof testBody === "undefined") { | 723 if (typeof testBody === "undefined") { |
| 553 testBody = eval(testFunction); | 724 testBody = eval(testFunction); |
| 554 testName = testBody.toString(); | 725 testName = testBody.toString(); |
| 555 } | 726 } |
| 556 if (testBody != RUN_TEST_F) { | 727 if (testBody != RUN_TEST_F) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 567 * expect to catch Errors. If |errors| is non-empty, it reports a failure and | 738 * expect to catch Errors. If |errors| is non-empty, it reports a failure and |
| 568 * a message by joining |errors|. Consumers can use this to use assert/expect | 739 * a message by joining |errors|. Consumers can use this to use assert/expect |
| 569 * functions asynchronously, but are then responsible for reporting errors to | 740 * functions asynchronously, but are then responsible for reporting errors to |
| 570 * the browser themselves through testDone(). | 741 * the browser themselves through testDone(). |
| 571 * @param {string} testFunction The function name to report on failure. | 742 * @param {string} testFunction The function name to report on failure. |
| 572 * @param {Function} testBody The function to call. | 743 * @param {Function} testBody The function to call. |
| 573 * @param {Array} testArguments The arguments to call |testBody| with. | 744 * @param {Array} testArguments The arguments to call |testBody| with. |
| 574 * @return {Array.<boolean, string>} [test-succeeded, message-if-failed] | 745 * @return {Array.<boolean, string>} [test-succeeded, message-if-failed] |
| 575 * @see createExpect | 746 * @see createExpect |
| 576 * @see testDone | 747 * @see testDone |
| 577 **/ | 748 */ |
| 578 function runTestFunction(testFunction, testBody, testArguments) { | 749 function runTestFunction(testFunction, testBody, testArguments) { |
| 579 currentTestFunction = testFunction; | 750 currentTestFunction = testFunction; |
| 580 currentTestArguments = testArguments; | 751 currentTestArguments = testArguments; |
| 581 createExpect(testBody).apply(null, testArguments); | 752 createExpect(testBody).apply(null, testArguments); |
| 582 return testResult(); | 753 return testResult(); |
| 583 } | 754 } |
| 584 | 755 |
| 585 /** | 756 /** |
| 586 * Creates a new test case for the given |testFixture| and |testName|. Assumes | 757 * Creates a new test case for the given |testFixture| and |testName|. Assumes |
| 587 * |testFixture| describes a globally available subclass of type Test. | 758 * |testFixture| describes a globally available subclass of type Test. |
| 588 * @param {string} testFixture The fixture for this test case. | 759 * @param {string} testFixture The fixture for this test case. |
| 589 * @param {string} testName The name for this test case. | 760 * @param {string} testName The name for this test case. |
| 590 * @return {TestCase} A newly created TestCase. | 761 * @return {TestCase} A newly created TestCase. |
| 591 **/ | 762 */ |
| 592 function createTestCase(testFixture, testName) { | 763 function createTestCase(testFixture, testName) { |
| 593 var fixtureConstructor = this[testFixture]; | 764 var fixtureConstructor = this[testFixture]; |
| 594 var testBody = fixtureConstructor.testCaseBodies[testName]; | 765 var testBody = fixtureConstructor.testCaseBodies[testName]; |
| 595 var fixture = new fixtureConstructor(); | 766 var fixture = new fixtureConstructor(); |
| 596 fixture.name = testFixture; | 767 fixture.name = testFixture; |
| 597 return new TestCase(testName, fixture, testBody); | 768 return new TestCase(testName, fixture, testBody); |
| 598 } | 769 } |
| 599 | 770 |
| 600 /** | 771 /** |
| 601 * Used by WebUIBrowserTest to preload the javascript libraries at the | 772 * Used by WebUIBrowserTest to preload the javascript libraries at the |
| 602 * appropriate time for javascript injection into the current page. This | 773 * appropriate time for javascript injection into the current page. This |
| 603 * creates a test case and calls its PreLoad for any early initialization such | 774 * creates a test case and calls its preLoad for any early initialization such |
| 604 * as registering handlers before the page's javascript runs it's OnLoad | 775 * as registering handlers before the page's javascript runs it's OnLoad |
| 605 * method. This is called before the page is loaded, so the |chrome| object is | 776 * method. This is called before the page is loaded, so the |chrome| object is |
| 606 * not yet bound and this DOMContentLoaded listener will be called first to | 777 * not yet bound and this DOMContentLoaded listener will be called first to |
| 607 * override |chrome| in order to route messages registered in |sendCallbacks|. | 778 * override |chrome| in order to route messages registered in |sendCallbacks|. |
| 608 * @param {string} testFixture The test fixture name. | 779 * @param {string} testFixture The test fixture name. |
| 609 * @param {string} testName The test name. | 780 * @param {string} testName The test name. |
| 610 * @see sendCallbacks | 781 * @see sendCallbacks |
| 611 **/ | 782 */ |
| 612 function preloadJavascriptLibraries(testFixture, testName) { | 783 function preloadJavascriptLibraries(testFixture, testName) { |
| 613 window.addEventListener('DOMContentLoaded', function() { | 784 window.addEventListener('DOMContentLoaded', function() { |
| 614 var oldChrome = chrome; | 785 var oldChrome = chrome; |
| 615 chrome = { | 786 chrome = { |
| 616 __proto__: oldChrome, | 787 __proto__: oldChrome, |
| 617 send: send, | 788 send: send, |
| 618 }; | 789 }; |
| 790 | |
| 791 // Override globals at load time so they will be defined. | |
| 792 for (var func in globalOverrides) { | |
| 793 assertNotEquals(undefined, this[func]); | |
| 794 var globalOverride = globalOverrides[func]; | |
| 795 assertNotEquals(undefined, globalOverride); | |
| 796 assertEquals(undefined, globalOverride.original); | |
| 797 globalOverride.original = this[func]; | |
| 798 this[func] = globalOverride.callback.bind(globalOverride.object); | |
| 799 } | |
| 619 }); | 800 }); |
| 620 currentTestCase = createTestCase(testFixture, testName); | 801 currentTestCase = createTestCase(testFixture, testName); |
| 621 currentTestCase.PreLoad(); | 802 currentTestCase.preLoad(); |
| 622 } | 803 } |
| 623 | 804 |
| 624 /** | 805 /** |
| 625 * During generation phase, this outputs; do nothing at runtime. | 806 * During generation phase, this outputs; do nothing at runtime. |
| 626 **/ | 807 */ |
| 627 function GEN() {} | 808 function GEN() {} |
| 628 | 809 |
| 629 /** | 810 /** |
| 630 * At runtime, register the testName with a test fixture. Since this method | 811 * At runtime, register the testName with a test fixture. Since this method |
| 631 * doesn't have a test fixture, create a dummy fixture to hold its |name| | 812 * doesn't have a test fixture, create a dummy fixture to hold its |name| |
| 632 * and |testCaseBodies|. | 813 * and |testCaseBodies|. |
| 633 * @param {string} testCaseName The name of the test case. | 814 * @param {string} testCaseName The name of the test case. |
| 634 * @param {string} testName The name of the test function. | 815 * @param {string} testName The name of the test function. |
| 635 * @param {Function} testBody The body to execute when running this test. | 816 * @param {Function} testBody The body to execute when running this test. |
| 636 **/ | 817 */ |
| 637 function TEST(testCaseName, testName, testBody) { | 818 function TEST(testCaseName, testName, testBody) { |
| 638 var fixtureConstructor = this[testCaseName]; | 819 var fixtureConstructor = this[testCaseName]; |
| 639 if (fixtureConstructor === undefined) { | 820 if (fixtureConstructor === undefined) { |
| 640 fixtureConstructor = function() {}; | 821 fixtureConstructor = function() {}; |
| 641 this[testCaseName] = fixtureConstructor; | 822 this[testCaseName] = fixtureConstructor; |
| 642 fixtureConstructor.prototype = { | 823 fixtureConstructor.prototype = { |
| 643 __proto__: Test.prototype, | 824 __proto__: Test.prototype, |
| 644 name: testCaseName, | 825 name: testCaseName, |
| 645 }; | 826 }; |
| 646 fixtureConstructor.testCaseBodies = {}; | 827 fixtureConstructor.testCaseBodies = {}; |
| 647 } | 828 } |
| 648 fixtureConstructor.testCaseBodies[testName] = testBody; | 829 fixtureConstructor.testCaseBodies[testName] = testBody; |
| 649 } | 830 } |
| 650 | 831 |
| 651 /** | 832 /** |
| 652 * At runtime, register the testName with its fixture. Stuff the |name| into | 833 * At runtime, register the testName with its fixture. Stuff the |name| into |
| 653 * the |testFixture|'s prototype, if needed, and the |testCaseBodies| into its | 834 * the |testFixture|'s prototype, if needed, and the |testCaseBodies| into its |
| 654 * constructor. | 835 * constructor. |
| 655 * @param {string} testFixture The name of the test fixture class. | 836 * @param {string} testFixture The name of the test fixture class. |
| 656 * @param {string} testName The name of the test function. | 837 * @param {string} testName The name of the test function. |
| 657 * @param {Function} testBody The body to execute when running this test. | 838 * @param {Function} testBody The body to execute when running this test. |
| 658 **/ | 839 */ |
| 659 function TEST_F(testFixture, testName, testBody) { | 840 function TEST_F(testFixture, testName, testBody) { |
| 660 var fixtureConstructor = this[testFixture]; | 841 var fixtureConstructor = this[testFixture]; |
| 661 if (!fixtureConstructor.prototype.name) | 842 if (!fixtureConstructor.prototype.name) |
| 662 fixtureConstructor.prototype.name = testFixture; | 843 fixtureConstructor.prototype.name = testFixture; |
| 663 if (fixtureConstructor['testCaseBodies'] === undefined) | 844 if (fixtureConstructor['testCaseBodies'] === undefined) |
| 664 fixtureConstructor.testCaseBodies = {}; | 845 fixtureConstructor.testCaseBodies = {}; |
| 665 fixtureConstructor.testCaseBodies[testName] = testBody; | 846 fixtureConstructor.testCaseBodies[testName] = testBody; |
| 666 } | 847 } |
| 667 | 848 |
| 668 /** | 849 /** |
| 669 * RunJavascriptTestF uses this as the |testFunction| when invoking | 850 * RunJavascriptTestF uses this as the |testFunction| when invoking |
| 670 * runTest. If |currentTestCase| is non-null at this point, verify that | 851 * runTest. If |currentTestCase| is non-null at this point, verify that |
| 671 * |testFixture| and |testName| agree with the preloaded values. Create | 852 * |testFixture| and |testName| agree with the preloaded values. Create |
| 672 * |currentTestCase|, if needed, run it, and clear the |currentTestCase|. | 853 * |currentTestCase|, if needed, run it, and clear the |currentTestCase|. |
| 673 * @param {string} testFixture The name of the test fixture class. | 854 * @param {string} testFixture The name of the test fixture class. |
| 674 * @param {string} testName The name of the test function. | 855 * @param {string} testName The name of the test function. |
| 675 * @see preloadJavascriptLibraries | 856 * @see preloadJavascriptLibraries |
| 676 * @see runTest | 857 * @see runTest |
| 677 **/ | 858 */ |
| 678 function RUN_TEST_F(testFixture, testName) { | 859 function RUN_TEST_F(testFixture, testName) { |
| 679 try { | 860 if (!currentTestCase) |
| 680 if (!currentTestCase) | 861 currentTestCase = createTestCase(testFixture, testName); |
| 681 currentTestCase = createTestCase(testFixture, testName); | 862 assertEquals(currentTestCase.name, testName); |
| 682 assertEquals(currentTestCase.name, testName); | 863 assertEquals(currentTestCase.fixture.name, testFixture); |
| 683 assertEquals(currentTestCase.fixture.name, testFixture); | 864 console.log('Running TestCase ' + testFixture + '.' + testName); |
| 684 console.log('Running TestCase ' + testFixture + '.' + testName); | 865 currentTestCase.run(); |
| 685 currentTestCase.Run(); | 866 } |
| 686 } finally { | 867 |
| 687 currentTestCase = null; | 868 /** |
| 869 * This Mock4JS matcher object pushes each |actualArgument| parameter to | |
| 870 * match() calls onto |args|. | |
| 871 * @param {Array} args The array to push |actualArgument| onto. | |
| 872 * @param {Object} realMatcher The real matcher check arguments with. | |
| 873 * @constructor | |
| 874 * @extends {realMatcher} | |
| 875 */ | |
| 876 function SaveMockArgumentMatcher(args, realMatcher) { | |
| 877 this.arguments_ = args; | |
| 878 this.realMatcher_ = realMatcher; | |
| 879 } | |
| 880 | |
| 881 SaveMockArgumentMatcher.prototype = { | |
| 882 /** | |
| 883 * Holds the arguments to push each |actualArgument| onto. | |
| 884 * @type {Array} | |
| 885 * @private | |
| 886 */ | |
| 887 arguments_: null, | |
| 888 | |
| 889 /** | |
| 890 * The real Mock4JS matcher object to check arguments with. | |
| 891 * @type {Object} | |
| 892 */ | |
| 893 realMatcher_: null, | |
| 894 | |
| 895 /** | |
| 896 * Pushes |actualArgument| onto |arguments_| and call |realMatcher_|. Clears | |
| 897 * |arguments_| on non-match. | |
| 898 * @param {*} actualArgument The argument to match and save. | |
| 899 * @return {boolean} Result of calling the |realMatcher|. | |
| 900 */ | |
| 901 argumentMatches: function(actualArgument) { | |
| 902 this.arguments_.push(actualArgument); | |
| 903 var match = this.realMatcher_.argumentMatches(actualArgument); | |
| 904 if (!match) | |
| 905 this.arguments_.splice(0, this.arguments_.length); | |
| 906 | |
| 907 return match; | |
| 908 }, | |
| 909 | |
| 910 /** | |
| 911 * Proxy to |realMatcher_| for description. | |
| 912 * @return {string} Description of this Mock4JS matcher. | |
| 913 */ | |
| 914 describe: function() { | |
| 915 return this.realMatcher_.describe(); | |
| 916 }, | |
| 917 }; | |
| 918 | |
| 919 /** | |
| 920 * Actions invoked by Mock4JS's "will()" syntax do not receive arguments from | |
| 921 * the mocked method. This class works with SaveMockArgumentMatcher to save | |
| 922 * arguments so that the invoked Action can pass arguments through to the | |
| 923 * invoked function. | |
| 924 * @param {!Object} realMatcher The real matcher to perform matching with. | |
| 925 * @constructor | |
| 926 */ | |
| 927 function SaveMockArguments() { | |
| 928 this.arguments = []; | |
| 929 } | |
| 930 | |
| 931 SaveMockArguments.prototype = { | |
| 932 /** | |
| 933 * Wraps the |realMatcher| with an object which will push its argument onto | |
| 934 * |arguments| and call realMatcher. | |
| 935 * @param {Object} realMatcher A Mock4JS matcher object for this argument. | |
| 936 * @return {SaveMockArgumentMatcher} A new matcher which will push its | |
| 937 * argument onto |arguments|. | |
| 938 */ | |
| 939 match: function(realMatcher) { | |
| 940 return new SaveMockArgumentMatcher(this.arguments, realMatcher); | |
| 941 }, | |
| 942 | |
| 943 /** | |
| 944 * Remember the argument passed to this stub invocation. | |
| 945 * @type {Array} | |
| 946 */ | |
| 947 arguments: null, | |
| 948 }; | |
| 949 | |
| 950 /** | |
| 951 * CallFunctionAction is provided to allow mocks to have side effects. | |
| 952 * @param {Object} obj The object to set |this| to when calling |func_|. | |
| 953 * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are | |
| 954 * passed to |func|. | |
| 955 * @param {Function} func The function to call. | |
| 956 * @param {Array=} args Any arguments to pass to func. | |
| 957 * @constructor | |
| 958 */ | |
| 959 function CallFunctionAction(obj, savedArgs, func, args) { | |
| 960 this.obj_ = obj; | |
| 961 this.savedArgs_ = savedArgs; | |
| 962 this.func_ = func; | |
| 963 this.args_ = args ? args : []; | |
| 964 } | |
| 965 | |
| 966 CallFunctionAction.prototype = { | |
| 967 /** | |
| 968 * Set |this| to |obj_| when calling |func_|. | |
| 969 * @type {?Object} | |
| 970 */ | |
| 971 obj_: null, | |
| 972 | |
| 973 /** | |
| 974 * The SaveMockArguments to hold arguments when invoking |func_|. | |
| 975 * @type {?SaveMockArguments} | |
| 976 * @private | |
| 977 */ | |
| 978 savedArgs_: null, | |
| 979 | |
| 980 /** | |
| 981 * The function to call when invoked. | |
| 982 * @type {!Function} | |
| 983 * @private | |
| 984 */ | |
| 985 func_: null, | |
| 986 | |
| 987 /** | |
| 988 * Arguments to pass to |func_| when invoked. | |
| 989 * @type {!Array} | |
| 990 */ | |
| 991 args_: null, | |
| 992 | |
| 993 /** | |
| 994 * Accessor for |func_|. | |
| 995 * @return {Function} The function to invoke. | |
| 996 */ | |
| 997 get func() { | |
| 998 return this.func_; | |
| 999 }, | |
| 1000 | |
| 1001 /** | |
| 1002 * Called by Mock4JS when using .will() to specify actions for stubs() or | |
| 1003 * expects(). Clears |savedArgs_| so it can be reused. | |
| 1004 * @return The results of calling |func_| with the concatenation of | |
| 1005 * |savedArgs_| and |args_|. | |
| 1006 */ | |
| 1007 invoke: function() { | |
| 1008 var prependArgs = []; | |
| 1009 if (this.savedArgs_) { | |
| 1010 prependArgs = this.savedArgs_.arguments.splice( | |
| 1011 0, this.savedArgs_.arguments.length); | |
| 1012 } | |
| 1013 return this.func.apply(this.obj_, prependArgs.concat(this.args_)); | |
| 1014 }, | |
| 1015 | |
| 1016 /** | |
| 1017 * Describe this action to Mock4JS. | |
| 1018 * @return {string} A description of this action. | |
| 1019 */ | |
| 1020 describe: function() { | |
| 1021 return 'calls the given function with saved arguments and ' + this.args_; | |
| 688 } | 1022 } |
| 689 } | 1023 }; |
| 690 | 1024 |
| 691 /** | 1025 /** |
| 692 * CallFunctionAction is provided to allow mocks to have side effects. | 1026 * Syntactic sugar for use with will() on a Mock4JS.Mock. |
| 693 * @param {Function} func The function to call. | 1027 * @param {Function} func The function to call when the method is invoked. |
| 1028 * @param {...*} var_args Arguments to pass when calling func. | |
| 1029 * @return {CallFunctionAction} Action for use in will. | |
| 1030 */ | |
| 1031 function callFunction(func) { | |
| 1032 return new CallFunctionAction( | |
| 1033 null, null, func, Array.prototype.slice.call(arguments, 1)); | |
| 1034 } | |
| 1035 | |
| 1036 /** | |
| 1037 * Syntactic sugar for use with will() on a Mock4JS.Mock. | |
| 1038 * @param {SaveMockArguments} savedArgs Arguments saved with this object | |
| 1039 * are passed to |func|. | |
| 1040 * @param {Function} func The function to call when the method is invoked. | |
| 1041 * @param {...*} var_args Arguments to pass when calling func. | |
| 1042 * @return {CallFunctionAction} Action for use in will. | |
| 1043 */ | |
| 1044 function callFunctionWithSavedArgs(savedArgs, func) { | |
| 1045 return new CallFunctionAction( | |
| 1046 null, savedArgs, func, Array.prototype.slice.call(arguments, 2)); | |
| 1047 } | |
| 1048 | |
| 1049 /** | |
| 1050 * CallGlobalAction as a subclass of CallFunctionAction looks up the original | |
| 1051 * global object in |globalOverrides| using |funcName| as the key. This allows | |
| 1052 * tests, which need to wait until a global function to be called in order to | |
| 1053 * start the test to run the original function. When used with runAllActions | |
| 1054 * or runAllActionsAsync, Mock4JS expectations may call start or continue the | |
| 1055 * test after calling the original function. | |
| 1056 * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are | |
| 1057 * passed to the global function |funcName|. | |
| 1058 * @param {string} funcName The name of the global function to call. | |
| 694 * @param {Array} args Any arguments to pass to func. | 1059 * @param {Array} args Any arguments to pass to func. |
| 695 * @constructor | 1060 * @constructor |
| 696 **/ | 1061 * @extends {CallFunctionAction} |
| 697 function CallFunctionAction(func, args) { | 1062 * @see globalOverrides |
| 698 this._func = func; | 1063 */ |
| 699 this._args = args; | 1064 function CallGlobalAction(savedArgs, funcName, args) { |
| 700 } | 1065 CallFunctionAction.call(this, null, savedArgs, funcName, args); |
| 701 | 1066 } |
| 702 CallFunctionAction.prototype = { | 1067 |
| 1068 CallGlobalAction.prototype = { | |
| 1069 __proto__: CallFunctionAction.prototype, | |
| 1070 | |
| 1071 /** | |
| 1072 * Fetch and return the original global function to call. | |
| 1073 * @return {Function} The global function to invoke. | |
| 1074 * @override | |
| 1075 */ | |
| 1076 get func() { | |
| 1077 var func = globalOverrides[this.func_].original; | |
| 1078 assertNotEquals(undefined, func); | |
| 1079 return func; | |
| 1080 }, | |
| 1081 }; | |
| 1082 | |
| 1083 /** | |
| 1084 * Syntactic sugar for use with will() on a Mock4JS.Mock. | |
| 1085 * @param {SaveMockArguments} savedArgs Arguments saved with this object | |
| 1086 * are passed to the global function |funcName|. | |
| 1087 * @param {string} funcName The name of a registered mock global function to | |
| 1088 * call when the method is invoked. | |
| 1089 * @param {...*} var_args Arguments to pass when calling func. | |
| 1090 * @return {CallGlobalAction} Action for use in Mock4JS will(). | |
| 1091 */ | |
| 1092 function callGlobalWithSavedArgs(savedArgs, funcName) { | |
|
mmenke
2011/08/24 15:27:50
Might be nice to have a way to have this record, a
Sheridan Rawlins
2011/08/24 21:15:45
You can do this with runAllActionsAsync. See exam
| |
| 1093 return new CallGlobalAction( | |
| 1094 savedArgs, funcName, Array.prototype.slice.call(arguments, 2)); | |
| 1095 } | |
| 1096 | |
| 1097 /** | |
| 1098 * When to call testDone(). | |
| 1099 * @enum {number} | |
| 1100 */ | |
| 1101 var WhenTestDone = { | |
| 1102 /** | |
| 1103 * Default for the method called. | |
| 1104 */ | |
| 1105 DEFAULT: -1, | |
| 1106 | |
| 1107 /** | |
| 1108 * Never call testDone(). | |
| 1109 */ | |
| 1110 NEVER: 0, | |
| 1111 | |
| 1112 /** | |
| 1113 * Call testDone() on assert failure. | |
| 1114 */ | |
| 1115 ASSERT: 1, | |
| 1116 | |
| 1117 /** | |
| 1118 * Call testDone() if there are any assert or expect failures. | |
| 1119 */ | |
| 1120 EXPECT: 2, | |
| 1121 | |
| 1122 /** | |
| 1123 * Always call testDone(). | |
| 1124 */ | |
| 1125 ALWAYS: 3, | |
| 1126 }; | |
| 1127 | |
| 1128 /** | |
| 1129 * Runs all |actions|. | |
| 1130 * @param {boolean} isAsync When true, call testDone() on Errors. | |
| 1131 * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate | |
| 1132 * time. | |
| 1133 * @param {Array.<Object>} actions Actions to run. | |
| 1134 * @constructor | |
| 1135 */ | |
| 1136 function RunAllAction(isAsync, whenTestDone, actions) { | |
| 1137 this.isAsync_ = isAsync; | |
| 1138 this.whenTestDone_ = whenTestDone; | |
| 1139 this.actions_ = actions; | |
| 1140 } | |
| 1141 | |
| 1142 RunAllAction.prototype = { | |
| 1143 /** | |
| 1144 * When true, call testDone() on Errors. | |
| 1145 * @type {boolean} | |
| 1146 * @private | |
| 1147 */ | |
| 1148 isAsync_: false, | |
| 1149 | |
| 1150 /** | |
| 1151 * Call testDone() at appropriate time. | |
| 1152 * @type {WhenTestDone} | |
| 1153 * @private | |
| 1154 * @see WhenTestDone | |
| 1155 */ | |
| 1156 whenTestDone_: WhenTestDone.ASSERT, | |
| 1157 | |
| 1158 /** | |
| 1159 * Holds the actions to execute when invoked. | |
| 1160 * @type {Array} | |
| 1161 * @private | |
| 1162 */ | |
| 1163 actions_: null, | |
| 1164 | |
| 1165 /** | |
| 1166 * Runs all |actions_|, returning the last one. When running in sync mode, | |
| 1167 * throws any exceptions to be caught by runTest() or | |
| 1168 * runTestFunction(). Call testDone() according to |whenTestDone_| setting. | |
| 1169 */ | |
| 703 invoke: function() { | 1170 invoke: function() { |
| 704 return this._func.apply(null, this._args); | 1171 try { |
| 705 }, | 1172 var result; |
| 1173 for(var i = 0; i < this.actions_.length; ++i) | |
| 1174 result = this.actions_[i].invoke(); | |
| 1175 | |
| 1176 if ((this.whenTestDone_ == WhenTestDone.EXPECT && errors.length) || | |
| 1177 this.whenTestDone_ == WhenTestDone.ALWAYS) | |
| 1178 testDone(); | |
| 1179 | |
| 1180 return result; | |
| 1181 } catch (e) { | |
| 1182 if (!(e instanceof Error)) | |
| 1183 e = new Error(e.toString()); | |
| 1184 | |
| 1185 if (!this.isAsync_) | |
| 1186 throw e; | |
| 1187 | |
| 1188 errors.push(e); | |
| 1189 if (this.whenTestDone_ == WhenTestDone.ASSERT || | |
| 1190 this.whenTestDone_ == WhenTestDone.ALWAYS) { | |
|
mmenke
2011/08/24 15:27:50
Important: Should also abort on WhenTestDone.EXPE
Sheridan Rawlins
2011/08/24 21:15:45
Ok. How 'bout != NEVER.
Done.
On 2011/08/24 15:
| |
| 1191 testDone(); | |
| 1192 } | |
| 1193 } | |
| 1194 }, | |
| 1195 | |
| 1196 /** | |
| 1197 * Describe this action to Mock4JS. | |
| 1198 * @return {string} A description of this action. | |
| 1199 */ | |
| 706 describe: function() { | 1200 describe: function() { |
| 707 return 'calls the given function with arguments ' + this._args; | 1201 return 'Calls all actions: ' + this.actions_; |
| 708 } | 1202 }, |
| 709 }; | 1203 }; |
| 710 | 1204 |
| 711 /** | 1205 /** |
| 712 * Syntactic sugar for will() on a Mock4JS.Mock. | 1206 * Syntactic sugar for use with will() on a Mock4JS.Mock. |
| 713 * @param {Function} func the function to call when the method is invoked. | 1207 * @param {...Object} var_actions Actions to run. |
| 714 * @param {...*} var_args arguments to pass when calling func. | 1208 * @return {RunAllAction} Action for use in will. |
| 715 **/ | 1209 */ |
| 716 function callFunction(func) { | 1210 function runAllActions() { |
| 717 return new CallFunctionAction(func, | 1211 return new RunAllAction(false, WhenTestDone.NEVER, |
| 718 Array.prototype.slice.call(arguments, 1)); | 1212 Array.prototype.slice.call(arguments)); |
| 719 } | 1213 } |
| 720 | 1214 |
| 721 /** | 1215 /** |
| 722 * Allow mock stubs() and expects() to know what arguments were passed to the | 1216 * Syntactic sugar for use with will() on a Mock4JS.Mock. |
| 723 * |realMatcher|. | 1217 * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate |
| 724 * @param {!Object} realMatcher The real matcher to perform matching with. | 1218 * time. |
| 725 * @constructor | 1219 * @param {...Object} var_actions Actions to run. |
| 726 **/ | 1220 * @return {RunAllAction} Action for use in will. |
| 727 function SaveArgumentsMatcher(realMatcher) { | 1221 */ |
| 728 this.realMatcher_ = realMatcher; | 1222 function runAllActionsAsync(whenTestDone) { |
| 729 } | 1223 return new RunAllAction(true, whenTestDone, |
| 730 | 1224 Array.prototype.slice.call(arguments, 1)); |
| 731 SaveArgumentsMatcher.prototype = { | 1225 } |
| 732 /** | |
| 733 * Remember the argument passed to this stub invocation. | |
| 734 * @type {*} | |
| 735 **/ | |
| 736 argument: undefined, | |
| 737 | |
| 738 /** | |
| 739 * @type {Object} the object performing the real match. | |
| 740 * @private | |
| 741 */ | |
| 742 realMatcher_: null, | |
| 743 | |
| 744 /** | |
| 745 * Saves |actualArgument| for later use by the mock stub or expect. | |
| 746 * @param {*} actualArgument The argument to match and save. | |
| 747 * @return {boolean} value of calling the |realMatcher_|. | |
| 748 **/ | |
| 749 argumentMatches: function(actualArgument) { | |
| 750 this.argument = actualArgument; | |
| 751 return this.realMatcher_.argumentMatches.call(this.realMatcher_, | |
| 752 actualArgument); | |
| 753 }, | |
| 754 | |
| 755 /** | |
| 756 * Generic description for this Matcher object. | |
| 757 * @return {string} description of the matcher for this argument. | |
| 758 **/ | |
| 759 describe: function() { | |
| 760 return 'SaveArguments(' + | |
| 761 this.realMatcher_.describe.call(this.realMatcher_) + ')'; | |
| 762 }, | |
| 763 }; | |
| 764 | 1226 |
| 765 // Exports. | 1227 // Exports. |
| 766 testing.Test = Test; | 1228 testing.Test = Test; |
| 767 window.testDone = testDone; | 1229 window.testDone = testDone; |
| 768 window.assertTrue = assertTrue; | 1230 window.assertTrue = assertTrue; |
| 769 window.assertFalse = assertFalse; | 1231 window.assertFalse = assertFalse; |
| 770 window.assertGE = assertGE; | 1232 window.assertGE = assertGE; |
| 771 window.assertGT = assertGT; | 1233 window.assertGT = assertGT; |
| 772 window.assertEquals = assertEquals; | 1234 window.assertEquals = assertEquals; |
| 773 window.assertLE = assertLE; | 1235 window.assertLE = assertLE; |
| 774 window.assertLT = assertLT; | 1236 window.assertLT = assertLT; |
| 775 window.assertNotEquals = assertNotEquals; | 1237 window.assertNotEquals = assertNotEquals; |
| 776 window.assertNotReached = assertNotReached; | 1238 window.assertNotReached = assertNotReached; |
| 777 window.callFunction = callFunction; | 1239 window.callFunction = callFunction; |
| 1240 window.callFunctionWithSavedArgs = callFunctionWithSavedArgs; | |
| 1241 window.callGlobalWithSavedArgs = callGlobalWithSavedArgs; | |
| 778 window.expectTrue = createExpect(assertTrue); | 1242 window.expectTrue = createExpect(assertTrue); |
| 779 window.expectFalse = createExpect(assertFalse); | 1243 window.expectFalse = createExpect(assertFalse); |
| 780 window.expectGE = createExpect(assertGE); | 1244 window.expectGE = createExpect(assertGE); |
| 781 window.expectGT = createExpect(assertGT); | 1245 window.expectGT = createExpect(assertGT); |
| 782 window.expectEquals = createExpect(assertEquals); | 1246 window.expectEquals = createExpect(assertEquals); |
| 783 window.expectLE = createExpect(assertLE); | 1247 window.expectLE = createExpect(assertLE); |
| 784 window.expectLT = createExpect(assertLT); | 1248 window.expectLT = createExpect(assertLT); |
| 785 window.expectNotEquals = createExpect(assertNotEquals); | 1249 window.expectNotEquals = createExpect(assertNotEquals); |
| 786 window.expectNotReached = createExpect(assertNotReached); | 1250 window.expectNotReached = createExpect(assertNotReached); |
| 787 window.preloadJavascriptLibraries = preloadJavascriptLibraries; | 1251 window.preloadJavascriptLibraries = preloadJavascriptLibraries; |
| 788 window.registerMessageCallback = registerMessageCallback; | 1252 window.registerMessageCallback = registerMessageCallback; |
| 1253 window.registerMockGlobals = registerMockGlobals; | |
| 789 window.registerMockMessageCallbacks = registerMockMessageCallbacks; | 1254 window.registerMockMessageCallbacks = registerMockMessageCallbacks; |
| 790 window.resetTestState = resetTestState; | 1255 window.resetTestState = resetTestState; |
| 1256 window.runAllActions = runAllActions; | |
| 1257 window.runAllActionsAsync = runAllActionsAsync; | |
| 791 window.runTest = runTest; | 1258 window.runTest = runTest; |
| 792 window.runTestFunction = runTestFunction; | 1259 window.runTestFunction = runTestFunction; |
| 793 window.SaveArgumentsMatcher = SaveArgumentsMatcher; | 1260 window.SaveMockArguments = SaveMockArguments; |
| 1261 window.DUMMY_URL = DUMMY_URL; | |
| 794 window.TEST = TEST; | 1262 window.TEST = TEST; |
| 795 window.TEST_F = TEST_F; | 1263 window.TEST_F = TEST_F; |
| 796 window.GEN = GEN; | 1264 window.GEN = GEN; |
| 1265 window.WhenTestDone = WhenTestDone; | |
| 797 | 1266 |
| 798 // Import the Mock4JS helpers. | 1267 // Import the Mock4JS helpers. |
| 799 Mock4JS.addMockSupport(window); | 1268 Mock4JS.addMockSupport(window); |
| 800 })(); | 1269 })(('window' in this) ? window : this); |
| OLD | NEW |