| 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..06d0f30261e45c3f55cc322c47efd5045dab8ec9 100644
|
| --- a/chrome/browser/resources/google_now/utility_unittest.gtestjs
|
| +++ b/chrome/browser/resources/google_now/utility_unittest.gtestjs
|
| @@ -426,3 +426,301 @@ 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) {
|
| + // Task B is conflicting with Task A. This means that if Task B is added when
|
| + // Task A is running, Task B will be ignored (but not vice versa). No other
|
| + // pair is conflicting.
|
| + 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. Since it conflicts with currently running task1
|
| + // (see areTasksConflicting), it should be ignored.
|
| + test.tasks.add(taskNameB, this.mockLocalFunctions.functions().task2);
|
| + Mock4JS.verifyAllMocks();
|
| +
|
| + // Step 3. Entering the callback of task1.
|
| + task1PluginInstance.prologue();
|
| + 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. Since it doesn't conflict with currently running
|
| + // task1 (see areTasksConflicting), it should not be ignored.
|
| + test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2);
|
| + 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 (in this test, task1 creates pending
|
| + // callbacks 1 and 2, and callback 1 creates pending callback 3).
|
| +
|
| + // 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, which is not conflicting (see areTasksConflicting)
|
| + // with task1.
|
| + test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2);
|
| + 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');
|
| + 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, both non-conflicting (see
|
| + // areTasksConflicting) with task1.
|
| + test.tasks.add(taskNameC, this.mockLocalFunctions.functions().task2);
|
| + 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;
|
| +
|
| + // 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.
|
| + test.pluginFactory();
|
| + 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);
|
| +});
|
|
|