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

Side by Side Diff: chrome/test/data/webui/test_api.js

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

Powered by Google App Engine
This is Rietveld 408576698