OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 /** | |
6 * Test fixture for utility.js. | |
7 * @constructor | |
8 * @extends {testing.Test} | |
9 */ | |
10 function GoogleNowUtilityUnitTest () { | |
11 testing.Test.call(this); | |
12 } | |
13 | |
14 GoogleNowUtilityUnitTest.prototype = { | |
15 __proto__: testing.Test.prototype, | |
16 | |
17 /** @override */ | |
18 extraLibraries: [ | |
19 'common_test_util.js', | |
20 'utility_test_util.js', | |
21 'utility.js' | |
22 ] | |
23 }; | |
24 | |
25 TEST_F('GoogleNowUtilityUnitTest', 'SendErrorReport1', function() { | |
26 // Test sending report for an error with a message that can be sent to server. | |
robliao
2013/08/28 22:05:29
Where is the test that checks for first line remov
vadimt
2013/08/28 22:29:35
Line 94.
| |
27 | |
28 // Setup and expectations. | |
29 var testStack = 'Error: TEST ERROR MESSAGE\n ' + | |
30 'at buildErrorWithMessageForServer ' + | |
31 '(chrome-extension://ext_id/utility.js:29:15)\n' + | |
32 ' at <anonymous>:2:16\n ' + | |
33 'at Object.InjectedScript._evaluateOn (<anonymous>:580:39)\n ' + | |
34 'at Object.InjectedScript._evaluateAndWrap (<anonymous>:539:52)\n ' + | |
35 'at Object.InjectedScript.evaluate (<anonymous>:458:21)'; | |
36 | |
37 var testError = { | |
38 canSendMessageToServer: true, | |
39 stack: testStack, | |
40 name: 'TEST ERROR NAME' | |
41 }; | |
42 | |
43 this.makeAndRegisterMockGlobals(['buildServerRequest']); | |
44 this.makeMockLocalFunctions(['sendRequest']); | |
45 | |
46 var mockRequest = {send: this.mockLocalFunctions.functions().sendRequest}; | |
47 | |
48 var expectedRequestParameters = 'error=TEST%20ERROR%20NAME&' + | |
49 'script=%2F%2Fext_id%2Futility.js&' + | |
50 'line=29&' + | |
51 'trace=Error%3A%20TEST%20ERROR%20MESSAGE%0A%20%20%20%20' + | |
52 'at%20buildErrorWithMessageForServer%20' + | |
53 '(chrome-extension%3A%2F%2Fext_id%2Futility.js%3A29%3A15)%0A' + | |
54 '%20%20%20%20at%20%3Canonymous%3E%3A2%3A16%0A%20%20%20%20' + | |
55 'at%20Object.InjectedScript._evaluateOn%20(%3Canonymous%3E%3A580%3A39)' + | |
56 '%0A%20%20%20%20' + | |
57 'at%20Object.InjectedScript._evaluateAndWrap%20(%3Canonymous%3E%3A539' + | |
58 '%3A52)%0A%20%20%20%20' + | |
59 'at%20Object.InjectedScript.evaluate%20(%3Canonymous%3E%3A458%3A21)'; | |
60 | |
61 this.mockGlobals.expects(once()). | |
62 buildServerRequest('jserror', 'application/x-www-form-urlencoded'). | |
63 will(returnValue(mockRequest)); | |
64 this.mockLocalFunctions.expects(once()).sendRequest( | |
65 expectedRequestParameters); | |
66 | |
67 // Invoking the tested function. | |
68 sendErrorReport(testError); | |
69 }); | |
70 | |
71 TEST_F('GoogleNowUtilityUnitTest', 'SendErrorReport2', function() { | |
72 // Test sending report for an error with a message that cannot be sent to | |
robliao
2013/08/28 22:42:31
cannot --> should not
vadimt
2013/08/28 23:02:19
Done.
| |
73 // server, with an error generated in an anonymous function. | |
74 | |
75 // Setup and expectations. | |
76 var testStack = 'TypeError: Property \'processPendingDismissals\' of ' + | |
77 'object [object Object] is not a function\n ' + | |
78 'at chrome-extension://ext_id/background.js:444:11\n ' + | |
79 'at chrome-extension://ext_id/utility.js:509:7'; | |
80 | |
81 var testError = { | |
82 stack: testStack, | |
83 name: 'TypeError' | |
84 }; | |
85 | |
86 this.makeAndRegisterMockGlobals(['buildServerRequest']); | |
87 this.makeMockLocalFunctions(['sendRequest']); | |
88 | |
89 var mockRequest = {send: this.mockLocalFunctions.functions().sendRequest}; | |
90 | |
91 var expectedRequestParameters = 'error=TypeError&' + | |
92 'script=%2F%2Fext_id%2Fbackground.js&' + | |
93 'line=444&' + | |
94 'trace=(message%20removed)%0A%20%20%20%20' + | |
95 'at%20chrome-extension%3A%2F%2Fext_id%2Fbackground.js%3A444%3A11' + | |
96 '%0A%20%20%20%20' + | |
97 'at%20chrome-extension%3A%2F%2Fext_id%2Futility.js%3A509%3A7'; | |
98 | |
99 this.mockGlobals.expects(once()). | |
100 buildServerRequest('jserror', 'application/x-www-form-urlencoded'). | |
101 will(returnValue(mockRequest)); | |
102 this.mockLocalFunctions.expects(once()).sendRequest( | |
103 expectedRequestParameters); | |
104 | |
105 // Invoking the tested function. | |
106 sendErrorReport(testError); | |
107 }); | |
108 | |
109 TEST_F('GoogleNowUtilityUnitTest', 'WrapperCheckInWrappedCallback', function() { | |
110 // Test generating an error when calling wrapper.checkInWrappedCallback from a | |
111 // non-instrumented code. | |
112 | |
113 // Setup and expectations. | |
114 var testError = { | |
115 testField: 'TEST VALUE' | |
116 }; | |
117 | |
118 this.makeAndRegisterMockGlobals([ | |
119 'buildErrorWithMessageForServer', | |
120 'reportError' | |
121 ]); | |
122 | |
123 this.mockGlobals.expects(once()). | |
124 buildErrorWithMessageForServer('Not in instrumented callback'). | |
125 will(returnValue(testError)); | |
126 this.mockGlobals.expects(once()). | |
127 reportError(eqJSON(testError)); | |
128 | |
129 // Invoking the tested function. | |
130 wrapper.checkInWrappedCallback(); | |
131 }); | |
132 | |
133 TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackEvent', function() { | |
134 // Tests wrapping event handler and that the handler code counts as an | |
135 // instrumented callback. | |
136 | |
137 // Setup. | |
138 var testError = { | |
139 testField: 'TEST VALUE' | |
140 }; | |
141 | |
142 this.makeAndRegisterMockGlobals([ | |
143 'buildErrorWithMessageForServer', | |
144 'reportError' | |
145 ]); | |
146 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); | |
147 | |
148 this.makeMockLocalFunctions(['callback']); | |
149 | |
150 // Step 1. Wrapping callback. | |
151 var wrappedCallback = | |
152 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); | |
153 Mock4JS.verifyAllMocks(); | |
154 | |
155 // Step 2. Invoking wrapped callback. | |
156 // Expectations. | |
robliao
2013/08/28 22:05:29
Incomplete comment? (and all others)
vadimt
2013/08/28 22:29:35
No, simply Step 2 is divided into Expectations and
robliao
2013/08/28 22:42:31
No other comments that I've seen thus far do this.
vadimt
2013/08/28 23:02:19
Done.
| |
157 this.mockLocalFunctions.expects(once()). | |
158 callback('test string', 239). | |
159 will(callFunction(function() { | |
160 wrapper.checkInWrappedCallback(); // it should succeed | |
161 })); | |
162 | |
163 // Invoking tested function. | |
robliao
2013/08/28 22:05:29
Spacing. (and all others)
vadimt
2013/08/28 22:29:35
See above.
| |
164 wrappedCallback('test string', 239); | |
165 Mock4JS.verifyAllMocks(); | |
166 | |
167 // Step 3. Checking that after the callback we are again in non-instrumented | |
robliao
2013/08/28 22:05:29
Let's not enumerate the steps. At the point you ne
vadimt
2013/08/28 22:29:35
Numbering really helps to read the code.
You want
robliao
2013/08/28 22:42:31
Your choice, as this is test code.
All further in
vadimt
2013/08/28 23:02:19
I feel that the current way is the best :)
Thanks!
| |
168 // code. | |
169 // Expectations. | |
170 this.mockGlobals.expects(once()). | |
171 buildErrorWithMessageForServer('Not in instrumented callback'). | |
172 will(returnValue(testError)); | |
173 this.mockGlobals.expects(once()). | |
174 reportError(eqJSON(testError)); | |
175 | |
176 // Invocation. | |
177 wrapper.checkInWrappedCallback(); | |
178 | |
179 // Step 4. Check that there won't be errors whe the page unloads. | |
180 assertTrue(onSuspendHandlerContainer.length == 1, | |
181 'onSuspendHandlerContainer.length must be 1'); | |
182 onSuspendHandlerContainer[0](); | |
183 }); | |
184 | |
185 TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackPlugin', function() { | |
186 // Tests calling plugin's prologue and epilogue. | |
187 | |
188 // Setup. | |
189 this.makeMockLocalFunctions([ | |
190 'callback', | |
191 'pluginFactory', | |
192 'prologue', | |
193 'epilogue' | |
194 ]); | |
195 | |
196 // Step 1. Registering plugin factory. | |
197 wrapper.registerWrapperPluginFactory( | |
198 this.mockLocalFunctions.functions().pluginFactory); | |
199 Mock4JS.verifyAllMocks(); | |
200 | |
201 // Step 2. Wrapping callback. | |
202 // Expectations. | |
203 this.mockLocalFunctions.expects(once()). | |
204 pluginFactory(). | |
205 will(returnValue({ | |
206 prologue: this.mockLocalFunctions.functions().prologue, | |
207 epilogue: this.mockLocalFunctions.functions().epilogue | |
208 })); | |
209 | |
210 // Invoking tested function. | |
211 var wrappedCallback = | |
212 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); | |
213 Mock4JS.verifyAllMocks(); | |
214 | |
215 // Step 3. Calling the wrapped callback. | |
216 // Expectations. | |
217 this.mockLocalFunctions.expects(once()).prologue(); | |
218 this.mockLocalFunctions.expects(once()).callback(); | |
219 this.mockLocalFunctions.expects(once()).epilogue(); | |
220 | |
221 // Invoking wrapped callback. | |
222 wrappedCallback(); | |
223 }); | |
224 | |
225 TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackCatchError', function() { | |
226 // Tests catching and sending errors by a wrapped callback. | |
227 | |
228 // Setup. | |
229 this.makeAndRegisterMockGlobals([ | |
230 'reportError' | |
231 ]); | |
232 this.makeMockLocalFunctions(['callback']); | |
233 | |
234 // Step 1. Wrapping callback. | |
235 var wrappedCallback = | |
236 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); | |
237 Mock4JS.verifyAllMocks(); | |
238 | |
239 // Step 2. Invoking wrapped callback. | |
240 // Expectations. | |
241 this.mockLocalFunctions.expects(once()). | |
242 callback(). | |
243 will(callFunction(function() { | |
244 undefined.x = 5; | |
245 })); | |
246 this.mockGlobals.expects(once()). | |
247 reportError( | |
248 eqToString('TypeError: Cannot set property \'x\' of undefined')); | |
249 | |
250 // Invoking tested function. | |
251 wrappedCallback(); | |
252 }); | |
253 | |
254 TEST_F('GoogleNowUtilityUnitTest', | |
255 'WrapperInstrumentChromeApiFunction', | |
256 function() { | |
257 // Tests wrapper.instrumentChromeApiFunction(). | |
258 | |
259 // Setup. | |
260 this.makeMockLocalFunctions([ | |
261 'apiFunction1', | |
262 'apiFunction2', | |
263 'callback1', | |
264 'callback2', | |
265 'pluginFactory', | |
266 'prologue', | |
267 'epilogue' | |
268 ]); | |
269 chrome.testApi = { | |
270 addListener: this.mockLocalFunctions.functions().apiFunction1 | |
271 }; | |
272 | |
273 // Step 1. Instrumenting the listener. | |
274 wrapper.instrumentChromeApiFunction('testApi.addListener', 1); | |
275 Mock4JS.verifyAllMocks(); | |
276 | |
277 // Step 2. Invoking the instrumented API call. | |
278 // Expectations. | |
279 var function1SavedArgs = new SaveMockArguments(); | |
280 this.mockLocalFunctions.expects(once()). | |
281 apiFunction1( | |
282 function1SavedArgs.match(eq(239)), | |
283 function1SavedArgs.match(ANYTHING)); | |
284 | |
285 // Invocation. | |
286 instrumented.testApi.addListener( | |
287 239, this.mockLocalFunctions.functions().callback1); | |
288 Mock4JS.verifyAllMocks(); | |
289 | |
290 // Step 3. Invoking the callback that was passed by the instrumented function | |
291 // to the original one. | |
292 // Expectations. | |
293 this.mockLocalFunctions.expects(once()).callback1(237); | |
294 | |
295 // Invocation. | |
296 function1SavedArgs.arguments[1](237); | |
297 Mock4JS.verifyAllMocks(); | |
298 | |
299 // Step 4. Register plugin factory. | |
300 wrapper.registerWrapperPluginFactory( | |
301 this.mockLocalFunctions.functions().pluginFactory); | |
302 Mock4JS.verifyAllMocks(); | |
303 | |
304 // Step 5. Binding the API to another function. | |
305 chrome.testApi.addListener = this.mockLocalFunctions.functions().apiFunction2; | |
306 | |
307 // Step 6. Invoking the API with another callback. | |
308 // Expectations. | |
309 this.mockLocalFunctions.expects(once()). | |
310 pluginFactory(). | |
311 will(returnValue({ | |
312 prologue: this.mockLocalFunctions.functions().prologue, | |
313 epilogue: this.mockLocalFunctions.functions().epilogue | |
314 })); | |
315 var function2SavedArgs = new SaveMockArguments(); | |
316 this.mockLocalFunctions.expects(once()). | |
317 apiFunction2( | |
318 function2SavedArgs.match(eq(239)), | |
319 function2SavedArgs.match(ANYTHING)); | |
320 | |
321 // Invocation. | |
322 instrumented.testApi.addListener( | |
323 239, this.mockLocalFunctions.functions().callback2); | |
324 Mock4JS.verifyAllMocks(); | |
325 | |
326 // Step 7. Invoking the callback that was passed by the instrumented function | |
327 // to the original one. | |
328 // Expectations. | |
329 this.mockLocalFunctions.expects(once()).prologue(); | |
330 this.mockLocalFunctions.expects(once()).callback2(237); | |
331 this.mockLocalFunctions.expects(once()).epilogue(); | |
332 | |
333 // Invocation. | |
334 function2SavedArgs.arguments[1](237); | |
335 }); | |
336 | |
337 TEST_F('GoogleNowUtilityUnitTest', 'WrapperOnSuspendListenerFail', function() { | |
338 // Tests that upon unloading event page, we get an error if there are pending | |
339 // required callbacks. | |
340 | |
341 // Setup. | |
342 var testError = { | |
343 testField: 'TEST VALUE' | |
344 }; | |
345 this.makeAndRegisterMockGlobals([ | |
346 'buildErrorWithMessageForServer', | |
347 'reportError' | |
348 ]); | |
349 this.makeMockLocalFunctions(['listener', 'callback']); | |
350 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); | |
351 | |
352 // Step 1. Wrapping event listener. | |
353 var wrappedListener = | |
354 wrapper.wrapCallback(this.mockLocalFunctions.functions().listener, true); | |
355 Mock4JS.verifyAllMocks(); | |
356 | |
357 // Step 2. Invoking event listener, which will wrap a required callback. | |
358 // Setup and expectations. | |
359 var wrappedCallback; | |
360 var testFixture = this; | |
361 this.mockLocalFunctions.expects(once()). | |
362 listener(). | |
363 will(callFunction(function() { | |
364 wrappedCallback = wrapper.wrapCallback( | |
365 testFixture.mockLocalFunctions.functions().callback); | |
366 })); | |
367 | |
368 // Invocation. | |
369 wrappedListener(); | |
370 Mock4JS.verifyAllMocks(); | |
371 | |
372 // Step 3. Firing runtime.onSuspend event. | |
373 // Expectations. | |
374 this.mockGlobals.expects(once()). | |
375 buildErrorWithMessageForServer(stringContains( | |
376 'ASSERT: Pending callbacks when unloading event page')). | |
377 will(returnValue(testError)); | |
378 this.mockGlobals.expects(once()). | |
379 reportError(eqJSON(testError)); | |
380 | |
381 // Invocation. | |
382 assertTrue(onSuspendHandlerContainer.length == 1, | |
383 'onSuspendHandlerContainer.length must be 1'); | |
384 onSuspendHandlerContainer[0](); | |
385 }); | |
386 | |
387 TEST_F('GoogleNowUtilityUnitTest', | |
388 'WrapperOnSuspendListenerSuccess', | |
389 function() { | |
390 // Tests that upon unloading event page, we don't get an error if there are no | |
391 // pending required callbacks. | |
392 | |
393 // Setup. | |
394 this.makeMockLocalFunctions(['listener', 'callback']); | |
395 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); | |
396 | |
397 // Step 1. Wrapping event listener. | |
398 var wrappedListener = | |
399 wrapper.wrapCallback(this.mockLocalFunctions.functions().listener, true); | |
400 Mock4JS.verifyAllMocks(); | |
401 | |
402 // Step 2. Invoking event listener, which will wrap a required callback. | |
403 // Setup and expectations. | |
404 var wrappedCallback; | |
405 var testFixture = this; | |
406 this.mockLocalFunctions.expects(once()). | |
407 listener(). | |
408 will(callFunction(function() { | |
409 wrappedCallback = wrapper.wrapCallback( | |
410 testFixture.mockLocalFunctions.functions().callback); | |
411 })); | |
412 | |
413 // Invocation. | |
414 wrappedListener(); | |
415 Mock4JS.verifyAllMocks(); | |
416 | |
417 // Step 3. Calling wrapped callback. | |
418 // Expectations. | |
419 this.mockLocalFunctions.expects(once()).callback(); | |
420 | |
421 // Invocation. | |
422 wrappedCallback(); | |
423 | |
424 // Step 4. Firing runtime.onSuspend event. | |
425 assertTrue(onSuspendHandlerContainer.length == 1, | |
426 'onSuspendHandlerContainer.length must be 1'); | |
427 onSuspendHandlerContainer[0](); | |
428 }); | |
OLD | NEW |