| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 * Test fixture for utility.js. | 6 * Test fixture for utility.js. |
| 7 * @constructor | 7 * @constructor |
| 8 * @extends {testing.Test} | 8 * @extends {testing.Test} |
| 9 */ | 9 */ |
| 10 function GoogleNowUtilityUnitTest () { | 10 function GoogleNowUtilityUnitTest () { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 }; | 142 }; |
| 143 | 143 |
| 144 this.makeAndRegisterMockGlobals([ | 144 this.makeAndRegisterMockGlobals([ |
| 145 'buildErrorWithMessageForServer', | 145 'buildErrorWithMessageForServer', |
| 146 'reportError' | 146 'reportError' |
| 147 ]); | 147 ]); |
| 148 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); | 148 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); |
| 149 | 149 |
| 150 this.makeMockLocalFunctions(['callback']); | 150 this.makeMockLocalFunctions(['callback']); |
| 151 | 151 |
| 152 // Step 1. Wrapping callback. | 152 // Step 1. Wrap a callback. |
| 153 var wrappedCallback = | 153 var wrappedCallback = |
| 154 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); | 154 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); |
| 155 Mock4JS.verifyAllMocks(); | 155 Mock4JS.verifyAllMocks(); |
| 156 | 156 |
| 157 // Step 2. Invoking wrapped callback. | 157 // Step 2. Invoke wrapped callback. |
| 158 // Expectations. | 158 // Expectations. |
| 159 this.mockLocalFunctions.expects(once()). | 159 this.mockLocalFunctions.expects(once()). |
| 160 callback('test string', 239). | 160 callback('test string', 239). |
| 161 will(callFunction(function() { | 161 will(callFunction(function() { |
| 162 wrapper.checkInWrappedCallback(); // it should succeed | 162 wrapper.checkInWrappedCallback(); // it should succeed |
| 163 })); | 163 })); |
| 164 | 164 |
| 165 // Invoking tested function. | 165 // Invoking tested function. |
| 166 wrappedCallback('test string', 239); | 166 wrappedCallback('test string', 239); |
| 167 Mock4JS.verifyAllMocks(); | 167 Mock4JS.verifyAllMocks(); |
| 168 | 168 |
| 169 // Step 3. Checking that after the callback we are again in non-instrumented | 169 // Step 3. Check that after the callback we are again in non-instrumented |
| 170 // code. | 170 // code. |
| 171 // Expectations. | 171 // Expectations. |
| 172 this.mockGlobals.expects(once()). | 172 this.mockGlobals.expects(once()). |
| 173 buildErrorWithMessageForServer('Not in instrumented callback'). | 173 buildErrorWithMessageForServer('Not in instrumented callback'). |
| 174 will(returnValue(testError)); | 174 will(returnValue(testError)); |
| 175 this.mockGlobals.expects(once()). | 175 this.mockGlobals.expects(once()). |
| 176 reportError(eqJSON(testError)); | 176 reportError(eqJSON(testError)); |
| 177 | 177 |
| 178 // Invocation. | 178 // Invocation. |
| 179 wrapper.checkInWrappedCallback(); | 179 wrapper.checkInWrappedCallback(); |
| 180 | 180 |
| 181 // Step 4. Check that there won't be errors whe the page unloads. | 181 // Step 4. Check that there won't be errors whe the page unloads. |
| 182 assertTrue(onSuspendHandlerContainer.length == 1, | 182 assertTrue(onSuspendHandlerContainer.length == 1, |
| 183 'onSuspendHandlerContainer.length must be 1'); | 183 'onSuspendHandlerContainer.length must be 1'); |
| 184 onSuspendHandlerContainer[0](); | 184 onSuspendHandlerContainer[0](); |
| 185 }); | 185 }); |
| 186 | 186 |
| 187 TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackPlugin', function() { | 187 TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackPlugin', function() { |
| 188 // Tests calling plugin's prologue and epilogue. | 188 // Tests calling plugin's prologue and epilogue. |
| 189 | 189 |
| 190 // Setup. | 190 // Setup. |
| 191 this.makeMockLocalFunctions([ | 191 this.makeMockLocalFunctions([ |
| 192 'callback', | 192 'callback', |
| 193 'pluginFactory', | 193 'pluginFactory', |
| 194 'prologue', | 194 'prologue', |
| 195 'epilogue' | 195 'epilogue' |
| 196 ]); | 196 ]); |
| 197 | 197 |
| 198 // Step 1. Registering plugin factory. | 198 // Step 1. Register plugin factory. |
| 199 wrapper.registerWrapperPluginFactory( | 199 wrapper.registerWrapperPluginFactory( |
| 200 this.mockLocalFunctions.functions().pluginFactory); | 200 this.mockLocalFunctions.functions().pluginFactory); |
| 201 Mock4JS.verifyAllMocks(); | 201 Mock4JS.verifyAllMocks(); |
| 202 | 202 |
| 203 // Step 2. Wrapping callback. | 203 // Step 2. Wrap a callback. |
| 204 // Expectations. | 204 // Expectations. |
| 205 this.mockLocalFunctions.expects(once()). | 205 this.mockLocalFunctions.expects(once()). |
| 206 pluginFactory(). | 206 pluginFactory(). |
| 207 will(returnValue({ | 207 will(returnValue({ |
| 208 prologue: this.mockLocalFunctions.functions().prologue, | 208 prologue: this.mockLocalFunctions.functions().prologue, |
| 209 epilogue: this.mockLocalFunctions.functions().epilogue | 209 epilogue: this.mockLocalFunctions.functions().epilogue |
| 210 })); | 210 })); |
| 211 | 211 |
| 212 // Invoking tested function. | 212 // Invoking tested function. |
| 213 var wrappedCallback = | 213 var wrappedCallback = |
| 214 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); | 214 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); |
| 215 Mock4JS.verifyAllMocks(); | 215 Mock4JS.verifyAllMocks(); |
| 216 | 216 |
| 217 // Step 3. Calling the wrapped callback. | 217 // Step 3. Call the wrapped callback. |
| 218 // Expectations. | 218 // Expectations. |
| 219 this.mockLocalFunctions.expects(once()).prologue(); | 219 this.mockLocalFunctions.expects(once()).prologue(); |
| 220 this.mockLocalFunctions.expects(once()).callback(); | 220 this.mockLocalFunctions.expects(once()).callback(); |
| 221 this.mockLocalFunctions.expects(once()).epilogue(); | 221 this.mockLocalFunctions.expects(once()).epilogue(); |
| 222 | 222 |
| 223 // Invoking wrapped callback. | 223 // Invoking wrapped callback. |
| 224 wrappedCallback(); | 224 wrappedCallback(); |
| 225 }); | 225 }); |
| 226 | 226 |
| 227 TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackCatchError', function() { | 227 TEST_F('GoogleNowUtilityUnitTest', 'WrapperWrapCallbackCatchError', function() { |
| 228 // Tests catching and sending errors by a wrapped callback. | 228 // Tests catching and sending errors by a wrapped callback. |
| 229 | 229 |
| 230 // Setup. | 230 // Setup. |
| 231 this.makeAndRegisterMockGlobals([ | 231 this.makeAndRegisterMockGlobals([ |
| 232 'reportError' | 232 'reportError' |
| 233 ]); | 233 ]); |
| 234 this.makeMockLocalFunctions(['callback']); | 234 this.makeMockLocalFunctions(['callback']); |
| 235 | 235 |
| 236 // Step 1. Wrapping callback. | 236 // Step 1. Wrap a callback. |
| 237 var wrappedCallback = | 237 var wrappedCallback = |
| 238 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); | 238 wrapper.wrapCallback(this.mockLocalFunctions.functions().callback, true); |
| 239 Mock4JS.verifyAllMocks(); | 239 Mock4JS.verifyAllMocks(); |
| 240 | 240 |
| 241 // Step 2. Invoking wrapped callback. | 241 // Step 2. Invoke wrapped callback. |
| 242 // Expectations. | 242 // Expectations. |
| 243 this.mockLocalFunctions.expects(once()). | 243 this.mockLocalFunctions.expects(once()). |
| 244 callback(). | 244 callback(). |
| 245 will(callFunction(function() { | 245 will(callFunction(function() { |
| 246 undefined.x = 5; | 246 undefined.x = 5; |
| 247 })); | 247 })); |
| 248 this.mockGlobals.expects(once()). | 248 this.mockGlobals.expects(once()). |
| 249 reportError( | 249 reportError( |
| 250 eqToString('TypeError: Cannot set property \'x\' of undefined')); | 250 eqToString('TypeError: Cannot set property \'x\' of undefined')); |
| 251 | 251 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 265 'callback1', | 265 'callback1', |
| 266 'callback2', | 266 'callback2', |
| 267 'pluginFactory', | 267 'pluginFactory', |
| 268 'prologue', | 268 'prologue', |
| 269 'epilogue' | 269 'epilogue' |
| 270 ]); | 270 ]); |
| 271 chrome.testApi = { | 271 chrome.testApi = { |
| 272 addListener: this.mockLocalFunctions.functions().apiFunction1 | 272 addListener: this.mockLocalFunctions.functions().apiFunction1 |
| 273 }; | 273 }; |
| 274 | 274 |
| 275 // Step 1. Instrumenting the listener. | 275 // Step 1. Instrument the listener. |
| 276 wrapper.instrumentChromeApiFunction('testApi.addListener', 1); | 276 wrapper.instrumentChromeApiFunction('testApi.addListener', 1); |
| 277 Mock4JS.verifyAllMocks(); | 277 Mock4JS.verifyAllMocks(); |
| 278 | 278 |
| 279 // Step 2. Invoking the instrumented API call. | 279 // Step 2. Invoke the instrumented API call. |
| 280 // Expectations. | 280 // Expectations. |
| 281 var function1SavedArgs = new SaveMockArguments(); | 281 var function1SavedArgs = new SaveMockArguments(); |
| 282 this.mockLocalFunctions.expects(once()). | 282 this.mockLocalFunctions.expects(once()). |
| 283 apiFunction1( | 283 apiFunction1( |
| 284 function1SavedArgs.match(eq(239)), | 284 function1SavedArgs.match(eq(239)), |
| 285 function1SavedArgs.match(ANYTHING)); | 285 function1SavedArgs.match(ANYTHING)); |
| 286 | 286 |
| 287 // Invocation. | 287 // Invocation. |
| 288 instrumented.testApi.addListener( | 288 instrumented.testApi.addListener( |
| 289 239, this.mockLocalFunctions.functions().callback1); | 289 239, this.mockLocalFunctions.functions().callback1); |
| 290 Mock4JS.verifyAllMocks(); | 290 Mock4JS.verifyAllMocks(); |
| 291 | 291 |
| 292 // Step 3. Invoking the callback that was passed by the instrumented function | 292 // Step 3. Invoke the callback that was passed by the instrumented function |
| 293 // to the original one. | 293 // to the original one. |
| 294 // Expectations. | 294 // Expectations. |
| 295 this.mockLocalFunctions.expects(once()).callback1(237); | 295 this.mockLocalFunctions.expects(once()).callback1(237); |
| 296 | 296 |
| 297 // Invocation. | 297 // Invocation. |
| 298 function1SavedArgs.arguments[1](237); | 298 function1SavedArgs.arguments[1](237); |
| 299 Mock4JS.verifyAllMocks(); | 299 Mock4JS.verifyAllMocks(); |
| 300 | 300 |
| 301 // Step 4. Register plugin factory. | 301 // Step 4. Register plugin factory. |
| 302 wrapper.registerWrapperPluginFactory( | 302 wrapper.registerWrapperPluginFactory( |
| 303 this.mockLocalFunctions.functions().pluginFactory); | 303 this.mockLocalFunctions.functions().pluginFactory); |
| 304 Mock4JS.verifyAllMocks(); | 304 Mock4JS.verifyAllMocks(); |
| 305 | 305 |
| 306 // Step 5. Binding the API to another function. | 306 // Step 5. Bind the API to another function. |
| 307 chrome.testApi.addListener = this.mockLocalFunctions.functions().apiFunction2; | 307 chrome.testApi.addListener = this.mockLocalFunctions.functions().apiFunction2; |
| 308 | 308 |
| 309 // Step 6. Invoking the API with another callback. | 309 // Step 6. Invoke the API with another callback. |
| 310 // Expectations. | 310 // Expectations. |
| 311 this.mockLocalFunctions.expects(once()). | 311 this.mockLocalFunctions.expects(once()). |
| 312 pluginFactory(). | 312 pluginFactory(). |
| 313 will(returnValue({ | 313 will(returnValue({ |
| 314 prologue: this.mockLocalFunctions.functions().prologue, | 314 prologue: this.mockLocalFunctions.functions().prologue, |
| 315 epilogue: this.mockLocalFunctions.functions().epilogue | 315 epilogue: this.mockLocalFunctions.functions().epilogue |
| 316 })); | 316 })); |
| 317 var function2SavedArgs = new SaveMockArguments(); | 317 var function2SavedArgs = new SaveMockArguments(); |
| 318 this.mockLocalFunctions.expects(once()). | 318 this.mockLocalFunctions.expects(once()). |
| 319 apiFunction2( | 319 apiFunction2( |
| 320 function2SavedArgs.match(eq(239)), | 320 function2SavedArgs.match(eq(239)), |
| 321 function2SavedArgs.match(ANYTHING)); | 321 function2SavedArgs.match(ANYTHING)); |
| 322 | 322 |
| 323 // Invocation. | 323 // Invocation. |
| 324 instrumented.testApi.addListener( | 324 instrumented.testApi.addListener( |
| 325 239, this.mockLocalFunctions.functions().callback2); | 325 239, this.mockLocalFunctions.functions().callback2); |
| 326 Mock4JS.verifyAllMocks(); | 326 Mock4JS.verifyAllMocks(); |
| 327 | 327 |
| 328 // Step 7. Invoking the callback that was passed by the instrumented function | 328 // Step 7. Invoke the callback that was passed by the instrumented function |
| 329 // to the original one. | 329 // to the original one. |
| 330 // Expectations. | 330 // Expectations. |
| 331 this.mockLocalFunctions.expects(once()).prologue(); | 331 this.mockLocalFunctions.expects(once()).prologue(); |
| 332 this.mockLocalFunctions.expects(once()).callback2(237); | 332 this.mockLocalFunctions.expects(once()).callback2(237); |
| 333 this.mockLocalFunctions.expects(once()).epilogue(); | 333 this.mockLocalFunctions.expects(once()).epilogue(); |
| 334 | 334 |
| 335 // Invocation. | 335 // Invocation. |
| 336 function2SavedArgs.arguments[1](237); | 336 function2SavedArgs.arguments[1](237); |
| 337 }); | 337 }); |
| 338 | 338 |
| 339 TEST_F('GoogleNowUtilityUnitTest', 'WrapperOnSuspendListenerFail', function() { | 339 TEST_F('GoogleNowUtilityUnitTest', 'WrapperOnSuspendListenerFail', function() { |
| 340 // Tests that upon unloading event page, we get an error if there are pending | 340 // Tests that upon unloading event page, we get an error if there are pending |
| 341 // required callbacks. | 341 // required callbacks. |
| 342 | 342 |
| 343 // Setup. | 343 // Setup. |
| 344 var testError = { | 344 var testError = { |
| 345 testField: 'TEST VALUE' | 345 testField: 'TEST VALUE' |
| 346 }; | 346 }; |
| 347 this.makeAndRegisterMockGlobals([ | 347 this.makeAndRegisterMockGlobals([ |
| 348 'buildErrorWithMessageForServer', | 348 'buildErrorWithMessageForServer', |
| 349 'reportError' | 349 'reportError' |
| 350 ]); | 350 ]); |
| 351 this.makeMockLocalFunctions(['listener', 'callback']); | 351 this.makeMockLocalFunctions(['listener', 'callback']); |
| 352 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); | 352 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); |
| 353 | 353 |
| 354 // Step 1. Wrapping event listener. | 354 // Step 1. Wrap event listener. |
| 355 var wrappedListener = | 355 var wrappedListener = |
| 356 wrapper.wrapCallback(this.mockLocalFunctions.functions().listener, true); | 356 wrapper.wrapCallback(this.mockLocalFunctions.functions().listener, true); |
| 357 Mock4JS.verifyAllMocks(); | 357 Mock4JS.verifyAllMocks(); |
| 358 | 358 |
| 359 // Step 2. Invoking event listener, which will wrap a required callback. | 359 // Step 2. Invoke event listener, which will wrap a required callback. |
| 360 // Setup and expectations. | 360 // Setup and expectations. |
| 361 var wrappedCallback; | 361 var wrappedCallback; |
| 362 var testFixture = this; | 362 var testFixture = this; |
| 363 this.mockLocalFunctions.expects(once()). | 363 this.mockLocalFunctions.expects(once()). |
| 364 listener(). | 364 listener(). |
| 365 will(callFunction(function() { | 365 will(callFunction(function() { |
| 366 wrappedCallback = wrapper.wrapCallback( | 366 wrappedCallback = wrapper.wrapCallback( |
| 367 testFixture.mockLocalFunctions.functions().callback); | 367 testFixture.mockLocalFunctions.functions().callback); |
| 368 })); | 368 })); |
| 369 | 369 |
| 370 // Invocation. | 370 // Invocation. |
| 371 wrappedListener(); | 371 wrappedListener(); |
| 372 Mock4JS.verifyAllMocks(); | 372 Mock4JS.verifyAllMocks(); |
| 373 | 373 |
| 374 // Step 3. Firing runtime.onSuspend event. | 374 // Step 3. Fire runtime.onSuspend event. |
| 375 // Expectations. | 375 // Expectations. |
| 376 this.mockGlobals.expects(once()). | 376 this.mockGlobals.expects(once()). |
| 377 buildErrorWithMessageForServer(stringContains( | 377 buildErrorWithMessageForServer(stringContains( |
| 378 'ASSERT: Pending callbacks when unloading event page')). | 378 'ASSERT: Pending callbacks when unloading event page')). |
| 379 will(returnValue(testError)); | 379 will(returnValue(testError)); |
| 380 this.mockGlobals.expects(once()). | 380 this.mockGlobals.expects(once()). |
| 381 reportError(eqJSON(testError)); | 381 reportError(eqJSON(testError)); |
| 382 | 382 |
| 383 // Invocation. | 383 // Invocation. |
| 384 assertTrue(onSuspendHandlerContainer.length == 1, | 384 assertTrue(onSuspendHandlerContainer.length == 1, |
| 385 'onSuspendHandlerContainer.length must be 1'); | 385 'onSuspendHandlerContainer.length must be 1'); |
| 386 onSuspendHandlerContainer[0](); | 386 onSuspendHandlerContainer[0](); |
| 387 }); | 387 }); |
| 388 | 388 |
| 389 TEST_F('GoogleNowUtilityUnitTest', | 389 TEST_F('GoogleNowUtilityUnitTest', |
| 390 'WrapperOnSuspendListenerSuccess', | 390 'WrapperOnSuspendListenerSuccess', |
| 391 function() { | 391 function() { |
| 392 // Tests that upon unloading event page, we don't get an error if there are no | 392 // Tests that upon unloading event page, we don't get an error if there are no |
| 393 // pending required callbacks. | 393 // pending required callbacks. |
| 394 | 394 |
| 395 // Setup. | 395 // Setup. |
| 396 this.makeMockLocalFunctions(['listener', 'callback']); | 396 this.makeMockLocalFunctions(['listener', 'callback']); |
| 397 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); | 397 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); |
| 398 | 398 |
| 399 // Step 1. Wrapping event listener. | 399 // Step 1. Wrap event listener. |
| 400 var wrappedListener = | 400 var wrappedListener = |
| 401 wrapper.wrapCallback(this.mockLocalFunctions.functions().listener, true); | 401 wrapper.wrapCallback(this.mockLocalFunctions.functions().listener, true); |
| 402 Mock4JS.verifyAllMocks(); | 402 Mock4JS.verifyAllMocks(); |
| 403 | 403 |
| 404 // Step 2. Invoking event listener, which will wrap a required callback. | 404 // Step 2. Invoke event listener, which will wrap a required callback. |
| 405 // Setup and expectations. | 405 // Setup and expectations. |
| 406 var wrappedCallback; | 406 var wrappedCallback; |
| 407 var testFixture = this; | 407 var testFixture = this; |
| 408 this.mockLocalFunctions.expects(once()). | 408 this.mockLocalFunctions.expects(once()). |
| 409 listener(). | 409 listener(). |
| 410 will(callFunction(function() { | 410 will(callFunction(function() { |
| 411 wrappedCallback = wrapper.wrapCallback( | 411 wrappedCallback = wrapper.wrapCallback( |
| 412 testFixture.mockLocalFunctions.functions().callback); | 412 testFixture.mockLocalFunctions.functions().callback); |
| 413 })); | 413 })); |
| 414 | 414 |
| 415 // Invocation. | 415 // Invocation. |
| 416 wrappedListener(); | 416 wrappedListener(); |
| 417 Mock4JS.verifyAllMocks(); | 417 Mock4JS.verifyAllMocks(); |
| 418 | 418 |
| 419 // Step 3. Calling wrapped callback. | 419 // Step 3. Call wrapped callback. |
| 420 // Expectations. | 420 // Expectations. |
| 421 this.mockLocalFunctions.expects(once()).callback(); | 421 this.mockLocalFunctions.expects(once()).callback(); |
| 422 | 422 |
| 423 // Invocation. | 423 // Invocation. |
| 424 wrappedCallback(); | 424 wrappedCallback(); |
| 425 | 425 |
| 426 // Step 4. Firing runtime.onSuspend event. | 426 // Step 4. Fire runtime.onSuspend event. |
| 427 assertTrue(onSuspendHandlerContainer.length == 1, | 427 assertTrue(onSuspendHandlerContainer.length == 1, |
| 428 'onSuspendHandlerContainer.length must be 1'); | 428 'onSuspendHandlerContainer.length must be 1'); |
| 429 onSuspendHandlerContainer[0](); | 429 onSuspendHandlerContainer[0](); |
| 430 }); | 430 }); |
| 431 |
| 432 var taskNameA = 'TASK A'; |
| 433 var taskNameB = 'TASK B'; |
| 434 var taskNameC = 'TASK C'; |
| 435 |
| 436 function areTasksConflicting(newTaskName, scheduledTaskName) { |
| 437 // Task B is conflicting with Task A. This means that if Task B is added when |
| 438 // Task A is running, Task B will be ignored (but not vice versa). No other |
| 439 // pair is conflicting. |
| 440 return newTaskName == taskNameB && scheduledTaskName == taskNameA; |
| 441 } |
| 442 |
| 443 function setUpTaskManagerTest(fixture) { |
| 444 // We want to mock wrapper using makeAndRegisterMockApis(), which requires |
| 445 // the mocked functions to not exist as a precondition. Resetting 'wrapper' to |
| 446 // 'undefined'. |
| 447 wrapper = undefined; |
| 448 |
| 449 fixture.makeAndRegisterMockApis([ |
| 450 'wrapper.checkInWrappedCallback', |
| 451 'wrapper.registerWrapperPluginFactory', |
| 452 'wrapper.debugGetStateString' |
| 453 ]); |
| 454 fixture.makeMockLocalFunctions(['task1', 'task2', 'task3']); |
| 455 fixture.makeAndRegisterMockGlobals(['reportError']); |
| 456 |
| 457 fixture.mockApis.stubs().wrapper_checkInWrappedCallback(); |
| 458 fixture.mockApis.stubs().wrapper_debugGetStateString(). |
| 459 will(returnValue('testWrapperDebugState')); |
| 460 |
| 461 var registerWrapperPluginFactorySavedArgs = new SaveMockArguments(); |
| 462 fixture.mockApis.expects(once()).wrapper_registerWrapperPluginFactory( |
| 463 registerWrapperPluginFactorySavedArgs.match(ANYTHING)); |
| 464 var tasks = buildTaskManager(areTasksConflicting); |
| 465 Mock4JS.verifyAllMocks(); |
| 466 |
| 467 return { |
| 468 tasks: tasks, |
| 469 pluginFactory: registerWrapperPluginFactorySavedArgs.arguments[0] |
| 470 }; |
| 471 } |
| 472 |
| 473 TEST_F('GoogleNowUtilityUnitTest', 'TaskManager2Sequential', function() { |
| 474 // Tests that 2 tasks get successfully executed consecutively, even if the |
| 475 // second one conflicts with the first. |
| 476 |
| 477 // Setup. |
| 478 var test = setUpTaskManagerTest(this); |
| 479 |
| 480 // Step 1. Add 1st task that doesn't create pending callbacks. |
| 481 // Expectations. |
| 482 this.mockLocalFunctions.expects(once()).task1(ANYTHING); |
| 483 // Invocation. |
| 484 test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| 485 Mock4JS.verifyAllMocks(); |
| 486 |
| 487 // Step 2. Add 2nd task. |
| 488 // Expectations. |
| 489 this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| 490 // Invocation. |
| 491 test.tasks.add(taskNameB, this.mockLocalFunctions.functions().task2); |
| 492 }); |
| 493 |
| 494 TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerConflicting', function() { |
| 495 // Tests that adding a task while a conflicting task is being executed causes |
| 496 // the second one to be ignored. |
| 497 |
| 498 // Setup. |
| 499 var test = setUpTaskManagerTest(this); |
| 500 var task1PluginInstance; |
| 501 |
| 502 // Step 1. Add 1st task that creates a pending callback. |
| 503 // Expectations. |
| 504 this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| 505 will(callFunction(function() { |
| 506 task1PluginInstance = test.pluginFactory(); |
| 507 })); |
| 508 // Invocation. |
| 509 test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| 510 Mock4JS.verifyAllMocks(); |
| 511 |
| 512 // Step 2. Add 2nd task. Since it conflicts with currently running task1 |
| 513 // (see areTasksConflicting), it should be ignored. |
| 514 test.tasks.add(taskNameB, this.mockLocalFunctions.functions().task2); |
| 515 Mock4JS.verifyAllMocks(); |
| 516 |
| 517 // Step 3. Enter the callback of task1. |
| 518 task1PluginInstance.prologue(); |
| 519 Mock4JS.verifyAllMocks(); |
| 520 |
| 521 // Step 4. Leave the callback of task1. |
| 522 task1PluginInstance.epilogue(); |
| 523 }); |
| 524 |
| 525 TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerNestedTaskEnqueue', function() { |
| 526 // Tests that adding a task while a non-conflicting task is being executed |
| 527 // causes the second one to be executed after the first one completes. |
| 528 |
| 529 // Setup. |
| 530 var test = setUpTaskManagerTest(this); |
| 531 var task1PluginInstance; |
| 532 |
| 533 // Step 1. Add 1st task that creates a pending callback. |
| 534 // Expectations. |
| 535 this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| 536 will(callFunction(function() { |
| 537 task1PluginInstance = test.pluginFactory(); |
| 538 })); |
| 539 // Invocation. |
| 540 test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| 541 Mock4JS.verifyAllMocks(); |
| 542 |
| 543 // Step 2. Add 2nd task. Since it doesn't conflict with currently running |
| 544 // task1 (see areTasksConflicting), it should not be ignored. |
| 545 test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2); |
| 546 Mock4JS.verifyAllMocks(); |
| 547 |
| 548 // Step 3. Enter the callback of task1. |
| 549 task1PluginInstance.prologue(); |
| 550 Mock4JS.verifyAllMocks(); |
| 551 |
| 552 // Step 4. Leave the callback of task1. |
| 553 // Expectations. |
| 554 this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| 555 // Invocation. |
| 556 task1PluginInstance.epilogue(); |
| 557 }); |
| 558 |
| 559 TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerBranching', function() { |
| 560 // Tests that task manager correctly detects completion of tasks that create |
| 561 // branching chains of callbacks (in this test, task1 creates pending |
| 562 // callbacks 1 and 2, and callback 1 creates pending callback 3). |
| 563 |
| 564 // Setup. |
| 565 var test = setUpTaskManagerTest(this); |
| 566 var task1PluginInstance1, task1PluginInstance2, task1PluginInstance3; |
| 567 |
| 568 // Step 1. Add 1st task that creates a 2 pending callbacks. |
| 569 // Expectations. |
| 570 this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| 571 will(callFunction(function() { |
| 572 task1PluginInstance1 = test.pluginFactory(); |
| 573 task1PluginInstance2 = test.pluginFactory(); |
| 574 })); |
| 575 // Invocation. |
| 576 test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| 577 Mock4JS.verifyAllMocks(); |
| 578 |
| 579 // Step 2. Add 2nd task, which is not conflicting (see areTasksConflicting) |
| 580 // with task1. |
| 581 test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2); |
| 582 Mock4JS.verifyAllMocks(); |
| 583 |
| 584 // Step 3. Enter callback 1, create pending callback 3, exit callback 1. |
| 585 // Enter/exit callback 2. Enter callback 3. |
| 586 task1PluginInstance1.prologue(); |
| 587 task1PluginInstance3 = test.pluginFactory(); |
| 588 task1PluginInstance1.epilogue(); |
| 589 task1PluginInstance2.prologue(); |
| 590 task1PluginInstance2.epilogue(); |
| 591 task1PluginInstance3.prologue(); |
| 592 Mock4JS.verifyAllMocks(); |
| 593 |
| 594 // Step 4. Leave 3rd callback of task1. Now task1 is complete, and task2 |
| 595 // should start. |
| 596 // Expectations. |
| 597 this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| 598 // Invocation. |
| 599 task1PluginInstance3.epilogue(); |
| 600 }); |
| 601 |
| 602 TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerSuspendError', function() { |
| 603 // Tests that task manager's onSuspend method reports an error if there are |
| 604 // pending tasks. |
| 605 |
| 606 // Setup. |
| 607 var test = setUpTaskManagerTest(this); |
| 608 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); |
| 609 |
| 610 // Step 1. Add a task that creates a pending callback. |
| 611 // Expectations. |
| 612 this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| 613 will(callFunction(function() { |
| 614 test.pluginFactory(); |
| 615 })); |
| 616 // Invocation. |
| 617 test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| 618 Mock4JS.verifyAllMocks(); |
| 619 |
| 620 // Step 2. Invoke onSuspend event of the task manager. |
| 621 // Setup and expectations. The 2 callbacks in onSuspendHandlerContainer are |
| 622 // from the wrapper and the task manager. |
| 623 assertTrue(onSuspendHandlerContainer.length == 2, |
| 624 'onSuspendHandlerContainer.length must be 2'); |
| 625 this.mockGlobals.expects(once()).reportError(eqToString( |
| 626 'Error: ASSERT: Incomplete task when unloading event page,' + |
| 627 ' queue = [{"name":"TASK A"}], testWrapperDebugState')); |
| 628 // Invocation. |
| 629 onSuspendHandlerContainer[1](); |
| 630 }); |
| 631 |
| 632 TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerSuspendSuccess', function() { |
| 633 // Tests that task manager's onSuspend method does not report an error if all |
| 634 // tasks completed. |
| 635 |
| 636 // Setup. |
| 637 var test = setUpTaskManagerTest(this); |
| 638 var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); |
| 639 var task1PluginInstance; |
| 640 |
| 641 // Step 1. Add a task that creates a pending callback. |
| 642 // Expectations. |
| 643 this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| 644 will(callFunction(function() { |
| 645 task1PluginInstance = test.pluginFactory(); |
| 646 })); |
| 647 // Invocation. |
| 648 test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| 649 Mock4JS.verifyAllMocks(); |
| 650 |
| 651 // Step 2. Invoke task's callback and the onSuspend event of the task manager. |
| 652 // The 2 callbacks in onSuspendHandlerContainer are from the wrapper and the |
| 653 // task manager. |
| 654 task1PluginInstance.prologue(); |
| 655 task1PluginInstance.epilogue(); |
| 656 onSuspendHandlerContainer[1](); |
| 657 }); |
| 658 |
| 659 TEST_F('GoogleNowUtilityUnitTest', 'TaskManager3Tasks', function() { |
| 660 // Tests that 3 tasks can be executed too. In particular, that if the second |
| 661 // task is a single-step task which execution was originally blocked by task1, |
| 662 // unblocking it causes immediate synchronous execution of both tasks 2 and 3. |
| 663 |
| 664 // Setup. |
| 665 var test = setUpTaskManagerTest(this); |
| 666 var task1PluginInstance; |
| 667 |
| 668 // Step 1. Add 1st task that creates a pending callback. |
| 669 // Expectations. |
| 670 this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| 671 will(callFunction(function() { |
| 672 task1PluginInstance = test.pluginFactory(); |
| 673 })); |
| 674 // Invocation. |
| 675 test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| 676 Mock4JS.verifyAllMocks(); |
| 677 |
| 678 // Step 2. Add 2nd and 3rd tasks, both non-conflicting (see |
| 679 // areTasksConflicting) with task1. |
| 680 test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2); |
| 681 test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task3); |
| 682 Mock4JS.verifyAllMocks(); |
| 683 |
| 684 // Step 3. Enter the callback of task1. |
| 685 task1PluginInstance.prologue(); |
| 686 Mock4JS.verifyAllMocks(); |
| 687 |
| 688 // Step 4. Leave the callback of task1. |
| 689 // Expectations. |
| 690 this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| 691 this.mockLocalFunctions.expects(once()).task3(ANYTHING); |
| 692 // Invocation. |
| 693 task1PluginInstance.epilogue(); |
| 694 }); |
| 695 |
| 696 TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerNestedNonTask', function() { |
| 697 // Tests callbacks requested while a task is running, but not from a callback |
| 698 // belonging to a task, are not counted as a part of the task. |
| 699 |
| 700 // Setup. |
| 701 var test = setUpTaskManagerTest(this); |
| 702 var task1PluginInstance; |
| 703 |
| 704 // Step 1. Add 1st task that creates a pending callback. |
| 705 // Expectations. |
| 706 this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| 707 will(callFunction(function() { |
| 708 task1PluginInstance = test.pluginFactory(); |
| 709 })); |
| 710 // Invocation. |
| 711 test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| 712 Mock4JS.verifyAllMocks(); |
| 713 |
| 714 // Step 2. Create a pending callback from code that is not a part of the task. |
| 715 test.pluginFactory(); |
| 716 Mock4JS.verifyAllMocks(); |
| 717 |
| 718 // Step 3. Enter the callback of task1. After this, task1 should be |
| 719 // finished despite the pending non-task callback. |
| 720 task1PluginInstance.prologue(); |
| 721 task1PluginInstance.epilogue(); |
| 722 Mock4JS.verifyAllMocks(); |
| 723 |
| 724 // Step 4. Check that task1 is finished by submitting task2, which should |
| 725 // be executed immediately. |
| 726 this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| 727 test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2); |
| 728 }); |
| OLD | NEW |