Chromium Code Reviews| Index: chrome/browser/resources/google_now/utility_unittest.gtestjs |
| diff --git a/chrome/browser/resources/google_now/utility_unittest.gtestjs b/chrome/browser/resources/google_now/utility_unittest.gtestjs |
| index 86cc6c6a302a32081c608fb3c18981502fa7d478..00a8dca695783f0ad26d09809d1e5511b28668ac 100644 |
| --- a/chrome/browser/resources/google_now/utility_unittest.gtestjs |
| +++ b/chrome/browser/resources/google_now/utility_unittest.gtestjs |
| @@ -426,3 +426,293 @@ TEST_F('GoogleNowUtilityUnitTest', |
| 'onSuspendHandlerContainer.length must be 1'); |
| onSuspendHandlerContainer[0](); |
| }); |
| + |
| +var taskNameA = 'TASK A'; |
| +var taskNameB = 'TASK B'; |
| +var taskNameC = 'TASK C'; |
| + |
| +function areTasksConflicting(newTaskName, scheduledTaskName) { |
| + return newTaskName == taskNameB && scheduledTaskName == taskNameA; |
| +} |
| + |
| +function setUpTaskManagerTest(fixture) { |
| + // We want to mock wrapper using makeAndRegisterMockApis(), which requires |
| + // the mocked functions to not exist as a precondition. Resetting 'wrapper' to |
| + // 'undefined'. |
| + wrapper = undefined; |
| + |
| + fixture.makeAndRegisterMockApis([ |
| + 'wrapper.checkInWrappedCallback', |
| + 'wrapper.registerWrapperPluginFactory', |
| + 'wrapper.debugGetStateString' |
| + ]); |
| + fixture.makeMockLocalFunctions(['task1', 'task2', 'task3']); |
| + fixture.makeAndRegisterMockGlobals(['reportError']); |
| + |
| + fixture.mockApis.stubs().wrapper_checkInWrappedCallback(); |
| + fixture.mockApis.stubs().wrapper_debugGetStateString(). |
| + will(returnValue('testWrapperDebugState')); |
| + |
| + var registerWrapperPluginFactorySavedArgs = new SaveMockArguments(); |
| + fixture.mockApis.expects(once()).wrapper_registerWrapperPluginFactory( |
| + registerWrapperPluginFactorySavedArgs.match(ANYTHING)); |
| + var tasks = buildTaskManager(areTasksConflicting); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + return { |
| + tasks: tasks, |
| + pluginFactory: registerWrapperPluginFactorySavedArgs.arguments[0] |
| + }; |
| +} |
| + |
| +TEST_F('GoogleNowUtilityUnitTest', 'TaskManager2Sequential', function() { |
| + // Tests that 2 tasks get successfully executed consequentially, even if the |
| + // second one conflicts with the first. |
| + |
| + // Setup. |
| + var test = setUpTaskManagerTest(this); |
| + |
| + // Step 1. Adding 1st task that doesn't create pending callbacks. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task1(ANYTHING); |
| + // Invocation. |
| + test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 2. Adding 2nd task. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| + // Invocation. |
| + test.tasks.add(taskNameB, this.mockLocalFunctions.functions().task2); |
| +}); |
| + |
| +TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerConflicting', function() { |
| + // Tests that adding a task while a conflicting task is being executed, causes |
| + // the second one to be ignored. |
| + |
| + // Setup. |
| + var test = setUpTaskManagerTest(this); |
| + var task1PluginInstance; |
| + |
| + // Step 1. Adding 1st task that creates a pending callback. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| + will(callFunction(function() { |
| + task1PluginInstance = test.pluginFactory(); |
| + })); |
| + // Invocation. |
| + test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 2. Adding 2nd task. |
| + test.tasks.add(taskNameB, this.mockLocalFunctions.functions().task2); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 3. Entering the callback of task1. |
| + task1PluginInstance.prologue(); |
|
robliao
2013/09/03 23:23:31
It is worth a discussion as to what makes this tes
vadimt
2013/09/04 00:29:16
You mean what's the difference from TaskManager2Se
robliao
2013/09/04 00:54:00
That's the idea. A bit of the mechanics should be
vadimt
2013/09/04 01:40:15
Done.
robliao
2013/09/04 17:02:03
Where was this done?
On 2013/09/04 01:40:15, vadim
vadimt
2013/09/04 17:21:37
CR tool may not show you the latest uploaded versi
|
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 4. Leaving the callback of task1. |
| + task1PluginInstance.epilogue(); |
| +}); |
| + |
| +TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerNestedTaskEnqueue', function() { |
| + // Tests that adding a task while a non-conflicting task is being executed, |
| + // causes the second one to be executed after the first one completes. |
| + |
| + // Setup. |
| + var test = setUpTaskManagerTest(this); |
| + var task1PluginInstance; |
| + |
| + // Step 1. Adding 1st task that creates a pending callback. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| + will(callFunction(function() { |
| + task1PluginInstance = test.pluginFactory(); |
| + })); |
| + // Invocation. |
| + test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 2. Adding 2nd task. |
| + test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2); |
|
robliao
2013/09/03 23:23:31
Why not taskNameB?
vadimt
2013/09/04 00:29:16
taskNameB conflicts with taskNameA, while taskName
robliao
2013/09/04 00:54:00
Future readers will ask this question since the co
vadimt
2013/09/04 01:40:15
Done.
|
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 3. Entering the callback of task1. |
| + task1PluginInstance.prologue(); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 4. Leaving the callback of task1. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| + // Invocation. |
| + task1PluginInstance.epilogue(); |
| +}); |
| + |
| +TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerBranching', function() { |
| + // Tests that task manager correctly detects completion of tasks that create |
| + // branching chains of callbacks. |
|
robliao
2013/09/03 23:23:31
Detail the tested branching pattern.
vadimt
2013/09/04 00:29:16
Done.
|
| + |
| + // Setup. |
| + var test = setUpTaskManagerTest(this); |
| + var task1PluginInstance1, task1PluginInstance2, task1PluginInstance3; |
| + |
| + // Step 1. Adding 1st task that creates a 2 pending callbacks. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| + will(callFunction(function() { |
| + task1PluginInstance1 = test.pluginFactory(); |
| + task1PluginInstance2 = test.pluginFactory(); |
| + })); |
| + // Invocation. |
| + test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 2. Adding 2nd task. |
| + test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2); |
|
robliao
2013/09/03 23:23:31
taskNameB?
vadimt
2013/09/04 00:29:16
Need 'C' because 'B' is conflicting and would be i
robliao
2013/09/04 00:54:00
That's not obvious from a reading of the test case
vadimt
2013/09/04 01:40:15
Done.
|
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 3. Entering callback 1, create pending callback 3, exit callback 1. |
| + // Enter/exit callback 2. Enter callback 3. |
| + task1PluginInstance1.prologue(); |
| + task1PluginInstance3 = test.pluginFactory(); |
| + task1PluginInstance1.epilogue(); |
| + task1PluginInstance2.prologue(); |
| + task1PluginInstance2.epilogue(); |
| + task1PluginInstance3.prologue(); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 4. Leaving 3rd callback of task1. Now task1 is complete, and task2 |
| + // should start. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| + // Invocation. |
| + task1PluginInstance3.epilogue(); |
| +}); |
| + |
| +TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerSuspendError', function() { |
| + // Tests that task manager's onSuspend method reports an error if there are |
| + // pending tasks. |
| + |
| + // Setup. |
| + var test = setUpTaskManagerTest(this); |
| + var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); |
| + |
| + // Step 1. Adding a task that creates a pending callback. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| + will(callFunction(function() { |
| + test.pluginFactory(); |
| + })); |
| + // Invocation. |
| + test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 2. Invoke onSuspend event of the task manager. |
| + // Setup and expectations. The 2 callbacks in onSuspendHandlerContainer are |
| + // from the wrapper and the task manager. |
| + assertTrue(onSuspendHandlerContainer.length == 2, |
| + 'onSuspendHandlerContainer.length must be 2'); |
| + this.mockGlobals.expects(once()).reportError(eqToString( |
| + 'Error: ASSERT: Incomplete task when unloading event page,' + |
| + ' queue = [{"name":"TASK A"}], testWrapperDebugState')); |
| + // Invocation. |
| + onSuspendHandlerContainer[1](); |
| +}); |
| + |
| +TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerSuspendSuccess', function() { |
| + // Tests that task manager's onSuspend method does not reports an error if all |
| + // tasks completed. |
| + |
| + // Setup. |
| + var test = setUpTaskManagerTest(this); |
| + var onSuspendHandlerContainer = getMockHandlerContainer('runtime.onSuspend'); |
|
robliao
2013/09/03 23:23:31
Where is getMockHandlerContainer defined? Code sea
vadimt
2013/09/04 00:29:16
In https://codereview.chromium.org/23477006/diff/3
|
| + var task1PluginInstance; |
| + |
| + // Step 1. Adding a task that creates a pending callback. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| + will(callFunction(function() { |
| + task1PluginInstance = test.pluginFactory(); |
| + })); |
| + // Invocation. |
| + test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 2. Invoke task's callback and the onSuspend event of the task manager. |
| + // The 2 callbacks in onSuspendHandlerContainer are from the wrapper and the |
| + // task manager. |
| + task1PluginInstance.prologue(); |
| + task1PluginInstance.epilogue(); |
| + onSuspendHandlerContainer[1](); |
| +}); |
| + |
| +TEST_F('GoogleNowUtilityUnitTest', 'TaskManager3Tasks', function() { |
| + // Tests that 3 tasks can be executed too. In particular, that if the second |
| + // task is a single-step task which execution was originally blocked by task1, |
| + // unblocking it causes immediate synchronous execution of both tasks 2 and 3. |
| + |
| + // Setup. |
| + var test = setUpTaskManagerTest(this); |
| + var task1PluginInstance; |
| + |
| + // Step 1. Adding 1st task that creates a pending callback. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| + will(callFunction(function() { |
| + task1PluginInstance = test.pluginFactory(); |
| + })); |
| + // Invocation. |
| + test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 2. Adding 2nd and 3rd tasks. |
| + test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2); |
|
robliao
2013/09/03 23:23:31
taskNameB?
vadimt
2013/09/04 00:29:16
Se above about conflicts.
|
| + test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task3); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 3. Entering the callback of task1. |
| + task1PluginInstance.prologue(); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 4. Leaving the callback of task1. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| + this.mockLocalFunctions.expects(once()).task3(ANYTHING); |
| + // Invocation. |
| + task1PluginInstance.epilogue(); |
| +}); |
| + |
| +TEST_F('GoogleNowUtilityUnitTest', 'TaskManagerNestedNonTask', function() { |
| + // Tests callbacks requested while a task is running, but not from a callback |
| + // belonging to a task, are not counted as a part of the task. |
| + |
| + // Setup. |
| + var test = setUpTaskManagerTest(this); |
| + var task1PluginInstance, nonTaskPluginInstance; |
| + |
| + // Step 1. Adding 1st task that creates a pending callback. |
| + // Expectations. |
| + this.mockLocalFunctions.expects(once()).task1(ANYTHING). |
| + will(callFunction(function() { |
| + task1PluginInstance = test.pluginFactory(); |
| + })); |
| + // Invocation. |
| + test.tasks.add(taskNameA, this.mockLocalFunctions.functions().task1); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 2. Code that is not a part of the task creates a pending callback. |
| + nonTaskPluginInstance = test.pluginFactory(); |
|
robliao
2013/09/03 23:23:31
This variable is never read. Necessary?
vadimt
2013/09/04 00:29:16
Thanks!
|
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 3. Entering the callback of task1. After this, task1 should be |
| + // finished despite the pending non-task callback. |
| + task1PluginInstance.prologue(); |
| + task1PluginInstance.epilogue(); |
| + Mock4JS.verifyAllMocks(); |
| + |
| + // Step 4. Checking that task1 is finished by submitting task2, which should |
| + // be executed immediately. |
| + this.mockLocalFunctions.expects(once()).task2(ANYTHING); |
| + test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2); |
| +}); |