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 |