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

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: Added ability to defer RunTest. 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 **/
arv (Not doing code reviews) 2011/08/22 20:57:18 Close these JSDoc comments with */ instead of **/
Sheridan Rawlins 2011/08/23 01:06:15 Done.
8 8
9 /** 9 /**
10 * Namespace for |Test|. 10 * Namespace for |Test|.
11 * @type {Object} 11 * @type {Object}
12 **/ 12 **/
13 var testing = {}; 13 var testing = {};
14 14
15 /** 15 /**
16 * Hold the currentTestCase across between PreLoad and Run. 16 * Hold the currentTestCase across between PreLoad and Run.
17 * @type {TestCase} 17 * @type {TestCase}
(...skipping 15 matching lines...) Expand all
33 // Provide global objects for generation case. 33 // Provide global objects for generation case.
34 if (this['window'] === undefined) 34 if (this['window'] === undefined)
35 this['window'] = this; 35 this['window'] = this;
36 if (this['chrome'] === undefined) { 36 if (this['chrome'] === undefined) {
37 this['chrome'] = { 37 this['chrome'] = {
38 send: function() {}, 38 send: function() {},
39 }; 39 };
40 } 40 }
41 if (this['console'] === undefined) { 41 if (this['console'] === undefined) {
42 this['console'] = { 42 this['console'] = {
43 log: print, 43 log: print,
arv (Not doing code reviews) 2011/08/22 20:57:18 what about error and info?
Sheridan Rawlins 2011/08/23 01:06:15 Only the window is needed, actually. I nuked thes
44 }; 44 };
45 } 45 }
46 46
47 /** 47 /**
48 * This class will be exported as testing.Test, and is provided to hold the 48 * 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 49 * fixture's configuration and callback methods for the various phases of
50 * invoking a test. It is called "Test" rather than TestFixture to roughly 50 * invoking a test. It is called "Test" rather than TestFixture to roughly
51 * mimic the gtest's class names. 51 * mimic the gtest's class names.
52 * @constructor 52 * @constructor
53 **/ 53 **/
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 92
93 /** 93 /**
94 * When set to a non-null string, auto-generate typedef before generating 94 * When set to a non-null string, auto-generate typedef before generating
95 * TEST*: {@code typedef typedefCppFixture testFixture}. 95 * TEST*: {@code typedef typedefCppFixture testFixture}.
96 * @type {string} 96 * @type {string}
97 **/ 97 **/
98 typedefCppFixture: 'WebUIBrowserTest', 98 typedefCppFixture: 'WebUIBrowserTest',
99 99
100 /** 100 /**
101 * This should be initialized by the test fixture and can be referenced 101 * This should be initialized by the test fixture and can be referenced
102 * during the test run. 102 * during the test run. It holds any mocked handler methods.
103 * @type {Mock4JS.Mock} 103 * @type {?Mock4JS.Mock}
104 **/ 104 **/
105 mockHandler: null, 105 mockHandler: null,
106 106
107 /** 107 /**
108 * This should be initialized by the test fixture and can be referenced
109 * during the test run. It holds any mocked global functions.
110 * @type {?Mock4JS.Mock}
111 **/
112 mockGlobals: null,
113
114 /**
115 * Value is passed through call to C++ RunJavascriptF to invoke this test.
116 * @type {boolean}
117 **/
118 isAsync: false,
119
120 /**
108 * Override this method to perform initialization during preload (such as 121 * Override this method to perform initialization during preload (such as
109 * creating mocks and registering handlers). 122 * creating mocks and registering handlers).
110 * @type {Function} 123 * @type {Function}
111 **/ 124 **/
112 PreLoad: function() {}, 125 PreLoad: function() {},
arv (Not doing code reviews) 2011/08/22 20:57:18 Can the names of these be fixed?
Sheridan Rawlins 2011/08/23 01:06:15 Done.
113 126
114 /** 127 /**
115 * Override this method to perform tasks before running your test. 128 * Override this method to perform tasks before running your test.
116 * @type {Function} 129 * @type {Function}
117 **/ 130 **/
118 SetUp: function() {}, 131 SetUp: function() {},
119 132
120 /** 133 /**
121 * Override this method to perform tasks after running your test. If you 134 * Override this method to perform tasks after running your test. If you
122 * create a mock class, you must call Mock4JS.verifyAllMocks() in this 135 * create a mock class, you must call Mock4JS.verifyAllMocks() in this
123 * phase. 136 * phase.
124 * @type {Function} 137 * @type {Function}
125 **/ 138 **/
126 TearDown: function() { 139 TearDown: function() {
127 Mock4JS.verifyAllMocks(); 140 Mock4JS.verifyAllMocks();
128 } 141 },
142
143 /**
144 * Called to run the body from the perspective of this fixture.
145 * @type {Function}
146 */
147 RunTest: function(testBody) {
148 testBody.call(this);
149 },
150
151 /**
152 * @param {boolean} alwaysDone When true, always call testDone().
153 * @param {Function} completion The function to call to complete the test.
154 * @return {function(): void} Return a function, bound to this test fixture,
155 * which continues the test.
156 **/
157 continueTest: function(alwaysDone, completion) {
158 var completionAction = new CallFunctionAction(
159 this, null, completion, null);
160 var runAll = new RunAllAction(
161 true, alwaysDone, [completionAction]);
162 return function() {
163 runAll.invoke();
164 };
165 },
166
167 /**
168 * Call this during SetUp to defer the call to RunTest() until later. The
169 * caller must call the returned function at some point to run the test.
170 * @type {Function}
171 * @return {function(): void} A function which will run the current body of
172 * the currentTestCase.
173 */
174 deferRunTest: function() {
175 return currentTestCase.deferRunTest();
176 },
129 }; 177 };
130 178
131 /** 179 /**
132 * This class is not exported and is available to hold the state of the 180 * This class is not exported and is available to hold the state of the
133 * |currentTestCase| throughout preload and test run. 181 * |currentTestCase| throughout preload and test run.
134 * @param {string} name The name of the test case. 182 * @param {string} name The name of the test case.
135 * @param {Test} fixture The fixture object for this test case. 183 * @param {Test} fixture The fixture object for this test case.
136 * @param {Function} body The code to run for the test. 184 * @param {Function} body The code to run for the test.
137 * @constructor 185 * @constructor
138 **/ 186 **/
139 function TestCase(name, fixture, body) { 187 function TestCase(name, fixture, body) {
140 this.name = name; 188 this.name = name;
141 this.fixture = fixture; 189 this.fixture = fixture;
142 this.body = body; 190 this.body = body;
143 } 191 }
144 192
145 TestCase.prototype = { 193 TestCase.prototype = {
194 /**
195 * The name of this test.
196 * @type {string}
197 */
146 name: null, 198 name: null,
199
200 /**
201 * The test fixture to set |this| to when running the test |body|.
202 * @type {testing.Test}
203 */
147 fixture: null, 204 fixture: null,
205
206 /**
207 * The test body to execute in RunTest().
208 * @type {Function}
209 **/
148 body: null, 210 body: null,
149 211
150 /** 212 /**
213 * True when the test fixture will run the test later.
214 * @type {boolean}
215 * @private
216 */
217 deferred_: false,
218
219 /**
151 * Called at preload time, proxies to the fixture. 220 * Called at preload time, proxies to the fixture.
152 * @type {Function} 221 * @type {Function}
153 **/ 222 **/
154 PreLoad: function(name) { 223 PreLoad: function(name) {
155 if (this.fixture) 224 if (this.fixture)
156 this.fixture.PreLoad(); 225 this.fixture.PreLoad();
157 }, 226 },
158 227
159 /** 228 /**
229 * Called before a test runs.
230 **/
231 SetUp: function() {
232 if (this.fixture)
233 this.fixture.SetUp();
234 },
235
236 /**
237 * Called before a test is torn down (by testDone()).
238 **/
239 TearDown: function() {
240 if (this.fixture)
241 this.fixture.TearDown();
242 },
243
244 /**
245 * Called to run this test's body.
246 **/
247 RunTest: function() {
248 if (this.body && this.fixture)
249 this.fixture.RunTest(this.body);
250 },
251
252 /**
160 * Runs this test case with |this| set to the |fixture|. 253 * Runs this test case with |this| set to the |fixture|.
161 * 254 *
162 * Note: Tests created with TEST_F may depend upon |this| being set to an 255 * 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 256 * instance of this.fixture. The current implementation of TEST creates a
164 * dummy constructor, but tests created with TEST should not rely on |this| 257 * dummy constructor, but tests created with TEST should not rely on |this|
165 * being set. 258 * being set.
166 * @type {Function} 259 * @type {Function}
167 **/ 260 **/
168 Run: function() { 261 Run: function() {
169 if (this.fixture) 262 try {
170 this.fixture.SetUp(); 263 this.SetUp();
171 if (this.body) 264 } catch(e) {
172 this.body.call(this.fixture); 265 console.error(e.stack);
173 if (this.fixture) 266 }
174 this.fixture.TearDown(); 267
268 if (!this.deferred_)
269 this.RunTest();
270
271 // TearDown called by testDone().
175 }, 272 },
273
274 /**
275 * Cause this TestCase to be deferred (don't call RunTest()) until the
276 * returned function is called.
277 * @type {Function}
278 * @return {function(): void} A function thatwill run this TestCase when
279 * called.
280 */
281 deferRunTest: function() {
282 this.deferred_ = true;
283 var completionAction = new CallFunctionAction(
284 this, null, this.RunTest, null);
285 var runAll = new RunAllAction(
286 true, true, [completionAction]);
287 return function() {
288 runAll.invoke();
289 };
290 },
291
176 }; 292 };
177 293
178 /** 294 /**
179 * Registry of javascript-defined callbacks for {@code chrome.send}. 295 * Registry of javascript-defined callbacks for {@code chrome.send}.
180 * @type {Object} 296 * @type {Object}
181 **/ 297 **/
182 var sendCallbacks = {}; 298 var sendCallbacks = {};
183 299
184 /** 300 /**
185 * Registers the message, object and callback for {@code chrome.send} 301 * Registers the message, object and callback for {@code chrome.send}
186 * @param {string} name The name of the message to route to this |callback|. 302 * @param {string} name The name of the message to route to this |callback|.
187 * @param {Object} messageHAndler Pass as |this| when calling the |callback|. 303 * @param {Object} messageHandler Pass as |this| when calling the |callback|.
188 * @param {function(...)} callback Called by {@code chrome.send}. 304 * @param {function(...)} callback Called by {@code chrome.send}.
189 * @see sendCallbacks 305 * @see sendCallbacks
190 **/ 306 **/
191 function registerMessageCallback(name, messageHandler, callback) { 307 function registerMessageCallback(name, messageHandler, callback) {
192 sendCallbacks[name] = [messageHandler, callback]; 308 sendCallbacks[name] = [messageHandler, callback];
193 } 309 }
194 310
195 /** 311 /**
196 * Register all methods of {@code mockClass.prototype} with messages of the 312 * 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 313 * same name as the method, using the proxy of the |mockObject| as the
198 * |messageHandler| when registering. 314 * |messageHandler| when registering.
199 * @param {Mock4JS.Mock} mockObject The mock to register callbacks against. 315 * @param {Mock4JS.Mock} mockObject The mock to register callbacks against.
200 * @param {function(new:Object)} mockClAss Constructor for the mocked class. 316 * @param {function(new:Object)} mockClAss Constructor for the mocked class.
201 * @see registerMessageCallback 317 * @see registerMessageCallback
202 **/ 318 **/
203 function registerMockMessageCallbacks(mockObject, mockClass) { 319 function registerMockMessageCallbacks(mockObject, mockClass) {
204 var mockProxy = mockObject.proxy(); 320 var mockProxy = mockObject.proxy();
205 for (func in mockClass.prototype) { 321 for (var func in mockClass.prototype) {
206 if (typeof(mockClass.prototype[func]) == 'function') { 322 if (typeof(mockClass.prototype[func]) == 'function') {
207 registerMessageCallback(func, 323 registerMessageCallback(func, mockProxy, mockProxy[func]);
208 mockProxy,
209 mockProxy[func]);
210 } 324 }
211 } 325 }
212 } 326 }
327
328 /**
329 * Holds the mapping of name -> global override information.
330 * @type {Object}
331 **/
332 var globalOverrides = {};
333
334 /**
335 * Registers the global function name, object and callback.
336 * @param {string} name The name of the message to route to this |callback|.
337 * @param {Object} object Pass as |this| when calling the |callback|.
338 * @param {function(...)} callback Called by {@code chrome.send}.
339 **/
340 function registerMockGlobal(name, object, callback) {
341 assertEquals(undefined, globalOverrides[name]);
342 globalOverrides[name] = {
343 object: object,
344 callback: callback,
345 };
346 }
347
348 /**
349 * Register all methods of {@code mockClass.prototype} as overrides to global
350 * functions of the same name as the method, using the proxy of the
351 * |mockObject| to handle the functions.
352 * @param {Mock4JS.Mock} mockObject The mock to register callbacks against.
353 * @param {function(new:Object)} mockClAss Constructor for the mocked class.
354 * @see registerMessageCallback
355 **/
356 function registerMockGlobals(mockObject, mockClass) {
357 var mockProxy = mockObject.proxy();
358 for (var func in mockClass.prototype) {
359 if (typeof(mockClass.prototype[func]) == 'function') {
arv (Not doing code reviews) 2011/08/22 20:57:18 typeof should not have parentheses
Sheridan Rawlins 2011/08/23 01:06:15 Done.
360 registerMockGlobal(func, mockProxy, mockProxy[func]);
361 }
362 }
363 }
213 364
214 /** 365 /**
215 * Overrides {@code chrome.send} for routing messages to javascript 366 * Overrides {@code chrome.send} for routing messages to javascript
216 * functions. Also falls back to sending with the original chrome object. 367 * functions. Also falls back to sending with the original chrome object.
217 * @param {string} messageName The message to route. 368 * @param {string} messageName The message to route.
218 **/ 369 **/
219 function send(messageName) { 370 function send(messageName) {
220 var callback = sendCallbacks[messageName]; 371 var callback = sendCallbacks[messageName];
221 if (callback != undefined) 372 if (callback != undefined)
222 callback[1].apply(callback[0], Array.prototype.slice.call(arguments, 1)); 373 callback[1].apply(callback[0], Array.prototype.slice.call(arguments, 1));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 } 492 }
342 493
343 /** 494 /**
344 * Notifies the running browser test of the test results. Clears |errors|. 495 * Notifies the running browser test of the test results. Clears |errors|.
345 * @param {Array.<boolean, string>=} result When passed, this is used for the 496 * @param {Array.<boolean, string>=} result When passed, this is used for the
346 * testResult message. 497 * testResult message.
347 **/ 498 **/
348 function testDone(result) { 499 function testDone(result) {
349 if (!testIsDone) { 500 if (!testIsDone) {
350 testIsDone = true; 501 testIsDone = true;
502 if (currentTestCase) {
503 currentTestCase.TearDown();
504 currentTestCase = null;
505 }
351 chrome.send('testResult', result ? result : testResult()); 506 chrome.send('testResult', result ? result : testResult());
352 errors.splice(0, errors.length); 507 errors.splice(0, errors.length);
353 } else { 508 } else {
354 console.warn('testIsDone already'); 509 console.warn('testIsDone already');
355 } 510 }
356 } 511 }
357 512
358 /** 513 /**
359 * Returns [success, message] & clears |errors|. 514 * Returns [success, message] & clears |errors|.
360 * @return {Array.<boolean, string>} 515 * @return {Array.<boolean, string>}
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 * @param {string} testName The test name. 764 * @param {string} testName The test name.
610 * @see sendCallbacks 765 * @see sendCallbacks
611 **/ 766 **/
612 function preloadJavascriptLibraries(testFixture, testName) { 767 function preloadJavascriptLibraries(testFixture, testName) {
613 window.addEventListener('DOMContentLoaded', function() { 768 window.addEventListener('DOMContentLoaded', function() {
614 var oldChrome = chrome; 769 var oldChrome = chrome;
615 chrome = { 770 chrome = {
616 __proto__: oldChrome, 771 __proto__: oldChrome,
617 send: send, 772 send: send,
618 }; 773 };
774
775 // Override globals at load time so they will be defined.
776 for (var func in globalOverrides) {
777 assertNotEquals(undefined, this[func]);
778 var globalOverride = globalOverrides[func];
779 assertNotEquals(undefined, globalOverride);
780 assertEquals(undefined, globalOverride.original);
781 globalOverride.original = this[func];
782 this[func] = globalOverride.callback.bind(globalOverride.object);
783 }
619 }); 784 });
620 currentTestCase = createTestCase(testFixture, testName); 785 currentTestCase = createTestCase(testFixture, testName);
621 currentTestCase.PreLoad(); 786 currentTestCase.PreLoad();
622 } 787 }
623 788
624 /** 789 /**
625 * During generation phase, this outputs; do nothing at runtime. 790 * During generation phase, this outputs; do nothing at runtime.
626 **/ 791 **/
627 function GEN() {} 792 function GEN() {}
628 793
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 * RunJavascriptTestF uses this as the |testFunction| when invoking 834 * RunJavascriptTestF uses this as the |testFunction| when invoking
670 * runTest. If |currentTestCase| is non-null at this point, verify that 835 * runTest. If |currentTestCase| is non-null at this point, verify that
671 * |testFixture| and |testName| agree with the preloaded values. Create 836 * |testFixture| and |testName| agree with the preloaded values. Create
672 * |currentTestCase|, if needed, run it, and clear the |currentTestCase|. 837 * |currentTestCase|, if needed, run it, and clear the |currentTestCase|.
673 * @param {string} testFixture The name of the test fixture class. 838 * @param {string} testFixture The name of the test fixture class.
674 * @param {string} testName The name of the test function. 839 * @param {string} testName The name of the test function.
675 * @see preloadJavascriptLibraries 840 * @see preloadJavascriptLibraries
676 * @see runTest 841 * @see runTest
677 **/ 842 **/
678 function RUN_TEST_F(testFixture, testName) { 843 function RUN_TEST_F(testFixture, testName) {
679 try { 844 if (!currentTestCase)
680 if (!currentTestCase) 845 currentTestCase = createTestCase(testFixture, testName);
681 currentTestCase = createTestCase(testFixture, testName); 846 assertEquals(currentTestCase.name, testName);
682 assertEquals(currentTestCase.name, testName); 847 assertEquals(currentTestCase.fixture.name, testFixture);
683 assertEquals(currentTestCase.fixture.name, testFixture); 848 console.log('Running TestCase ' + testFixture + '.' + testName);
684 console.log('Running TestCase ' + testFixture + '.' + testName); 849 currentTestCase.Run();
685 currentTestCase.Run(); 850 }
686 } finally { 851
687 currentTestCase = null; 852 /**
688 } 853 * Matcher which pushes the |actualArgument| of argumentMatches() onto
689 } 854 * |arguments|, then proxies the return result to the |realMatcher|. Because
690 855 * |realMatcher| can be any type, this constructor overrides argumentMatches,
691 /** 856 * then forces |this| to be an instance of |realMatcher|.
mmenke 2011/08/22 16:26:44 You're defining a class in terms of one of its met
Sheridan Rawlins 2011/08/23 01:06:15 I rewrote this with composition instead of hacky i
692 * CallFunctionAction is provided to allow mocks to have side effects. 857 * @param {Array} arguments The arguments to push |actualArgument| onto.
693 * @param {Function} func The function to call. 858 * @param {Object} realMatcher The real matcher check arguments with.
694 * @param {Array} args Any arguments to pass to func. 859 * @constructor
695 * @constructor 860 * @extends {realMatcher}
arv (Not doing code reviews) 2011/08/22 20:57:18 This annotation is a bit strange
Sheridan Rawlins 2011/08/23 01:06:15 See new version. On 2011/08/22 20:57:18, arv wrot
696 **/ 861 **/
697 function CallFunctionAction(func, args) { 862 function SaveArgumentMatcher(arguments, realMatcher) {
698 this._func = func; 863 this.arguments_ = arguments;
699 this._args = args; 864 this.argumentMatches = this.argumentMatches;
mmenke 2011/08/22 16:26:44 ?
Sheridan Rawlins 2011/08/23 01:06:15 Yeah, this was weird - it could have been this.arg
700 } 865 this.__proto__ = realMatcher;
arv (Not doing code reviews) 2011/08/22 20:57:18 This seems a bit hacky. How about? var obj = Obje
Sheridan Rawlins 2011/08/23 01:06:15 See new version with composition instead of the ha
701 866 }
702 CallFunctionAction.prototype = { 867
703 invoke: function() { 868 SaveArgumentMatcher.prototype = {
704 return this._func.apply(null, this._args); 869 /**
705 }, 870 * Holds the arguments to push each |actualArgument| onto.
706 describe: function() { 871 * @type {Array}
707 return 'calls the given function with arguments ' + this._args; 872 * @private
708 } 873 **/
709 }; 874 arguments_: null,
710 875
711 /** 876 /**
712 * Syntactic sugar for will() on a Mock4JS.Mock. 877 * Pushes |actualArgument| onto |arguments_| for later use. Clears
713 * @param {Function} func the function to call when the method is invoked. 878 * |arguments_| on non-match.
714 * @param {...*} var_args arguments to pass when calling func. 879 * @param {*} actualArgument The argument to match and save.
715 **/ 880 * @return {boolean} value of calling the |realMatcher|.
716 function callFunction(func) { 881 * @override
717 return new CallFunctionAction(func, 882 **/
718 Array.prototype.slice.call(arguments, 1)); 883 argumentMatches: function(actualArgument) {
719 } 884 this.arguments_.push(actualArgument);
885 var match = this.__proto__.argumentMatches(actualArgument);
886 if (!match)
887 this.arguments_.splice(0, this.arguments_.length);
888
889 return match;
890 },
891 };
720 892
721 /** 893 /**
722 * Allow mock stubs() and expects() to know what arguments were passed to the 894 * Allow mock stubs() and expects() to know what arguments were passed to the
723 * |realMatcher|. 895 * |realMatcher|.
mmenke 2011/08/22 16:26:44 This isn't terribly illuminating for someone tryin
Sheridan Rawlins 2011/08/23 01:06:15 OK. Added more context to comments. On 2011/08/2
724 * @param {!Object} realMatcher The real matcher to perform matching with. 896 * @param {!Object} realMatcher The real matcher to perform matching with.
725 * @constructor 897 * @constructor
726 **/ 898 **/
727 function SaveArgumentsMatcher(realMatcher) { 899 function SaveMockArguments() {
728 this.realMatcher_ = realMatcher; 900 this.arguments = [];
729 } 901 }
730 902
731 SaveArgumentsMatcher.prototype = { 903 SaveMockArguments.prototype = {
904 /**
905 * Wraps the |realMatcher| with an object which will push its argument onto
906 * |arguments| and call realMatcher.
907 * @param {Object} realMatcher A Mock4JS matcher object for this argument.
908 * @return {SaveArgumentMatcher} A new matcher which will push its argument
909 * onto |arguments|.
910 **/
911 match: function(realMatcher) {
912 return new SaveArgumentMatcher(this.arguments, realMatcher);
913 },
914
732 /** 915 /**
733 * Remember the argument passed to this stub invocation. 916 * Remember the argument passed to this stub invocation.
734 * @type {*} 917 * @type {Array}
735 **/ 918 **/
736 argument: undefined, 919 arguments: null,
737 920 };
738 /** 921
739 * @type {Object} the object performing the real match. 922 /**
740 * @private 923 * CallFunctionAction is provided to allow mocks to have side effects.
741 */ 924 * @param {Object} obj The object to set |this| to when calling |func_|.
742 realMatcher_: null, 925 * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are
743 926 * passed to |func|.
744 /** 927 * @param {Function} func The function to call.
745 * Saves |actualArgument| for later use by the mock stub or expect. 928 * @param {Array} args Any arguments to pass to func.
746 * @param {*} actualArgument The argument to match and save. 929 * @constructor
747 * @return {boolean} value of calling the |realMatcher_|. 930 **/
748 **/ 931 function CallFunctionAction(obj, savedArgs, func, args) {
749 argumentMatches: function(actualArgument) { 932 this.obj_ = obj;
750 this.argument = actualArgument; 933 this.savedArgs_ = savedArgs;
751 return this.realMatcher_.argumentMatches.call(this.realMatcher_, 934 this.func_ = func;
752 actualArgument); 935 this.args_ = args;
753 }, 936 }
754 937
755 /** 938 CallFunctionAction.prototype = {
756 * Generic description for this Matcher object. 939 /**
757 * @return {string} description of the matcher for this argument. 940 * Set |this| to |obj_| when calling |func_|.
941 * @type {?Object}
942 **/
943 obj_: null,
944
945 /**
946 * The SaveMockArguments to hold arguments when invoking |func_|.
947 * @type {?SaveMockArguments}
948 * @private
949 **/
950 savedArgs_: null,
951
952 /**
953 * The function to call when invoked.
954 * @type {!Function}
955 * @private
956 **/
957 func_: null,
958
959 /**
960 * Arguments to pass to |func_| when invoked.
961 * @type {!Array}
962 **/
963 args_: null,
964
965 /**
966 * Accessor for |func_|.
967 * @return {Function} The function to invoke.
968 **/
969 get func() {
970 return this.func_;
971 },
972
973 /**
974 * Called by Mock4JS when using .will() to specify actions for stubs() or
975 * expects(). Clears |savedArgs_| so it can be reused.
976 * @return The results of calling |func_| with the concatenation of
977 * |savedArgs_| and |args_|.
978 **/
979 invoke: function() {
980 var prependArgs = [];
981 if (this.savedArgs_) {
982 prependArgs = this.savedArgs_.arguments.splice(
983 0, this.savedArgs_.arguments.length);
984 }
985 return this.func.apply(this.obj_, prependArgs.concat(this.args_));
986 },
987
988 /**
989 * Describe this action to Mock4JS.
990 * @return {string} A description of this action.
758 **/ 991 **/
759 describe: function() { 992 describe: function() {
760 return 'SaveArguments(' + 993 return 'calls the given function with saved arguments and ' + this.args_;
761 this.realMatcher_.describe.call(this.realMatcher_) + ')'; 994 }
762 }, 995 };
763 }; 996
997 /**
998 * Syntactic sugar for will() on a Mock4JS.Mock.
mmenke 2011/08/22 16:26:44 nit: "for use with" make it clearer that this sho
Sheridan Rawlins 2011/08/23 01:06:15 Done.
999 * @param {Function} func The function to call when the method is invoked.
1000 * @param {...*} var_args Arguments to pass when calling func.
1001 * @return {CallFunctionAction} Action for use in will.
1002 **/
1003 function callFunction(func) {
1004 return new CallFunctionAction(
1005 null, null, func, Array.prototype.slice.call(arguments, 1));
1006 }
1007
1008 /**
1009 * Syntactic sugar for will() on a Mock4JS.Mock.
mmenke 2011/08/22 16:26:44 nit: "for use with"
Sheridan Rawlins 2011/08/23 01:06:15 Done.
1010 * @param {SaveMockArguments} savedArgs Arguments saved with this object
1011 * are passed to |func|.
1012 * @param {Function} func The function to call when the method is invoked.
1013 * @param {...*} var_args Arguments to pass when calling func.
1014 * @return {CallFunctionAction} Action for use in will.
1015 **/
1016 function callFunctionWithSavedArgs(savedArgs, func) {
1017 return new CallFunctionAction(
1018 null, savedArgs, func, Array.prototype.slice.call(arguments, 2));
1019 }
1020
1021 /**
1022 * CallGlobalAction is provided to help override global function with mocking
1023 * expectations and still call the global function.
mmenke 2011/08/22 16:26:44 nit: Say what it does, not just why it exists.
Sheridan Rawlins 2011/08/23 01:06:15 Done.
1024 * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are
1025 * passed to the global function |funcName|.
1026 * @param {Function} funcName The name of the global function to call.
1027 * @param {Array} args Any arguments to pass to func.
1028 * @constructor
1029 * @extends {CallFunctionAction}
1030 * @see globalOverrides
1031 **/
1032 function CallGlobalAction(savedArgs, funcName, args) {
1033 CallFunctionAction.call(this, null, savedArgs, funcName, args);
1034 }
1035
1036 CallGlobalAction.prototype = {
1037 __proto__: CallFunctionAction.prototype,
1038
1039 /**
1040 * Fetch and return the original global function to call.
1041 * @return {Function} The global function to invoke.
1042 * @override
1043 **/
1044 get func() {
1045 var func = globalOverrides[this.func_].original;
1046 assertNotEquals(undefined, func);
1047 return func;
1048 },
1049 };
1050
1051 /**
1052 * Syntactic sugar for will() on a Mock4JS.Mock.
mmenke 2011/08/22 16:26:44 nit: For use with.
Sheridan Rawlins 2011/08/23 01:06:15 Done.
1053 * @param {SaveMockArguments} savedArgs Arguments saved with this object
1054 * are passed to the global function |funcName|.
1055 * @param {Function} funcName The name of the global function to call when the
1056 * method is invoked.
mmenke 2011/08/22 16:26:44 nit: Name of a registered mock global function.
Sheridan Rawlins 2011/08/23 01:06:15 Done.
1057 * @param {...*} var_args Arguments to pass when calling func.
1058 * @return {CallGlobalAction} Action for use in will.
1059 **/
1060 function callGlobalWithSavedArgs(savedArgs, funcName) {
1061 return new CallGlobalAction(
1062 savedArgs, funcName, Array.prototype.slice.call(arguments, 2));
1063 }
1064
1065 /**
1066 * Runs all |actions|.
1067 * @param {boolean} isAsync When true, call testDone() on Errors.
1068 * @param {boolean} alwaysDone When true, always call testDone().
1069 * @param {Array.<Object>} actions Actions to run.
1070 * @constructor
1071 **/
1072 function RunAllAction(isAsync, alwaysDone, actions) {
1073 this.isAsync_ = isAsync;
1074 this.alwaysDone_ = alwaysDone;
1075 this.actions_ = actions;
1076 }
1077
1078 RunAllAction.prototype = {
1079 /**
1080 * When true, call testDone() on Errors.
1081 * @type {boolean}
1082 * @private
1083 **/
1084 isAsync_: false,
1085
1086 /**
1087 * When true, always call testDone().
1088 * @type {boolean}
1089 * @private
1090 **/
1091 alwaysDone_: false,
1092
1093 /**
1094 * Holds the actions to execute when invoked.
1095 * @type {Array}
1096 * @private
1097 **/
1098 actions_: null,
1099
1100 /**
1101 * Runs all |actions_|, returning the last one.
1102 **/
1103 invoke: function() {
1104 try {
1105 var result;
1106 for(var i = 0; i < this.actions_.length; ++i) {
1107 result = this.actions_[i].invoke.apply(
1108 this.actions_[i], Array.prototype.slice.call(arguments));
1109 }
1110 if (this.alwaysDone_)
1111 testDone();
1112
1113 return result;
1114 } catch (e) {
1115 if (!this.isAsync_)
1116 throw e;
1117
1118 errors.push(e);
1119 testDone();
mmenke 2011/08/22 16:26:44 You should also call testDone on expect failures,
Sheridan Rawlins 2011/08/23 01:06:15 I don't think so. There should be a distinction be
mmenke 2011/08/23 01:36:09 Then should probably add a way to tell if there's
Sheridan Rawlins 2011/08/23 05:52:18 Ok. I added a whenTestDone enum to describe when
mmenke 2011/08/23 15:26:29 Seems reasonable to me.
1120 }
1121 },
1122
1123 /**
1124 * Describe this action to Mock4JS.
1125 * @return {string} A description of this action.
1126 **/
1127 describe: function() {
1128 return 'Calls all actions: ' + this.actions_;
1129 },
1130 };
1131
1132 /**
1133 * Syntactic sugar for will() on a Mock4JS.Mock.
1134 * @param {...Object} var_actions Actions to run.
1135 * @return {RunAllAction} Action for use in will.
1136 **/
1137 function runAllActions() {
1138 return new RunAllAction(false, false,
1139 Array.prototype.slice.call(arguments));
1140 }
1141
1142 /**
1143 * Syntactic sugar for will() on a Mock4JS.Mock.
1144 * @param {boolean} alwaysDone When true, always call testDone() otherwise,
1145 * call it only when Errors are thrown (from asserts).
1146 * @return {RunAllAction} Action for use in will.
1147 **/
1148 function runAllActionsAsync(alwaysDone) {
1149 return new RunAllAction(true, alwaysDone,
1150 Array.prototype.slice.call(arguments));
1151 }
764 1152
765 // Exports. 1153 // Exports.
766 testing.Test = Test; 1154 testing.Test = Test;
767 window.testDone = testDone; 1155 window.testDone = testDone;
768 window.assertTrue = assertTrue; 1156 window.assertTrue = assertTrue;
769 window.assertFalse = assertFalse; 1157 window.assertFalse = assertFalse;
770 window.assertGE = assertGE; 1158 window.assertGE = assertGE;
771 window.assertGT = assertGT; 1159 window.assertGT = assertGT;
772 window.assertEquals = assertEquals; 1160 window.assertEquals = assertEquals;
773 window.assertLE = assertLE; 1161 window.assertLE = assertLE;
774 window.assertLT = assertLT; 1162 window.assertLT = assertLT;
775 window.assertNotEquals = assertNotEquals; 1163 window.assertNotEquals = assertNotEquals;
776 window.assertNotReached = assertNotReached; 1164 window.assertNotReached = assertNotReached;
777 window.callFunction = callFunction; 1165 window.callFunction = callFunction;
1166 window.callFunctionWithSavedArgs = callFunctionWithSavedArgs;
1167 window.callGlobalWithSavedArgs = callGlobalWithSavedArgs;
778 window.expectTrue = createExpect(assertTrue); 1168 window.expectTrue = createExpect(assertTrue);
779 window.expectFalse = createExpect(assertFalse); 1169 window.expectFalse = createExpect(assertFalse);
780 window.expectGE = createExpect(assertGE); 1170 window.expectGE = createExpect(assertGE);
781 window.expectGT = createExpect(assertGT); 1171 window.expectGT = createExpect(assertGT);
782 window.expectEquals = createExpect(assertEquals); 1172 window.expectEquals = createExpect(assertEquals);
783 window.expectLE = createExpect(assertLE); 1173 window.expectLE = createExpect(assertLE);
784 window.expectLT = createExpect(assertLT); 1174 window.expectLT = createExpect(assertLT);
785 window.expectNotEquals = createExpect(assertNotEquals); 1175 window.expectNotEquals = createExpect(assertNotEquals);
786 window.expectNotReached = createExpect(assertNotReached); 1176 window.expectNotReached = createExpect(assertNotReached);
787 window.preloadJavascriptLibraries = preloadJavascriptLibraries; 1177 window.preloadJavascriptLibraries = preloadJavascriptLibraries;
788 window.registerMessageCallback = registerMessageCallback; 1178 window.registerMessageCallback = registerMessageCallback;
1179 window.registerMockGlobals = registerMockGlobals;
789 window.registerMockMessageCallbacks = registerMockMessageCallbacks; 1180 window.registerMockMessageCallbacks = registerMockMessageCallbacks;
790 window.resetTestState = resetTestState; 1181 window.resetTestState = resetTestState;
1182 window.runAllActions = runAllActions;
1183 window.runAllActionsAsync = runAllActionsAsync;
791 window.runTest = runTest; 1184 window.runTest = runTest;
792 window.runTestFunction = runTestFunction; 1185 window.runTestFunction = runTestFunction;
793 window.SaveArgumentsMatcher = SaveArgumentsMatcher; 1186 window.SaveMockArguments = SaveMockArguments;
794 window.TEST = TEST; 1187 window.TEST = TEST;
795 window.TEST_F = TEST_F; 1188 window.TEST_F = TEST_F;
796 window.GEN = GEN; 1189 window.GEN = GEN;
797 1190
798 // Import the Mock4JS helpers. 1191 // Import the Mock4JS helpers.
799 Mock4JS.addMockSupport(window); 1192 Mock4JS.addMockSupport(window);
800 })(); 1193 })();
OLDNEW
« chrome/test/data/webui/async_gen.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