| Index: chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
|
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..85a0de8a6aee9b11dae741e73d5625f33d9995a1
|
| --- /dev/null
|
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
|
| @@ -0,0 +1,1414 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.chrome.browser.tabmodel;
|
| +
|
| +import android.test.FlakyTest;
|
| +import android.test.suitebuilder.annotation.MediumTest;
|
| +
|
| +
|
| +import org.chromium.base.CommandLine;
|
| +import org.chromium.base.ThreadUtils;
|
| +import org.chromium.chrome.browser.ChromeSwitches;
|
| +import org.chromium.chrome.browser.Tab;
|
| +import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
|
| +import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
|
| +import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
|
| +import org.chromium.content.browser.test.util.CallbackHelper;
|
| +import org.chromium.content_public.browser.LoadUrlParams;
|
| +
|
| +import java.util.concurrent.TimeoutException;
|
| +
|
| +/**
|
| + * Tests undo and restoring of tabs in a {@link TabModel}.
|
| + */
|
| +public class UndoTabModelTest extends ChromeTabbedActivityTestBase {
|
| + private static final Tab[] EMPTY = new Tab[] { };
|
| +
|
| + @Override
|
| + public void startMainActivity() throws InterruptedException {
|
| + CommandLine.getInstance().appendSwitch(ChromeSwitches.ENABLE_HIGH_END_UI_UNDO);
|
| + startMainActivityOnBlankPage();
|
| + }
|
| +
|
| + private void checkState(
|
| + final TabModel model, final Tab[] tabsList, final Tab selectedTab,
|
| + final Tab[] closingTabs, final Tab[] fullTabsList,
|
| + final Tab fullSelectedTab) {
|
| + // Keeping these checks on the test thread so the stacks are useful for identifying
|
| + // failures.
|
| +
|
| + // Check the selected tab.
|
| + assertEquals("Wrong selected tab", selectedTab, TabModelUtils.getCurrentTab(model));
|
| +
|
| + // Check the list of tabs.
|
| + assertEquals("Incorrect number of tabs", tabsList.length, model.getCount());
|
| + for (int i = 0; i < tabsList.length; i++) {
|
| + assertEquals("Unexpected tab at " + i, tabsList[i].getId(), model.getTabAt(i).getId());
|
| + }
|
| +
|
| + // Check the list of tabs we expect to be closing.
|
| + for (int i = 0; i < closingTabs.length; i++) {
|
| + int id = closingTabs[i].getId();
|
| + assertTrue("Tab " + id + " not in closing list", model.isClosurePending(id));
|
| + }
|
| +
|
| + TabList fullModel = model.getComprehensiveModel();
|
| +
|
| + // Check the comprehensive selected tab.
|
| + assertEquals("Wrong selected tab", fullSelectedTab, TabModelUtils.getCurrentTab(fullModel));
|
| +
|
| + // Check the comprehensive list of tabs.
|
| + assertEquals("Incorrect number of tabs", fullTabsList.length, fullModel.getCount());
|
| + for (int i = 0; i < fullModel.getCount(); i++) {
|
| + int id = fullModel.getTabAt(i).getId();
|
| + assertEquals("Unexpected tab at " + i, fullTabsList[i].getId(), id);
|
| + }
|
| + }
|
| +
|
| + private void createTabOnUiThread(final ChromeTabCreator tabCreator) {
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + tabCreator.createNewTab(new LoadUrlParams("about:blank"),
|
| + TabLaunchType.FROM_MENU_OR_OVERVIEW, null);
|
| + }
|
| + });
|
| + }
|
| +
|
| + private void selectTabOnUiThread(final TabModel model, final Tab tab) {
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + model.setIndex(model.indexOf(tab), TabSelectionType.FROM_USER);
|
| + }
|
| + });
|
| + }
|
| +
|
| + private void closeTabOnUiThread(
|
| + final TabModel model, final Tab tab, final boolean undoable)
|
| + throws InterruptedException {
|
| + // Check preconditions.
|
| + assertFalse(tab.isClosing());
|
| + assertTrue(tab.isInitialized());
|
| + assertFalse(model.isClosurePending(tab.getId()));
|
| + assertNotNull(TabModelUtils.getTabById(model, tab.getId()));
|
| +
|
| + final CallbackHelper didReceivePendingClosureHelper = new CallbackHelper();
|
| + model.addObserver(new EmptyTabModelObserver() {
|
| + @Override
|
| + public void tabPendingClosure(Tab tab) {
|
| + didReceivePendingClosureHelper.notifyCalled();
|
| + }
|
| + });
|
| +
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + // Take action.
|
| + model.closeTab(tab, true, false, undoable);
|
| + }
|
| + });
|
| +
|
| + boolean didUndo = undoable && model.supportsPendingClosures();
|
| +
|
| + // Make sure the TabModel throws a tabPendingClosure callback if necessary.
|
| + if (didUndo) {
|
| + try {
|
| + didReceivePendingClosureHelper.waitForCallback(0);
|
| + } catch (TimeoutException e) {
|
| + fail();
|
| + }
|
| + }
|
| +
|
| + // Check post conditions
|
| + assertEquals(didUndo, model.isClosurePending(tab.getId()));
|
| + assertNull(TabModelUtils.getTabById(model, tab.getId()));
|
| + assertTrue(tab.isClosing());
|
| + assertEquals(didUndo, tab.isInitialized());
|
| + }
|
| +
|
| + private void closeAllTabsOnUiThread(final TabModel model) {
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + model.closeAllTabs();
|
| + }
|
| + });
|
| + }
|
| +
|
| + private void moveTabOnUiThread(final TabModel model, final Tab tab, final int newIndex) {
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + model.moveTab(tab.getId(), newIndex);
|
| + }
|
| + });
|
| + }
|
| +
|
| + private void cancelTabClosureOnUiThread(final TabModel model, final Tab tab)
|
| + throws InterruptedException {
|
| + // Check preconditions.
|
| + assertTrue(tab.isClosing());
|
| + assertTrue(tab.isInitialized());
|
| + assertTrue(model.isClosurePending(tab.getId()));
|
| + assertNull(TabModelUtils.getTabById(model, tab.getId()));
|
| +
|
| + final CallbackHelper didReceiveClosureCancelledHelper = new CallbackHelper();
|
| + model.addObserver(new EmptyTabModelObserver() {
|
| + @Override
|
| + public void tabClosureUndone(Tab tab) {
|
| + didReceiveClosureCancelledHelper.notifyCalled();
|
| + }
|
| + });
|
| +
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + // Take action.
|
| + model.cancelTabClosure(tab.getId());
|
| + }
|
| + });
|
| +
|
| + // Make sure the TabModel throws a tabClosureUndone.
|
| + try {
|
| + didReceiveClosureCancelledHelper.waitForCallback(0);
|
| + } catch (TimeoutException e) {
|
| + fail();
|
| + }
|
| +
|
| + // Check post conditions.
|
| + assertFalse(model.isClosurePending(tab.getId()));
|
| + assertNotNull(TabModelUtils.getTabById(model, tab.getId()));
|
| + assertFalse(tab.isClosing());
|
| + assertTrue(tab.isInitialized());
|
| + }
|
| +
|
| + private void cancelAllTabClosuresOnUiThread(final TabModel model, final Tab[] expectedToClose)
|
| + throws InterruptedException {
|
| + final CallbackHelper tabClosureUndoneHelper = new CallbackHelper();
|
| +
|
| + for (int i = 0; i < expectedToClose.length; i++) {
|
| + Tab tab = expectedToClose[i];
|
| + assertTrue(tab.isClosing());
|
| + assertTrue(tab.isInitialized());
|
| + assertTrue(model.isClosurePending(tab.getId()));
|
| + assertNull(TabModelUtils.getTabById(model, tab.getId()));
|
| +
|
| + // Make sure that this TabModel throws the right events.
|
| + model.addObserver(new EmptyTabModelObserver() {
|
| + @Override
|
| + public void tabClosureUndone(Tab currentTab) {
|
| + tabClosureUndoneHelper.notifyCalled();
|
| + }
|
| + });
|
| + }
|
| +
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + for (int i = 0; i < expectedToClose.length; i++) {
|
| + Tab tab = expectedToClose[i];
|
| + model.cancelTabClosure(tab.getId());
|
| + }
|
| + }
|
| + });
|
| +
|
| + try {
|
| + tabClosureUndoneHelper.waitForCallback(0, expectedToClose.length);
|
| + } catch (TimeoutException e) {
|
| + fail();
|
| + }
|
| +
|
| + for (int i = 0; i < expectedToClose.length; i++) {
|
| + final Tab tab = expectedToClose[i];
|
| + assertFalse(model.isClosurePending(tab.getId()));
|
| + assertNotNull(TabModelUtils.getTabById(model, tab.getId()));
|
| + assertFalse(tab.isClosing());
|
| + assertTrue(tab.isInitialized());
|
| + }
|
| + }
|
| +
|
| + private void commitTabClosureOnUiThread(final TabModel model, final Tab tab)
|
| + throws InterruptedException {
|
| + // Check preconditions.
|
| + assertTrue(tab.isClosing());
|
| + assertTrue(tab.isInitialized());
|
| + assertTrue(model.isClosurePending(tab.getId()));
|
| + assertNull(TabModelUtils.getTabById(model, tab.getId()));
|
| +
|
| + final CallbackHelper didReceiveClosureCommittedHelper = new CallbackHelper();
|
| + model.addObserver(new EmptyTabModelObserver() {
|
| + @Override
|
| + public void tabClosureCommitted(Tab tab) {
|
| + didReceiveClosureCommittedHelper.notifyCalled();
|
| + }
|
| + });
|
| +
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + // Take action.
|
| + model.commitTabClosure(tab.getId());
|
| + }
|
| + });
|
| +
|
| + // Make sure the TabModel throws a tabClosureCommitted.
|
| + try {
|
| + didReceiveClosureCommittedHelper.waitForCallback(0);
|
| + } catch (TimeoutException e) {
|
| + fail();
|
| + }
|
| +
|
| + // Check post conditions
|
| + assertFalse(model.isClosurePending(tab.getId()));
|
| + assertNull(TabModelUtils.getTabById(model, tab.getId()));
|
| + assertTrue(tab.isClosing());
|
| + assertFalse(tab.isInitialized());
|
| + }
|
| +
|
| + private void commitAllTabClosuresOnUiThread(final TabModel model, Tab[] expectedToClose)
|
| + throws InterruptedException {
|
| + final CallbackHelper tabClosureCommittedHelper = new CallbackHelper();
|
| +
|
| + for (int i = 0; i < expectedToClose.length; i++) {
|
| + Tab tab = expectedToClose[i];
|
| + assertTrue(tab.isClosing());
|
| + assertTrue(tab.isInitialized());
|
| + assertTrue(model.isClosurePending(tab.getId()));
|
| +
|
| + // Make sure that this TabModel throws the right events.
|
| + model.addObserver(new EmptyTabModelObserver() {
|
| + @Override
|
| + public void tabClosureCommitted(Tab currentTab) {
|
| + tabClosureCommittedHelper.notifyCalled();
|
| + }
|
| + });
|
| + }
|
| +
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + model.commitAllTabClosures();
|
| + }
|
| + });
|
| +
|
| + try {
|
| + tabClosureCommittedHelper.waitForCallback(0, expectedToClose.length);
|
| + } catch (TimeoutException e) {
|
| + fail();
|
| + }
|
| + for (int i = 0; i < expectedToClose.length; i++) {
|
| + final Tab tab = expectedToClose[i];
|
| + assertTrue(tab.isClosing());
|
| + assertFalse(tab.isInitialized());
|
| + assertFalse(model.isClosurePending(tab.getId()));
|
| + }
|
| + }
|
| +
|
| + private void saveStateOnUiThread(final TabModelSelector selector) {
|
| + ThreadUtils.runOnUiThreadBlocking(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + ((TabModelSelectorImpl) selector).saveState();
|
| + }
|
| + });
|
| +
|
| + for (int i = 0; i < selector.getModels().size(); i++) {
|
| + TabList tabs = selector.getModelAt(i).getComprehensiveModel();
|
| + for (int j = 0; j < tabs.getCount(); j++) {
|
| + assertFalse(tabs.isClosurePending(tabs.getTabAt(j).getId()));
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Test undo with a single tab with the following actions/expected states:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0s ] - [ 0s ]
|
| + * 2. CloseTab(0, allow undo) - [ 0 ] [ 0s ]
|
| + * 3. CancelClose(0) [ 0s ] - [ 0s ]
|
| + * 4. CloseTab(0, allow undo) - [ 0 ] [ 0s ]
|
| + * 5. CommitClose(0) - - -
|
| + * 6. CreateTab(0) [ 0s ] - [ 0s ]
|
| + * 7. CloseTab(0, allow undo) - [ 0 ] [ 0s ]
|
| + * 8. CommitAllClose - - -
|
| + * 9. CreateTab(0) [ 0s ] - [ 0s ]
|
| + * 10. CloseTab(0, disallow undo) - - -
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testSingleTab() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0 }, fullList, tab0);
|
| +
|
| + // 3.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 4.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0 }, fullList, tab0);
|
| +
|
| + // 5.
|
| + commitTabClosureOnUiThread(model, tab0);
|
| + fullList = EMPTY;
|
| + checkState(model, EMPTY, null, EMPTY, EMPTY, null);
|
| +
|
| + // 6.
|
| + createTabOnUiThread(tabCreator);
|
| + tab0 = model.getTabAt(0);
|
| + fullList = new Tab[] { tab0 };
|
| + checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 7.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0 }, fullList, tab0);
|
| +
|
| + // 8.
|
| + commitAllTabClosuresOnUiThread(model, new Tab[] { tab0 });
|
| + fullList = EMPTY;
|
| + checkState(model, EMPTY, null, EMPTY, EMPTY, null);
|
| +
|
| + // 9.
|
| + createTabOnUiThread(tabCreator);
|
| + tab0 = model.getTabAt(0);
|
| + fullList = new Tab[] { tab0 };
|
| + checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 10.
|
| + closeTabOnUiThread(model, tab0, false);
|
| + fullList = EMPTY;
|
| + checkState(model, EMPTY, null, EMPTY, fullList, null);
|
| + assertTrue(tab0.isClosing());
|
| + assertFalse(tab0.isInitialized());
|
| + }
|
| +
|
| + /**
|
| + * Flaky on instrumentation-nakasi-clankium. See http://crbug.com/417720.
|
| + *
|
| + * Test undo with two tabs with the following actions/expected states:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1s ] - [ 0 1s ]
|
| + * 2. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 0 1s ]
|
| + * 3. CancelClose(0) [ 0s 1 ] - [ 0s 1 ]
|
| + * 4. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 0 1s ]
|
| + * 5. CloseTab(1, allow undo) - [ 1 0 ] [ 0 1s ]
|
| + * 6. CancelClose(1) [ 1s ] [ 0 ] [ 0s 1 ]
|
| + * 7. CancelClose(0) [ 0s 1 ] - [ 0s 1 ]
|
| + * 8. CloseTab(1, allow undo) [ 0s ] [ 1 ] [ 0s 1 ]
|
| + * 9. CloseTab(0, allow undo) - [ 0 1 ] [ 0s 1 ]
|
| + * 10. CancelClose(1) [ 1s ] [ 0 ] [ 0 1s ]
|
| + * 11. CancelClose(0) [ 0s 1 ] - [ 0s 1 ]
|
| + * 12. CloseTab(1, allow undo) [ 0s ] [ 1 ] [ 0s 1 ]
|
| + * 13. CloseTab(0, allow undo) - [ 0 1 ] [ 0s 1 ]
|
| + * 14. CancelClose(0) [ 0s ] [ 1 ] [ 0s 1 ]
|
| + * 15. CloseTab(0, allow undo) - [ 0 1 ] [ 0s 1 ]
|
| + * 16. CancelClose(0) [ 0s ] [ 1 ] [ 0s 1 ]
|
| + * 17. CancelClose(1) [ 0 1s ] - [ 0 1s ]
|
| + * 18. CloseTab(0, disallow undo) [ 1s ] - [ 1s ]
|
| + * 19. CreateTab(0) [ 1 0s ] - [ 1 0s ]
|
| + * 20. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 1s 0 ]
|
| + * 21. CommitClose(0) [ 1s ] - [ 1s ]
|
| + * 22. CreateTab(0) [ 1 0s ] - [ 1 0s ]
|
| + * 23. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 1s 0 ]
|
| + * 24. CloseTab(1, allow undo) - [ 1 0 ] [ 1s 0 ]
|
| + * 25. CommitAllClose - - -
|
| + *
|
| + * @throws InterruptedException
|
| + * @MediumTest
|
| + */
|
| + @FlakyTest
|
| + public void testTwoTabs() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList, tab1);
|
| +
|
| + // 3.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 4.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList, tab1);
|
| +
|
| + // 5.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0, tab1 }, fullList, tab0);
|
| +
|
| + // 6.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList, tab1);
|
| +
|
| + // 7.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 8.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1 }, fullList, tab0);
|
| +
|
| + // 9.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0, tab1 }, fullList, tab0);
|
| +
|
| + // 10.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList, tab1);
|
| +
|
| + // 11.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 12.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1 }, fullList, tab0);
|
| +
|
| + // 13.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0, tab1 }, fullList, tab0);
|
| +
|
| + // 14.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1 }, fullList, tab0);
|
| +
|
| + // 15.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0, tab1 }, fullList, tab0);
|
| +
|
| + // 16.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1 }, fullList, tab0);
|
| +
|
| + // 17.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 18.
|
| + closeTabOnUiThread(model, tab0, false);
|
| + fullList = new Tab[] { tab1 };
|
| + checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 19.
|
| + createTabOnUiThread(tabCreator);
|
| + tab0 = model.getTabAt(1);
|
| + fullList = new Tab[] { tab1, tab0 };
|
| + checkState(model, new Tab[] { tab1, tab0 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 20.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList, tab1);
|
| +
|
| + // 21.
|
| + commitTabClosureOnUiThread(model, tab0);
|
| + fullList = new Tab[] { tab1 };
|
| + checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 22.
|
| + createTabOnUiThread(tabCreator);
|
| + tab0 = model.getTabAt(1);
|
| + fullList = new Tab[] { tab1, tab0 };
|
| + checkState(model, new Tab[] { tab1, tab0 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 23.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList, tab1);
|
| +
|
| + // 24.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab1, tab0 }, fullList, tab1);
|
| +
|
| + // 25.
|
| + commitAllTabClosuresOnUiThread(model, new Tab[] { tab1, tab0 });
|
| + checkState(model, EMPTY, null, EMPTY, EMPTY, null);
|
| + }
|
| +
|
| + /**
|
| + * Test restoring in the same order of closing with the following actions/expected states:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(0, allow undo) [ 1 2 3s ] [ 0 ] [ 0 1 2 3s ]
|
| + * 3. CloseTab(1, allow undo) [ 2 3s ] [ 1 0 ] [ 0 1 2 3s ]
|
| + * 4. CloseTab(2, allow undo) [ 3s ] [ 2 1 0 ] [ 0 1 2 3s ]
|
| + * 5. CloseTab(3, allow undo) - [ 3 2 1 0 ] [ 0s 1 2 3 ]
|
| + * 6. CancelClose(3) [ 3s ] [ 2 1 0 ] [ 0 1 2 3s ]
|
| + * 7. CancelClose(2) [ 2s 3 ] [ 1 0 ] [ 0 1 2s 3 ]
|
| + * 8. CancelClose(1) [ 1s 2 3 ] [ 0 ] [ 0 1s 2 3 ]
|
| + * 9. CancelClose(0) [ 0s 1 2 3 ] - [ 0s 1 2 3 ]
|
| + * 10. SelectTab(3) [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 11. CloseTab(3, allow undo) [ 0 1 2s ] [ 3 ] [ 0 1 2s 3 ]
|
| + * 12. CloseTab(2, allow undo) [ 0 1s ] [ 2 3 ] [ 0 1s 2 3 ]
|
| + * 13. CloseTab(1, allow undo) [ 0s ] [ 1 2 3 ] [ 0s 1 2 3 ]
|
| + * 14. CloseTab(0, allow undo) - [ 0 1 2 3 ] [ 0s 1 2 3 ]
|
| + * 15. CancelClose(0) [ 0s ] [ 1 2 3 ] [ 0s 1 2 3 ]
|
| + * 16. CancelClose(1) [ 0 1s ] [ 2 3 ] [ 0 1s 2 3 ]
|
| + * 17. CancelClose(2) [ 0 1 2s ] [ 3 ] [ 0 1 2s 3 ]
|
| + * 18. CancelClose(3) [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 19. CloseTab(2, allow undo) [ 0 1 3s ] [ 2 ] [ 0 1 2 3s ]
|
| + * 20. CloseTab(0, allow undo) [ 1 3s ] [ 0 2 ] [ 0 1 2 3s ]
|
| + * 21. CloseTab(3, allow undo) [ 1s ] [ 3 0 2 ] [ 0 1s 2 3 ]
|
| + * 22. CancelClose(3) [ 1 3s ] [ 0 2 ] [ 0 1 2 3s ]
|
| + * 23. CancelClose(0) [ 0s 1 3 ] [ 2 ] [ 0s 1 2 3 ]
|
| + * 24. CancelClose(2) [ 0 1 2s 3 ] - [ 0 1 2s 3 ]
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testInOrderRestore() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + final Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1, tab2, tab3 }, tab3, new Tab[] { tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 3.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab2, tab3 }, tab3, new Tab[] { tab1, tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 4.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab2, tab1, tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 5.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab3, tab2, tab1, tab0 }, fullList, tab0);
|
| +
|
| + // 6.
|
| + cancelTabClosureOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab2, tab1, tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 7.
|
| + cancelTabClosureOnUiThread(model, tab2);
|
| + checkState(model, new Tab[] { tab2, tab3 }, tab2, new Tab[] { tab1, tab0 },
|
| + fullList, tab2);
|
| +
|
| + // 8.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab1, tab2, tab3 }, tab1, new Tab[] { tab0 },
|
| + fullList, tab1);
|
| +
|
| + // 9.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 10.
|
| + selectTabOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 11.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2 }, tab2, new Tab[] { tab3 },
|
| + fullList, tab2);
|
| +
|
| + // 12.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab2, tab3 },
|
| + fullList, tab1);
|
| +
|
| + // 13.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1, tab2, tab3 },
|
| + fullList, tab0);
|
| +
|
| + // 14.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0, tab1, tab2, tab3 }, fullList, tab0);
|
| +
|
| + // 15.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1, tab2, tab3 },
|
| + fullList, tab0);
|
| +
|
| + // 16.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab2, tab3 },
|
| + fullList, tab1);
|
| +
|
| + // 17.
|
| + cancelTabClosureOnUiThread(model, tab2);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2 }, tab2, new Tab[] { tab3 },
|
| + fullList, tab2);
|
| +
|
| + // 18.
|
| + cancelTabClosureOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 19.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab1, tab3 }, tab3, new Tab[] { tab2 },
|
| + fullList, tab3);
|
| +
|
| + // 20.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1, tab3 }, tab3, new Tab[] { tab0, tab2 },
|
| + fullList, tab3);
|
| +
|
| + // 21.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab3, tab0, tab2 },
|
| + fullList, tab1);
|
| +
|
| + // 22.
|
| + cancelTabClosureOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab1, tab3 }, tab3, new Tab[] { tab0, tab2 },
|
| + fullList, tab3);
|
| +
|
| + // 23.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0, tab1, tab3 }, tab0, new Tab[] { tab2 },
|
| + fullList, tab0);
|
| +
|
| + // 24.
|
| + cancelTabClosureOnUiThread(model, tab2);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab2, EMPTY, fullList, tab2);
|
| + }
|
| +
|
| +
|
| + /**
|
| + * Test restoring in the reverse of closing with the following actions/expected states:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(0, allow undo) [ 1 2 3s ] [ 0 ] [ 0 1 2 3s ]
|
| + * 3. CloseTab(1, allow undo) [ 2 3s ] [ 1 0 ] [ 0 1 2 3s ]
|
| + * 4. CloseTab(2, allow undo) [ 3s ] [ 2 1 0 ] [ 0 1 2 3s ]
|
| + * 5. CloseTab(3, allow undo) - [ 3 2 1 0 ] [ 0s 1 2 3 ]
|
| + * 6. CancelClose(0) [ 0s ] [ 3 2 1 ] [ 0s 1 2 3 ]
|
| + * 7. CancelClose(1) [ 0 1s ] [ 3 2 ] [ 0 1s 2 3 ]
|
| + * 8. CancelClose(2) [ 0 1 2s ] [ 3 ] [ 0 1 2s 3 ]
|
| + * 9. CancelClose(3) [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 10. CloseTab(3, allow undo) [ 0 1 2s ] [ 3 ] [ 0 1 2s 3 ]
|
| + * 11. CloseTab(2, allow undo) [ 0 1s ] [ 2 3 ] [ 0 1s 2 3 ]
|
| + * 12. CloseTab(1, allow undo) [ 0s ] [ 1 2 3 ] [ 0s 1 2 3 ]
|
| + * 13. CloseTab(0, allow undo) - [ 0 1 2 3 ] [ 0s 1 2 3 ]
|
| + * 14. CancelClose(3) [ 3s ] [ 0 1 2 ] [ 0 1 2 3s ]
|
| + * 15. CancelClose(2) [ 2s 3 ] [ 0 1 ] [ 0 1 2s 3 ]
|
| + * 16. CancelClose(1) [ 1s 2 3 ] [ 0 ] [ 0 1s 2 3 ]
|
| + * 17. CancelClose(0) [ 0s 1 2 3 ] - [ 0s 1 2 3 ]
|
| + * 18. SelectTab(3) [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 19. CloseTab(2, allow undo) [ 0 1 3s ] [ 2 ] [ 0 1 2 3s ]
|
| + * 20. CloseTab(0, allow undo) [ 1 3s ] [ 0 2 ] [ 0 1 2 3s ]
|
| + * 21. CloseTab(3, allow undo) [ 1s ] [ 3 0 2 ] [ 0 1s 2 3 ]
|
| + * 22. CancelClose(2) [ 1 2s ] [ 3 0 ] [ 0 1 2s 3 ]
|
| + * 23. CancelClose(0) [ 0s 1 2 ] [ 3 ] [ 0s 1 2 3 ]
|
| + * 24. CancelClose(3) [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testReverseOrderRestore() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1, tab2, tab3 }, tab3, new Tab[] { tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 3.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab2, tab3 }, tab3, new Tab[] { tab1, tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 4.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab2, tab1, tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 5.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab3, tab2, tab1, tab0 }, fullList, tab0);
|
| +
|
| + // 6.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab3, tab2, tab1 },
|
| + fullList, tab0);
|
| +
|
| + // 7.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab3, tab2 },
|
| + fullList, tab1);
|
| +
|
| + // 8.
|
| + cancelTabClosureOnUiThread(model, tab2);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2 }, tab2, new Tab[] { tab3 },
|
| + fullList, tab2);
|
| +
|
| + // 9.
|
| + cancelTabClosureOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 10.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2 }, tab2, new Tab[] { tab3 },
|
| + fullList, tab2);
|
| +
|
| + // 11.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab2, tab3 },
|
| + fullList, tab1);
|
| +
|
| + // 12.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1, tab2, tab3 },
|
| + fullList, tab0);
|
| +
|
| + // 13.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab0, tab1, tab2, tab3 }, fullList, tab0);
|
| +
|
| + // 14.
|
| + cancelTabClosureOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab0, tab1, tab2 },
|
| + fullList, tab3);
|
| +
|
| + // 15.
|
| + cancelTabClosureOnUiThread(model, tab2);
|
| + checkState(model, new Tab[] { tab2, tab3 }, tab2, new Tab[] { tab0, tab1 },
|
| + fullList, tab2);
|
| +
|
| + // 16.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab1, tab2, tab3 }, tab1, new Tab[] { tab0 },
|
| + fullList, tab1);
|
| +
|
| + // 17.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 18.
|
| + selectTabOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 19.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab1, tab3 }, tab3, new Tab[] { tab2 },
|
| + fullList, tab3);
|
| +
|
| + // 20.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1, tab3 }, tab3, new Tab[] { tab0, tab2 },
|
| + fullList, tab3);
|
| +
|
| + // 21.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab3, tab0, tab2 },
|
| + fullList, tab1);
|
| +
|
| + // 22.
|
| + cancelTabClosureOnUiThread(model, tab2);
|
| + checkState(model, new Tab[] { tab1, tab2 }, tab2, new Tab[] { tab3, tab0 },
|
| + fullList, tab2);
|
| +
|
| + // 23.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2 }, tab0, new Tab[] { tab3 },
|
| + fullList, tab0);
|
| +
|
| + // 24.
|
| + cancelTabClosureOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| + }
|
| +
|
| + /**
|
| + * Test restoring out of order with the following actions/expected states:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(0, allow undo) [ 1 2 3s ] [ 0 ] [ 0 1 2 3s ]
|
| + * 3. CloseTab(1, allow undo) [ 2 3s ] [ 1 0 ] [ 0 1 2 3s ]
|
| + * 4. CloseTab(2, allow undo) [ 3s ] [ 2 1 0 ] [ 0 1 2 3s ]
|
| + * 5. CloseTab(3, allow undo) - [ 3 2 1 0 ] [ 0s 1 2 3 ]
|
| + * 6. CancelClose(2) [ 2s ] [ 3 1 0 ] [ 0 1 2s 3 ]
|
| + * 7. CancelClose(1) [ 1s 2 ] [ 3 0 ] [ 0 1s 2 3 ]
|
| + * 8. CancelClose(3) [ 1 2 3s ] [ 0 ] [ 0 1 2 3s ]
|
| + * 9. CancelClose(0) [ 0s 1 2 3 ] - [ 0s 1 2 3 ]
|
| + * 10. CloseTab(1, allow undo) [ 0s 2 3 ] [ 1 ] [ 0s 1 2 3 ]
|
| + * 11. CancelClose(1) [ 0 1s 2 3 ] - [ 0 1s 2 3 ]
|
| + * 12. CloseTab(3, disallow undo) [ 0 1s 2 ] - [ 0 1s 2 ]
|
| + * 13. CloseTab(1, allow undo) [ 0s 2 ] [ 1 ] [ 0s 1 2 ]
|
| + * 14. CloseTab(0, allow undo) [ 2s ] [ 0 1 ] [ 0 1 2s ]
|
| + * 15. CommitClose(0) [ 2s ] [ 1 ] [ 1 2s ]
|
| + * 16. CancelClose(1) [ 1s 2 ] - [ 1s 2 ]
|
| + * 17. CloseTab(2, disallow undo) [ 1s ] - [ 1s ]
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testOutOfOrder1() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1, tab2, tab3 }, tab3, new Tab[] { tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 3.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab2, tab3 }, tab3, new Tab[] { tab1, tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 4.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab2, tab1, tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 5.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab3, tab2, tab1, tab0 }, fullList, tab0);
|
| +
|
| + // 6.
|
| + cancelTabClosureOnUiThread(model, tab2);
|
| + checkState(model, new Tab[] { tab2 }, tab2, new Tab[] { tab3, tab1, tab0 },
|
| + fullList, tab2);
|
| +
|
| + // 7.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab1, tab2 }, tab1, new Tab[] { tab3, tab0 },
|
| + fullList, tab1);
|
| +
|
| + // 8.
|
| + cancelTabClosureOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab1, tab2, tab3 }, tab3, new Tab[] { tab0 },
|
| + fullList, tab3);
|
| +
|
| + // 9.
|
| + cancelTabClosureOnUiThread(model, tab0);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 10.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0, tab2, tab3 }, tab0, new Tab[] { tab1 },
|
| + fullList, tab0);
|
| +
|
| + // 11.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 12.
|
| + closeTabOnUiThread(model, tab3, false);
|
| + fullList = new Tab[] { tab0, tab1, tab2 };
|
| + checkState(model, new Tab[] { tab0, tab1, tab2 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 13.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0, tab2 }, tab0, new Tab[] { tab1 }, fullList,
|
| + tab0);
|
| +
|
| + // 14.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab2 }, tab2, new Tab[] { tab0, tab1 }, fullList,
|
| + tab2);
|
| +
|
| + // 15.
|
| + commitTabClosureOnUiThread(model, tab0);
|
| + fullList = new Tab[] { tab1, tab2 };
|
| + checkState(model, new Tab[] { tab2 }, tab2, new Tab[] { tab1 }, fullList, tab2);
|
| +
|
| + // 16.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab1, tab2 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 17.
|
| + closeTabOnUiThread(model, tab2, false);
|
| + fullList = new Tab[] { tab1 };
|
| + checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1);
|
| + }
|
| +
|
| + /**
|
| + * Test restoring out of order with the following actions/expected states:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1 2 3s ]
|
| + * 3. CloseTab(3, allow undo) [ 0 2s ] [ 3 1 ] [ 0 1 2s 3 ]
|
| + * 4. CancelClose(1) [ 0 1s 2 ] [ 3 ] [ 0 1s 2 3 ]
|
| + * 5. CloseTab(2, allow undo) [ 0 1s ] [ 2 3 ] [ 0 1s 2 3 ]
|
| + * 6. CloseTab(0, allow undo) [ 1s ] [ 0 2 3 ] [ 0 1s 2 3 ]
|
| + * 7. CommitClose(0) [ 1s ] [ 2 3 ] [ 1s 2 3 ]
|
| + * 8. CancelClose(3) [ 1 3s ] [ 2 ] [ 1 2 3s ]
|
| + * 9. CloseTab(1, allow undo) [ 3s ] [ 1 2 ] [ 1 2 3s ]
|
| + * 10. CommitClose(2) [ 3s ] [ 1 ] [ 1 3s ]
|
| + * 11. CancelClose(1) [ 1s 3 ] - [ 1s 3 ]
|
| + * 12. CloseTab(3, allow undo) [ 1s ] [ 3 ] [ 1s 3 ]
|
| + * 13. CloseTab(1, allow undo) - [ 1 3 ] [ 1s 3 ]
|
| + * 14. CommitAll - - -
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testOutOfOrder2() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, new Tab[] { tab1 },
|
| + fullList, tab3);
|
| +
|
| + // 3.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, new Tab[] { tab0, tab2 }, tab2, new Tab[] { tab3, tab1 },
|
| + fullList, tab2);
|
| +
|
| + // 4.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab0, tab1, tab2 }, tab1, new Tab[] { tab3 },
|
| + fullList, tab1);
|
| +
|
| + // 5.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab2, tab3 },
|
| + fullList, tab1);
|
| +
|
| + // 6.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0, tab2, tab3 },
|
| + fullList, tab1);
|
| +
|
| + // 7.
|
| + commitTabClosureOnUiThread(model, tab0);
|
| + fullList = new Tab[] { tab1, tab2, tab3 };
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab2, tab3 }, fullList,
|
| + tab1);
|
| +
|
| + // 8.
|
| + cancelTabClosureOnUiThread(model, tab3);
|
| + checkState(model, new Tab[] { tab1, tab3 }, tab3, new Tab[] { tab2 }, fullList,
|
| + tab3);
|
| +
|
| + // 9.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab1, tab2 }, fullList,
|
| + tab3);
|
| +
|
| + // 10.
|
| + commitTabClosureOnUiThread(model, tab2);
|
| + fullList = new Tab[] { tab1, tab3 };
|
| + checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab1 }, fullList, tab3);
|
| +
|
| + // 11.
|
| + cancelTabClosureOnUiThread(model, tab1);
|
| + checkState(model, new Tab[] { tab1, tab3 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 12.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab3 }, fullList, tab1);
|
| +
|
| + // 13.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab1, tab3 }, fullList, tab1);
|
| +
|
| + // 14.
|
| + commitAllTabClosuresOnUiThread(model, new Tab[] { tab1, tab3 });
|
| + checkState(model, EMPTY, null, EMPTY, EMPTY, null);
|
| + }
|
| +
|
| + /**
|
| + * Test undo {@link TabModel#closeAllTabs()} with the following actions/expected states:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1 2 3s ]
|
| + * 3. CloseTab(2, allow undo) [ 0 3s ] [ 2 1 ] [ 0 1 2 3s ]
|
| + * 4. CloseAll - [ 0 3 2 1 ] [ 0s 1 2 3 ]
|
| + * 5. CancelAllClose [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 6. CloseAll - [ 0 1 2 3 ] [ 0s 1 2 3 ]
|
| + * 7. CommitAllClose - - -
|
| + * 8. CreateTab(0) [ 0s ] - [ 0s ]
|
| + * 9. CloseAll - [ 0 ] [ 0s ]
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testCloseAll() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, fullList, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, new Tab[] { tab1 }, fullList, tab3);
|
| +
|
| + // 3.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab3 }, tab3, new Tab[] { tab1, tab2 }, fullList, tab3);
|
| +
|
| + // 4.
|
| + closeAllTabsOnUiThread(model);
|
| + checkState(model, EMPTY, null, fullList, fullList, tab0);
|
| +
|
| + // 5.
|
| + cancelAllTabClosuresOnUiThread(model, fullList);
|
| + checkState(model, fullList, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 6.
|
| + closeAllTabsOnUiThread(model);
|
| + checkState(model, EMPTY, null, fullList, fullList, tab0);
|
| +
|
| + // 7.
|
| + commitAllTabClosuresOnUiThread(model, fullList);
|
| + checkState(model, EMPTY, null, EMPTY, EMPTY, null);
|
| + assertTrue(tab0.isClosing());
|
| + assertTrue(tab1.isClosing());
|
| + assertTrue(tab2.isClosing());
|
| + assertTrue(tab3.isClosing());
|
| + assertFalse(tab0.isInitialized());
|
| + assertFalse(tab1.isInitialized());
|
| + assertFalse(tab2.isInitialized());
|
| + assertFalse(tab3.isInitialized());
|
| +
|
| + // 8.
|
| + createTabOnUiThread(tabCreator);
|
| + tab0 = model.getTabAt(0);
|
| + fullList = new Tab[] { tab0 };
|
| + checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0);
|
| +
|
| + // 9.
|
| + closeAllTabsOnUiThread(model);
|
| + checkState(model, EMPTY, null, fullList, fullList, tab0);
|
| + assertTrue(tab0.isClosing());
|
| + assertTrue(tab0.isInitialized());
|
| + }
|
| +
|
| + /**
|
| + * Test {@link TabModel#closeTab(Tab)} when not allowing a close commits all pending
|
| + * closes:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1 2 3s ]
|
| + * 3. CloseTab(2, allow undo) [ 0 3s ] [ 2 1 ] [ 0 1 2 3s ]
|
| + * 4. CloseTab(3, disallow undo) [ 0s ] - [ 0s ]
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testCloseTab() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 3.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 4.
|
| + closeTabOnUiThread(model, tab3, false);
|
| + fullList = new Tab[] { tab0 };
|
| + checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0);
|
| + assertTrue(tab1.isClosing());
|
| + assertTrue(tab2.isClosing());
|
| + assertFalse(tab1.isInitialized());
|
| + assertFalse(tab2.isInitialized());
|
| + }
|
| +
|
| + /**
|
| + * Test {@link TabModel#moveTab(int, int)} commits all pending closes:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1 2 3s ]
|
| + * 3. CloseTab(2, allow undo) [ 0 3s ] [ 2 1 ] [ 0 1 2 3s ]
|
| + * 4. MoveTab(0, 2) [ 3s 0 ] - [ 3s 0 ]
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testMoveTab() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 3.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 4.
|
| + moveTabOnUiThread(model, tab0, 2);
|
| + fullList = new Tab[] { tab3, tab0 };
|
| + checkState(model, new Tab[] { tab3, tab0 }, tab3, EMPTY, fullList, tab3);
|
| + assertTrue(tab1.isClosing());
|
| + assertTrue(tab2.isClosing());
|
| + assertFalse(tab1.isInitialized());
|
| + assertFalse(tab1.isInitialized());
|
| + }
|
| +
|
| + /**
|
| + * Test adding a {@link Tab} to a {@link TabModel} commits all pending closes:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1 2 3s ]
|
| + * 3. CloseTab(2, allow undo) [ 0 3s ] [ 2 1 ] [ 0 1 2 3s ]
|
| + * 4. CreateTab(4) [ 0 3 4s ] - [ 0 3 4s ]
|
| + * 5. CloseTab(0, allow undo) [ 3 4s ] [ 0 ] [ 0 3 4s ]
|
| + * 6. CloseTab(3, allow undo) [ 4s ] [ 3 0 ] [ 0 3 4s ]
|
| + * 7. CloseTab(4, allow undo) - [ 4 3 0 ] [ 0s 3 4 ]
|
| + * 8. CreateTab(5) [ 5s ] - [ 5s ]
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testAddTab() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 3.
|
| + closeTabOnUiThread(model, tab2, true);
|
| + checkState(model, new Tab[] { tab0, tab3 }, tab3, EMPTY, fullList, tab3);
|
| +
|
| + // 4.
|
| + createTabOnUiThread(tabCreator);
|
| + Tab tab4 = model.getTabAt(2);
|
| + fullList = new Tab[] { tab0, tab3, tab4 };
|
| + checkState(model, new Tab[] { tab0, tab3, tab4 }, tab4, EMPTY, fullList, tab4);
|
| + assertTrue(tab1.isClosing());
|
| + assertTrue(tab2.isClosing());
|
| + assertFalse(tab1.isInitialized());
|
| + assertFalse(tab2.isInitialized());
|
| +
|
| + // 5.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab3, tab4 }, tab4, new Tab[] { tab0 }, fullList,
|
| + tab4);
|
| +
|
| + // 6.
|
| + closeTabOnUiThread(model, tab3, true);
|
| + checkState(model, new Tab[] { tab4 }, tab4, new Tab[] { tab3, tab0 }, fullList,
|
| + tab4);
|
| +
|
| + // 7.
|
| + closeTabOnUiThread(model, tab4, true);
|
| + checkState(model, EMPTY, null, new Tab[] { tab4, tab3, tab0 }, fullList, tab0);
|
| +
|
| + // 8.
|
| + createTabOnUiThread(tabCreator);
|
| + Tab tab5 = model.getTabAt(0);
|
| + fullList = new Tab[] { tab5 };
|
| + checkState(model, new Tab[] { tab5 }, tab5, EMPTY, fullList, tab5);
|
| + assertTrue(tab0.isClosing());
|
| + assertTrue(tab3.isClosing());
|
| + assertTrue(tab4.isClosing());
|
| + assertFalse(tab0.isInitialized());
|
| + assertFalse(tab3.isInitialized());
|
| + assertFalse(tab4.isInitialized());
|
| + }
|
| +
|
| + /**
|
| + * Test a {@link TabModel} where undo is not supported:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1 2 3s ] - [ 0 1 2 3s ]
|
| + * 2. CloseTab(1, allow undo) [ 0 2 3s ] - [ 0 2 3s ]
|
| + * 3. CloseAll - - -
|
| + *
|
| + * @throws InterruptedException
|
| + */
|
| + @MediumTest
|
| + public void testUndoNotSupported() throws InterruptedException {
|
| + TabModel model = getActivity().getTabModelSelector().getModel(true);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(true);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| + Tab tab2 = model.getTabAt(2);
|
| + Tab tab3 = model.getTabAt(3);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| + assertFalse(model.supportsPendingClosures());
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab1, true);
|
| + fullList = new Tab[] { tab0, tab2, tab3 };
|
| + checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, EMPTY, fullList, tab3);
|
| + assertTrue(tab1.isClosing());
|
| + assertFalse(tab1.isInitialized());
|
| +
|
| + // 3.
|
| + closeAllTabsOnUiThread(model);
|
| + checkState(model, EMPTY, null, EMPTY, EMPTY, null);
|
| + assertTrue(tab0.isClosing());
|
| + assertTrue(tab2.isClosing());
|
| + assertTrue(tab3.isClosing());
|
| + assertFalse(tab0.isInitialized());
|
| + assertFalse(tab2.isInitialized());
|
| + assertFalse(tab3.isInitialized());
|
| + }
|
| +
|
| + /**
|
| + * Test calling {@link TabModelSelectorImpl#saveState()} commits all pending closures:
|
| + * Action Model List Close List Comprehensive List
|
| + * 1. Initial State [ 0 1s ] - [ 0 1s ]
|
| + * 2. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 0 1s ]
|
| + * 3. SaveState [ 1s ] - [ 1s ]
|
| + */
|
| + @MediumTest
|
| + public void testSaveStateCommitsUndos() throws InterruptedException {
|
| + TabModelSelector selector = getActivity().getTabModelSelector();
|
| + TabModel model = selector.getModel(false);
|
| + ChromeTabCreator tabCreator = getActivity().getTabCreator(false);
|
| + createTabOnUiThread(tabCreator);
|
| +
|
| + Tab tab0 = model.getTabAt(0);
|
| + Tab tab1 = model.getTabAt(1);
|
| +
|
| + Tab[] fullList = new Tab[] { tab0, tab1 };
|
| +
|
| + // 1.
|
| + checkState(model, new Tab[] { tab0, tab1 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 2.
|
| + closeTabOnUiThread(model, tab0, true);
|
| + checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1);
|
| +
|
| + // 3.
|
| + saveStateOnUiThread(selector);
|
| + fullList = new Tab[] { tab1 };
|
| + checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1);
|
| + assertTrue(tab0.isClosing());
|
| + assertFalse(tab0.isInitialized());
|
| + }
|
| +}
|
|
|