Chromium Code Reviews| 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 |