OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.tabmodel; |
| 6 |
| 7 import android.test.FlakyTest; |
| 8 import android.test.suitebuilder.annotation.MediumTest; |
| 9 |
| 10 |
| 11 import org.chromium.base.CommandLine; |
| 12 import org.chromium.base.ThreadUtils; |
| 13 import org.chromium.chrome.browser.ChromeSwitches; |
| 14 import org.chromium.chrome.browser.Tab; |
| 15 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
| 16 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; |
| 17 import org.chromium.chrome.test.ChromeTabbedActivityTestBase; |
| 18 import org.chromium.content.browser.test.util.CallbackHelper; |
| 19 import org.chromium.content_public.browser.LoadUrlParams; |
| 20 |
| 21 import java.util.concurrent.TimeoutException; |
| 22 |
| 23 /** |
| 24 * Tests undo and restoring of tabs in a {@link TabModel}. |
| 25 */ |
| 26 public class UndoTabModelTest extends ChromeTabbedActivityTestBase { |
| 27 private static final Tab[] EMPTY = new Tab[] { }; |
| 28 |
| 29 @Override |
| 30 public void startMainActivity() throws InterruptedException { |
| 31 CommandLine.getInstance().appendSwitch(ChromeSwitches.ENABLE_HIGH_END_UI
_UNDO); |
| 32 startMainActivityOnBlankPage(); |
| 33 } |
| 34 |
| 35 private void checkState( |
| 36 final TabModel model, final Tab[] tabsList, final Tab selectedTab, |
| 37 final Tab[] closingTabs, final Tab[] fullTabsList, |
| 38 final Tab fullSelectedTab) { |
| 39 // Keeping these checks on the test thread so the stacks are useful for
identifying |
| 40 // failures. |
| 41 |
| 42 // Check the selected tab. |
| 43 assertEquals("Wrong selected tab", selectedTab, TabModelUtils.getCurrent
Tab(model)); |
| 44 |
| 45 // Check the list of tabs. |
| 46 assertEquals("Incorrect number of tabs", tabsList.length, model.getCount
()); |
| 47 for (int i = 0; i < tabsList.length; i++) { |
| 48 assertEquals("Unexpected tab at " + i, tabsList[i].getId(), model.ge
tTabAt(i).getId()); |
| 49 } |
| 50 |
| 51 // Check the list of tabs we expect to be closing. |
| 52 for (int i = 0; i < closingTabs.length; i++) { |
| 53 int id = closingTabs[i].getId(); |
| 54 assertTrue("Tab " + id + " not in closing list", model.isClosurePend
ing(id)); |
| 55 } |
| 56 |
| 57 TabList fullModel = model.getComprehensiveModel(); |
| 58 |
| 59 // Check the comprehensive selected tab. |
| 60 assertEquals("Wrong selected tab", fullSelectedTab, TabModelUtils.getCur
rentTab(fullModel)); |
| 61 |
| 62 // Check the comprehensive list of tabs. |
| 63 assertEquals("Incorrect number of tabs", fullTabsList.length, fullModel.
getCount()); |
| 64 for (int i = 0; i < fullModel.getCount(); i++) { |
| 65 int id = fullModel.getTabAt(i).getId(); |
| 66 assertEquals("Unexpected tab at " + i, fullTabsList[i].getId(), id); |
| 67 } |
| 68 } |
| 69 |
| 70 private void createTabOnUiThread(final ChromeTabCreator tabCreator) { |
| 71 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 72 @Override |
| 73 public void run() { |
| 74 tabCreator.createNewTab(new LoadUrlParams("about:blank"), |
| 75 TabLaunchType.FROM_MENU_OR_OVERVIEW, null); |
| 76 } |
| 77 }); |
| 78 } |
| 79 |
| 80 private void selectTabOnUiThread(final TabModel model, final Tab tab) { |
| 81 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 82 @Override |
| 83 public void run() { |
| 84 model.setIndex(model.indexOf(tab), TabSelectionType.FROM_USER); |
| 85 } |
| 86 }); |
| 87 } |
| 88 |
| 89 private void closeTabOnUiThread( |
| 90 final TabModel model, final Tab tab, final boolean undoable) |
| 91 throws InterruptedException { |
| 92 // Check preconditions. |
| 93 assertFalse(tab.isClosing()); |
| 94 assertTrue(tab.isInitialized()); |
| 95 assertFalse(model.isClosurePending(tab.getId())); |
| 96 assertNotNull(TabModelUtils.getTabById(model, tab.getId())); |
| 97 |
| 98 final CallbackHelper didReceivePendingClosureHelper = new CallbackHelper
(); |
| 99 model.addObserver(new EmptyTabModelObserver() { |
| 100 @Override |
| 101 public void tabPendingClosure(Tab tab) { |
| 102 didReceivePendingClosureHelper.notifyCalled(); |
| 103 } |
| 104 }); |
| 105 |
| 106 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 107 @Override |
| 108 public void run() { |
| 109 // Take action. |
| 110 model.closeTab(tab, true, false, undoable); |
| 111 } |
| 112 }); |
| 113 |
| 114 boolean didUndo = undoable && model.supportsPendingClosures(); |
| 115 |
| 116 // Make sure the TabModel throws a tabPendingClosure callback if necessa
ry. |
| 117 if (didUndo) { |
| 118 try { |
| 119 didReceivePendingClosureHelper.waitForCallback(0); |
| 120 } catch (TimeoutException e) { |
| 121 fail(); |
| 122 } |
| 123 } |
| 124 |
| 125 // Check post conditions |
| 126 assertEquals(didUndo, model.isClosurePending(tab.getId())); |
| 127 assertNull(TabModelUtils.getTabById(model, tab.getId())); |
| 128 assertTrue(tab.isClosing()); |
| 129 assertEquals(didUndo, tab.isInitialized()); |
| 130 } |
| 131 |
| 132 private void closeAllTabsOnUiThread(final TabModel model) { |
| 133 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 134 @Override |
| 135 public void run() { |
| 136 model.closeAllTabs(); |
| 137 } |
| 138 }); |
| 139 } |
| 140 |
| 141 private void moveTabOnUiThread(final TabModel model, final Tab tab, final in
t newIndex) { |
| 142 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 143 @Override |
| 144 public void run() { |
| 145 model.moveTab(tab.getId(), newIndex); |
| 146 } |
| 147 }); |
| 148 } |
| 149 |
| 150 private void cancelTabClosureOnUiThread(final TabModel model, final Tab tab) |
| 151 throws InterruptedException { |
| 152 // Check preconditions. |
| 153 assertTrue(tab.isClosing()); |
| 154 assertTrue(tab.isInitialized()); |
| 155 assertTrue(model.isClosurePending(tab.getId())); |
| 156 assertNull(TabModelUtils.getTabById(model, tab.getId())); |
| 157 |
| 158 final CallbackHelper didReceiveClosureCancelledHelper = new CallbackHelp
er(); |
| 159 model.addObserver(new EmptyTabModelObserver() { |
| 160 @Override |
| 161 public void tabClosureUndone(Tab tab) { |
| 162 didReceiveClosureCancelledHelper.notifyCalled(); |
| 163 } |
| 164 }); |
| 165 |
| 166 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 167 @Override |
| 168 public void run() { |
| 169 // Take action. |
| 170 model.cancelTabClosure(tab.getId()); |
| 171 } |
| 172 }); |
| 173 |
| 174 // Make sure the TabModel throws a tabClosureUndone. |
| 175 try { |
| 176 didReceiveClosureCancelledHelper.waitForCallback(0); |
| 177 } catch (TimeoutException e) { |
| 178 fail(); |
| 179 } |
| 180 |
| 181 // Check post conditions. |
| 182 assertFalse(model.isClosurePending(tab.getId())); |
| 183 assertNotNull(TabModelUtils.getTabById(model, tab.getId())); |
| 184 assertFalse(tab.isClosing()); |
| 185 assertTrue(tab.isInitialized()); |
| 186 } |
| 187 |
| 188 private void cancelAllTabClosuresOnUiThread(final TabModel model, final Tab[
] expectedToClose) |
| 189 throws InterruptedException { |
| 190 final CallbackHelper tabClosureUndoneHelper = new CallbackHelper(); |
| 191 |
| 192 for (int i = 0; i < expectedToClose.length; i++) { |
| 193 Tab tab = expectedToClose[i]; |
| 194 assertTrue(tab.isClosing()); |
| 195 assertTrue(tab.isInitialized()); |
| 196 assertTrue(model.isClosurePending(tab.getId())); |
| 197 assertNull(TabModelUtils.getTabById(model, tab.getId())); |
| 198 |
| 199 // Make sure that this TabModel throws the right events. |
| 200 model.addObserver(new EmptyTabModelObserver() { |
| 201 @Override |
| 202 public void tabClosureUndone(Tab currentTab) { |
| 203 tabClosureUndoneHelper.notifyCalled(); |
| 204 } |
| 205 }); |
| 206 } |
| 207 |
| 208 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 209 @Override |
| 210 public void run() { |
| 211 for (int i = 0; i < expectedToClose.length; i++) { |
| 212 Tab tab = expectedToClose[i]; |
| 213 model.cancelTabClosure(tab.getId()); |
| 214 } |
| 215 } |
| 216 }); |
| 217 |
| 218 try { |
| 219 tabClosureUndoneHelper.waitForCallback(0, expectedToClose.length); |
| 220 } catch (TimeoutException e) { |
| 221 fail(); |
| 222 } |
| 223 |
| 224 for (int i = 0; i < expectedToClose.length; i++) { |
| 225 final Tab tab = expectedToClose[i]; |
| 226 assertFalse(model.isClosurePending(tab.getId())); |
| 227 assertNotNull(TabModelUtils.getTabById(model, tab.getId())); |
| 228 assertFalse(tab.isClosing()); |
| 229 assertTrue(tab.isInitialized()); |
| 230 } |
| 231 } |
| 232 |
| 233 private void commitTabClosureOnUiThread(final TabModel model, final Tab tab) |
| 234 throws InterruptedException { |
| 235 // Check preconditions. |
| 236 assertTrue(tab.isClosing()); |
| 237 assertTrue(tab.isInitialized()); |
| 238 assertTrue(model.isClosurePending(tab.getId())); |
| 239 assertNull(TabModelUtils.getTabById(model, tab.getId())); |
| 240 |
| 241 final CallbackHelper didReceiveClosureCommittedHelper = new CallbackHelp
er(); |
| 242 model.addObserver(new EmptyTabModelObserver() { |
| 243 @Override |
| 244 public void tabClosureCommitted(Tab tab) { |
| 245 didReceiveClosureCommittedHelper.notifyCalled(); |
| 246 } |
| 247 }); |
| 248 |
| 249 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 250 @Override |
| 251 public void run() { |
| 252 // Take action. |
| 253 model.commitTabClosure(tab.getId()); |
| 254 } |
| 255 }); |
| 256 |
| 257 // Make sure the TabModel throws a tabClosureCommitted. |
| 258 try { |
| 259 didReceiveClosureCommittedHelper.waitForCallback(0); |
| 260 } catch (TimeoutException e) { |
| 261 fail(); |
| 262 } |
| 263 |
| 264 // Check post conditions |
| 265 assertFalse(model.isClosurePending(tab.getId())); |
| 266 assertNull(TabModelUtils.getTabById(model, tab.getId())); |
| 267 assertTrue(tab.isClosing()); |
| 268 assertFalse(tab.isInitialized()); |
| 269 } |
| 270 |
| 271 private void commitAllTabClosuresOnUiThread(final TabModel model, Tab[] expe
ctedToClose) |
| 272 throws InterruptedException { |
| 273 final CallbackHelper tabClosureCommittedHelper = new CallbackHelper(); |
| 274 |
| 275 for (int i = 0; i < expectedToClose.length; i++) { |
| 276 Tab tab = expectedToClose[i]; |
| 277 assertTrue(tab.isClosing()); |
| 278 assertTrue(tab.isInitialized()); |
| 279 assertTrue(model.isClosurePending(tab.getId())); |
| 280 |
| 281 // Make sure that this TabModel throws the right events. |
| 282 model.addObserver(new EmptyTabModelObserver() { |
| 283 @Override |
| 284 public void tabClosureCommitted(Tab currentTab) { |
| 285 tabClosureCommittedHelper.notifyCalled(); |
| 286 } |
| 287 }); |
| 288 } |
| 289 |
| 290 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 291 @Override |
| 292 public void run() { |
| 293 model.commitAllTabClosures(); |
| 294 } |
| 295 }); |
| 296 |
| 297 try { |
| 298 tabClosureCommittedHelper.waitForCallback(0, expectedToClose.length)
; |
| 299 } catch (TimeoutException e) { |
| 300 fail(); |
| 301 } |
| 302 for (int i = 0; i < expectedToClose.length; i++) { |
| 303 final Tab tab = expectedToClose[i]; |
| 304 assertTrue(tab.isClosing()); |
| 305 assertFalse(tab.isInitialized()); |
| 306 assertFalse(model.isClosurePending(tab.getId())); |
| 307 } |
| 308 } |
| 309 |
| 310 private void saveStateOnUiThread(final TabModelSelector selector) { |
| 311 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 312 @Override |
| 313 public void run() { |
| 314 ((TabModelSelectorImpl) selector).saveState(); |
| 315 } |
| 316 }); |
| 317 |
| 318 for (int i = 0; i < selector.getModels().size(); i++) { |
| 319 TabList tabs = selector.getModelAt(i).getComprehensiveModel(); |
| 320 for (int j = 0; j < tabs.getCount(); j++) { |
| 321 assertFalse(tabs.isClosurePending(tabs.getTabAt(j).getId())); |
| 322 } |
| 323 } |
| 324 } |
| 325 |
| 326 /** |
| 327 * Test undo with a single tab with the following actions/expected states: |
| 328 * Action Model List Close List Compr
ehensive List |
| 329 * 1. Initial State [ 0s ] - [ 0s
] |
| 330 * 2. CloseTab(0, allow undo) - [ 0 ] [ 0s
] |
| 331 * 3. CancelClose(0) [ 0s ] - [ 0s
] |
| 332 * 4. CloseTab(0, allow undo) - [ 0 ] [ 0s
] |
| 333 * 5. CommitClose(0) - - - |
| 334 * 6. CreateTab(0) [ 0s ] - [ 0s
] |
| 335 * 7. CloseTab(0, allow undo) - [ 0 ] [ 0s
] |
| 336 * 8. CommitAllClose - - - |
| 337 * 9. CreateTab(0) [ 0s ] - [ 0s
] |
| 338 * 10. CloseTab(0, disallow undo) - - - |
| 339 * |
| 340 * @throws InterruptedException |
| 341 */ |
| 342 @MediumTest |
| 343 public void testSingleTab() throws InterruptedException { |
| 344 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 345 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 346 |
| 347 Tab tab0 = model.getTabAt(0); |
| 348 |
| 349 Tab[] fullList = new Tab[] { tab0 }; |
| 350 |
| 351 // 1. |
| 352 checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0); |
| 353 |
| 354 // 2. |
| 355 closeTabOnUiThread(model, tab0, true); |
| 356 checkState(model, EMPTY, null, new Tab[] { tab0 }, fullList, tab0); |
| 357 |
| 358 // 3. |
| 359 cancelTabClosureOnUiThread(model, tab0); |
| 360 checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0); |
| 361 |
| 362 // 4. |
| 363 closeTabOnUiThread(model, tab0, true); |
| 364 checkState(model, EMPTY, null, new Tab[] { tab0 }, fullList, tab0); |
| 365 |
| 366 // 5. |
| 367 commitTabClosureOnUiThread(model, tab0); |
| 368 fullList = EMPTY; |
| 369 checkState(model, EMPTY, null, EMPTY, EMPTY, null); |
| 370 |
| 371 // 6. |
| 372 createTabOnUiThread(tabCreator); |
| 373 tab0 = model.getTabAt(0); |
| 374 fullList = new Tab[] { tab0 }; |
| 375 checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0); |
| 376 |
| 377 // 7. |
| 378 closeTabOnUiThread(model, tab0, true); |
| 379 checkState(model, EMPTY, null, new Tab[] { tab0 }, fullList, tab0); |
| 380 |
| 381 // 8. |
| 382 commitAllTabClosuresOnUiThread(model, new Tab[] { tab0 }); |
| 383 fullList = EMPTY; |
| 384 checkState(model, EMPTY, null, EMPTY, EMPTY, null); |
| 385 |
| 386 // 9. |
| 387 createTabOnUiThread(tabCreator); |
| 388 tab0 = model.getTabAt(0); |
| 389 fullList = new Tab[] { tab0 }; |
| 390 checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0); |
| 391 |
| 392 // 10. |
| 393 closeTabOnUiThread(model, tab0, false); |
| 394 fullList = EMPTY; |
| 395 checkState(model, EMPTY, null, EMPTY, fullList, null); |
| 396 assertTrue(tab0.isClosing()); |
| 397 assertFalse(tab0.isInitialized()); |
| 398 } |
| 399 |
| 400 /** |
| 401 * Flaky on instrumentation-nakasi-clankium. See http://crbug.com/417720. |
| 402 * |
| 403 * Test undo with two tabs with the following actions/expected states: |
| 404 * Action Model List Close List Compr
ehensive List |
| 405 * 1. Initial State [ 0 1s ] - [ 0 1
s ] |
| 406 * 2. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 0 1
s ] |
| 407 * 3. CancelClose(0) [ 0s 1 ] - [ 0s
1 ] |
| 408 * 4. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 0 1
s ] |
| 409 * 5. CloseTab(1, allow undo) - [ 1 0 ] [ 0 1
s ] |
| 410 * 6. CancelClose(1) [ 1s ] [ 0 ] [ 0s
1 ] |
| 411 * 7. CancelClose(0) [ 0s 1 ] - [ 0s
1 ] |
| 412 * 8. CloseTab(1, allow undo) [ 0s ] [ 1 ] [ 0s
1 ] |
| 413 * 9. CloseTab(0, allow undo) - [ 0 1 ] [ 0s
1 ] |
| 414 * 10. CancelClose(1) [ 1s ] [ 0 ] [ 0 1
s ] |
| 415 * 11. CancelClose(0) [ 0s 1 ] - [ 0s
1 ] |
| 416 * 12. CloseTab(1, allow undo) [ 0s ] [ 1 ] [ 0s
1 ] |
| 417 * 13. CloseTab(0, allow undo) - [ 0 1 ] [ 0s
1 ] |
| 418 * 14. CancelClose(0) [ 0s ] [ 1 ] [ 0s
1 ] |
| 419 * 15. CloseTab(0, allow undo) - [ 0 1 ] [ 0s
1 ] |
| 420 * 16. CancelClose(0) [ 0s ] [ 1 ] [ 0s
1 ] |
| 421 * 17. CancelClose(1) [ 0 1s ] - [ 0 1
s ] |
| 422 * 18. CloseTab(0, disallow undo) [ 1s ] - [ 1s
] |
| 423 * 19. CreateTab(0) [ 1 0s ] - [ 1 0
s ] |
| 424 * 20. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 1s
0 ] |
| 425 * 21. CommitClose(0) [ 1s ] - [ 1s
] |
| 426 * 22. CreateTab(0) [ 1 0s ] - [ 1 0
s ] |
| 427 * 23. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 1s
0 ] |
| 428 * 24. CloseTab(1, allow undo) - [ 1 0 ] [ 1s
0 ] |
| 429 * 25. CommitAllClose - - - |
| 430 * |
| 431 * @throws InterruptedException |
| 432 * @MediumTest |
| 433 */ |
| 434 @FlakyTest |
| 435 public void testTwoTabs() throws InterruptedException { |
| 436 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 437 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 438 createTabOnUiThread(tabCreator); |
| 439 |
| 440 Tab tab0 = model.getTabAt(0); |
| 441 Tab tab1 = model.getTabAt(1); |
| 442 |
| 443 Tab[] fullList = new Tab[] { tab0, tab1 }; |
| 444 |
| 445 // 1. |
| 446 checkState(model, new Tab[] { tab0, tab1 }, tab1, EMPTY, fullList, tab1)
; |
| 447 |
| 448 // 2. |
| 449 closeTabOnUiThread(model, tab0, true); |
| 450 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList
, tab1); |
| 451 |
| 452 // 3. |
| 453 cancelTabClosureOnUiThread(model, tab0); |
| 454 checkState(model, new Tab[] { tab0, tab1 }, tab0, EMPTY, fullList, tab0)
; |
| 455 |
| 456 // 4. |
| 457 closeTabOnUiThread(model, tab0, true); |
| 458 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList
, tab1); |
| 459 |
| 460 // 5. |
| 461 closeTabOnUiThread(model, tab1, true); |
| 462 checkState(model, EMPTY, null, new Tab[] { tab0, tab1 }, fullList, tab0)
; |
| 463 |
| 464 // 6. |
| 465 cancelTabClosureOnUiThread(model, tab1); |
| 466 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList
, tab1); |
| 467 |
| 468 // 7. |
| 469 cancelTabClosureOnUiThread(model, tab0); |
| 470 checkState(model, new Tab[] { tab0, tab1 }, tab0, EMPTY, fullList, tab0)
; |
| 471 |
| 472 // 8. |
| 473 closeTabOnUiThread(model, tab1, true); |
| 474 checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1 }, fullList
, tab0); |
| 475 |
| 476 // 9. |
| 477 closeTabOnUiThread(model, tab0, true); |
| 478 checkState(model, EMPTY, null, new Tab[] { tab0, tab1 }, fullList, tab0)
; |
| 479 |
| 480 // 10. |
| 481 cancelTabClosureOnUiThread(model, tab1); |
| 482 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList
, tab1); |
| 483 |
| 484 // 11. |
| 485 cancelTabClosureOnUiThread(model, tab0); |
| 486 checkState(model, new Tab[] { tab0, tab1 }, tab0, EMPTY, fullList, tab0)
; |
| 487 |
| 488 // 12. |
| 489 closeTabOnUiThread(model, tab1, true); |
| 490 checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1 }, fullList
, tab0); |
| 491 |
| 492 // 13. |
| 493 closeTabOnUiThread(model, tab0, true); |
| 494 checkState(model, EMPTY, null, new Tab[] { tab0, tab1 }, fullList, tab0)
; |
| 495 |
| 496 // 14. |
| 497 cancelTabClosureOnUiThread(model, tab0); |
| 498 checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1 }, fullList
, tab0); |
| 499 |
| 500 // 15. |
| 501 closeTabOnUiThread(model, tab0, true); |
| 502 checkState(model, EMPTY, null, new Tab[] { tab0, tab1 }, fullList, tab0)
; |
| 503 |
| 504 // 16. |
| 505 cancelTabClosureOnUiThread(model, tab0); |
| 506 checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1 }, fullList
, tab0); |
| 507 |
| 508 // 17. |
| 509 cancelTabClosureOnUiThread(model, tab1); |
| 510 checkState(model, new Tab[] { tab0, tab1 }, tab1, EMPTY, fullList, tab1)
; |
| 511 |
| 512 // 18. |
| 513 closeTabOnUiThread(model, tab0, false); |
| 514 fullList = new Tab[] { tab1 }; |
| 515 checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1); |
| 516 |
| 517 // 19. |
| 518 createTabOnUiThread(tabCreator); |
| 519 tab0 = model.getTabAt(1); |
| 520 fullList = new Tab[] { tab1, tab0 }; |
| 521 checkState(model, new Tab[] { tab1, tab0 }, tab0, EMPTY, fullList, tab0)
; |
| 522 |
| 523 // 20. |
| 524 closeTabOnUiThread(model, tab0, true); |
| 525 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList
, tab1); |
| 526 |
| 527 // 21. |
| 528 commitTabClosureOnUiThread(model, tab0); |
| 529 fullList = new Tab[] { tab1 }; |
| 530 checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1); |
| 531 |
| 532 // 22. |
| 533 createTabOnUiThread(tabCreator); |
| 534 tab0 = model.getTabAt(1); |
| 535 fullList = new Tab[] { tab1, tab0 }; |
| 536 checkState(model, new Tab[] { tab1, tab0 }, tab0, EMPTY, fullList, tab0)
; |
| 537 |
| 538 // 23. |
| 539 closeTabOnUiThread(model, tab0, true); |
| 540 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0 }, fullList
, tab1); |
| 541 |
| 542 // 24. |
| 543 closeTabOnUiThread(model, tab1, true); |
| 544 checkState(model, EMPTY, null, new Tab[] { tab1, tab0 }, fullList, tab1)
; |
| 545 |
| 546 // 25. |
| 547 commitAllTabClosuresOnUiThread(model, new Tab[] { tab1, tab0 }); |
| 548 checkState(model, EMPTY, null, EMPTY, EMPTY, null); |
| 549 } |
| 550 |
| 551 /** |
| 552 * Test restoring in the same order of closing with the following actions/ex
pected states: |
| 553 * Action Model List Close List Compr
ehensive List |
| 554 * 1. Initial State [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 555 * 2. CloseTab(0, allow undo) [ 1 2 3s ] [ 0 ] [ 0 1
2 3s ] |
| 556 * 3. CloseTab(1, allow undo) [ 2 3s ] [ 1 0 ] [ 0 1
2 3s ] |
| 557 * 4. CloseTab(2, allow undo) [ 3s ] [ 2 1 0 ] [ 0 1
2 3s ] |
| 558 * 5. CloseTab(3, allow undo) - [ 3 2 1 0 ] [ 0s
1 2 3 ] |
| 559 * 6. CancelClose(3) [ 3s ] [ 2 1 0 ] [ 0 1
2 3s ] |
| 560 * 7. CancelClose(2) [ 2s 3 ] [ 1 0 ] [ 0 1
2s 3 ] |
| 561 * 8. CancelClose(1) [ 1s 2 3 ] [ 0 ] [ 0 1
s 2 3 ] |
| 562 * 9. CancelClose(0) [ 0s 1 2 3 ] - [ 0s
1 2 3 ] |
| 563 * 10. SelectTab(3) [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 564 * 11. CloseTab(3, allow undo) [ 0 1 2s ] [ 3 ] [ 0 1
2s 3 ] |
| 565 * 12. CloseTab(2, allow undo) [ 0 1s ] [ 2 3 ] [ 0 1
s 2 3 ] |
| 566 * 13. CloseTab(1, allow undo) [ 0s ] [ 1 2 3 ] [ 0s
1 2 3 ] |
| 567 * 14. CloseTab(0, allow undo) - [ 0 1 2 3 ] [ 0s
1 2 3 ] |
| 568 * 15. CancelClose(0) [ 0s ] [ 1 2 3 ] [ 0s
1 2 3 ] |
| 569 * 16. CancelClose(1) [ 0 1s ] [ 2 3 ] [ 0 1
s 2 3 ] |
| 570 * 17. CancelClose(2) [ 0 1 2s ] [ 3 ] [ 0 1
2s 3 ] |
| 571 * 18. CancelClose(3) [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 572 * 19. CloseTab(2, allow undo) [ 0 1 3s ] [ 2 ] [ 0 1
2 3s ] |
| 573 * 20. CloseTab(0, allow undo) [ 1 3s ] [ 0 2 ] [ 0 1
2 3s ] |
| 574 * 21. CloseTab(3, allow undo) [ 1s ] [ 3 0 2 ] [ 0 1
s 2 3 ] |
| 575 * 22. CancelClose(3) [ 1 3s ] [ 0 2 ] [ 0 1
2 3s ] |
| 576 * 23. CancelClose(0) [ 0s 1 3 ] [ 2 ] [ 0s
1 2 3 ] |
| 577 * 24. CancelClose(2) [ 0 1 2s 3 ] - [ 0 1
2s 3 ] |
| 578 * |
| 579 * @throws InterruptedException |
| 580 */ |
| 581 @MediumTest |
| 582 public void testInOrderRestore() throws InterruptedException { |
| 583 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 584 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 585 createTabOnUiThread(tabCreator); |
| 586 createTabOnUiThread(tabCreator); |
| 587 createTabOnUiThread(tabCreator); |
| 588 |
| 589 Tab tab0 = model.getTabAt(0); |
| 590 Tab tab1 = model.getTabAt(1); |
| 591 Tab tab2 = model.getTabAt(2); |
| 592 Tab tab3 = model.getTabAt(3); |
| 593 |
| 594 final Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 595 |
| 596 // 1. |
| 597 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 598 |
| 599 // 2. |
| 600 closeTabOnUiThread(model, tab0, true); |
| 601 checkState(model, new Tab[] { tab1, tab2, tab3 }, tab3, new Tab[] { tab0
}, |
| 602 fullList, tab3); |
| 603 |
| 604 // 3. |
| 605 closeTabOnUiThread(model, tab1, true); |
| 606 checkState(model, new Tab[] { tab2, tab3 }, tab3, new Tab[] { tab1, tab0
}, |
| 607 fullList, tab3); |
| 608 |
| 609 // 4. |
| 610 closeTabOnUiThread(model, tab2, true); |
| 611 checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab2, tab1, tab0
}, |
| 612 fullList, tab3); |
| 613 |
| 614 // 5. |
| 615 closeTabOnUiThread(model, tab3, true); |
| 616 checkState(model, EMPTY, null, new Tab[] { tab3, tab2, tab1, tab0 }, ful
lList, tab0); |
| 617 |
| 618 // 6. |
| 619 cancelTabClosureOnUiThread(model, tab3); |
| 620 checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab2, tab1, tab0
}, |
| 621 fullList, tab3); |
| 622 |
| 623 // 7. |
| 624 cancelTabClosureOnUiThread(model, tab2); |
| 625 checkState(model, new Tab[] { tab2, tab3 }, tab2, new Tab[] { tab1, tab0
}, |
| 626 fullList, tab2); |
| 627 |
| 628 // 8. |
| 629 cancelTabClosureOnUiThread(model, tab1); |
| 630 checkState(model, new Tab[] { tab1, tab2, tab3 }, tab1, new Tab[] { tab0
}, |
| 631 fullList, tab1); |
| 632 |
| 633 // 9. |
| 634 cancelTabClosureOnUiThread(model, tab0); |
| 635 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab0, EMPTY, ful
lList, tab0); |
| 636 |
| 637 // 10. |
| 638 selectTabOnUiThread(model, tab3); |
| 639 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 640 |
| 641 // 11. |
| 642 closeTabOnUiThread(model, tab3, true); |
| 643 checkState(model, new Tab[] { tab0, tab1, tab2 }, tab2, new Tab[] { tab3
}, |
| 644 fullList, tab2); |
| 645 |
| 646 // 12. |
| 647 closeTabOnUiThread(model, tab2, true); |
| 648 checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab2, tab3
}, |
| 649 fullList, tab1); |
| 650 |
| 651 // 13. |
| 652 closeTabOnUiThread(model, tab1, true); |
| 653 checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1, tab2, tab3
}, |
| 654 fullList, tab0); |
| 655 |
| 656 // 14. |
| 657 closeTabOnUiThread(model, tab0, true); |
| 658 checkState(model, EMPTY, null, new Tab[] { tab0, tab1, tab2, tab3 }, ful
lList, tab0); |
| 659 |
| 660 // 15. |
| 661 cancelTabClosureOnUiThread(model, tab0); |
| 662 checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1, tab2, tab3
}, |
| 663 fullList, tab0); |
| 664 |
| 665 // 16. |
| 666 cancelTabClosureOnUiThread(model, tab1); |
| 667 checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab2, tab3
}, |
| 668 fullList, tab1); |
| 669 |
| 670 // 17. |
| 671 cancelTabClosureOnUiThread(model, tab2); |
| 672 checkState(model, new Tab[] { tab0, tab1, tab2 }, tab2, new Tab[] { tab3
}, |
| 673 fullList, tab2); |
| 674 |
| 675 // 18. |
| 676 cancelTabClosureOnUiThread(model, tab3); |
| 677 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 678 |
| 679 // 19. |
| 680 closeTabOnUiThread(model, tab2, true); |
| 681 checkState(model, new Tab[] { tab0, tab1, tab3 }, tab3, new Tab[] { tab2
}, |
| 682 fullList, tab3); |
| 683 |
| 684 // 20. |
| 685 closeTabOnUiThread(model, tab0, true); |
| 686 checkState(model, new Tab[] { tab1, tab3 }, tab3, new Tab[] { tab0, tab2
}, |
| 687 fullList, tab3); |
| 688 |
| 689 // 21. |
| 690 closeTabOnUiThread(model, tab3, true); |
| 691 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab3, tab0, tab2
}, |
| 692 fullList, tab1); |
| 693 |
| 694 // 22. |
| 695 cancelTabClosureOnUiThread(model, tab3); |
| 696 checkState(model, new Tab[] { tab1, tab3 }, tab3, new Tab[] { tab0, tab2
}, |
| 697 fullList, tab3); |
| 698 |
| 699 // 23. |
| 700 cancelTabClosureOnUiThread(model, tab0); |
| 701 checkState(model, new Tab[] { tab0, tab1, tab3 }, tab0, new Tab[] { tab2
}, |
| 702 fullList, tab0); |
| 703 |
| 704 // 24. |
| 705 cancelTabClosureOnUiThread(model, tab2); |
| 706 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab2, EMPTY, ful
lList, tab2); |
| 707 } |
| 708 |
| 709 |
| 710 /** |
| 711 * Test restoring in the reverse of closing with the following actions/expec
ted states: |
| 712 * Action Model List Close List Compr
ehensive List |
| 713 * 1. Initial State [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 714 * 2. CloseTab(0, allow undo) [ 1 2 3s ] [ 0 ] [ 0 1
2 3s ] |
| 715 * 3. CloseTab(1, allow undo) [ 2 3s ] [ 1 0 ] [ 0 1
2 3s ] |
| 716 * 4. CloseTab(2, allow undo) [ 3s ] [ 2 1 0 ] [ 0 1
2 3s ] |
| 717 * 5. CloseTab(3, allow undo) - [ 3 2 1 0 ] [ 0s
1 2 3 ] |
| 718 * 6. CancelClose(0) [ 0s ] [ 3 2 1 ] [ 0s
1 2 3 ] |
| 719 * 7. CancelClose(1) [ 0 1s ] [ 3 2 ] [ 0 1
s 2 3 ] |
| 720 * 8. CancelClose(2) [ 0 1 2s ] [ 3 ] [ 0 1
2s 3 ] |
| 721 * 9. CancelClose(3) [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 722 * 10. CloseTab(3, allow undo) [ 0 1 2s ] [ 3 ] [ 0 1
2s 3 ] |
| 723 * 11. CloseTab(2, allow undo) [ 0 1s ] [ 2 3 ] [ 0 1
s 2 3 ] |
| 724 * 12. CloseTab(1, allow undo) [ 0s ] [ 1 2 3 ] [ 0s
1 2 3 ] |
| 725 * 13. CloseTab(0, allow undo) - [ 0 1 2 3 ] [ 0s
1 2 3 ] |
| 726 * 14. CancelClose(3) [ 3s ] [ 0 1 2 ] [ 0 1
2 3s ] |
| 727 * 15. CancelClose(2) [ 2s 3 ] [ 0 1 ] [ 0 1
2s 3 ] |
| 728 * 16. CancelClose(1) [ 1s 2 3 ] [ 0 ] [ 0 1
s 2 3 ] |
| 729 * 17. CancelClose(0) [ 0s 1 2 3 ] - [ 0s
1 2 3 ] |
| 730 * 18. SelectTab(3) [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 731 * 19. CloseTab(2, allow undo) [ 0 1 3s ] [ 2 ] [ 0 1
2 3s ] |
| 732 * 20. CloseTab(0, allow undo) [ 1 3s ] [ 0 2 ] [ 0 1
2 3s ] |
| 733 * 21. CloseTab(3, allow undo) [ 1s ] [ 3 0 2 ] [ 0 1
s 2 3 ] |
| 734 * 22. CancelClose(2) [ 1 2s ] [ 3 0 ] [ 0 1
2s 3 ] |
| 735 * 23. CancelClose(0) [ 0s 1 2 ] [ 3 ] [ 0s
1 2 3 ] |
| 736 * 24. CancelClose(3) [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 737 * |
| 738 * @throws InterruptedException |
| 739 */ |
| 740 @MediumTest |
| 741 public void testReverseOrderRestore() throws InterruptedException { |
| 742 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 743 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 744 createTabOnUiThread(tabCreator); |
| 745 createTabOnUiThread(tabCreator); |
| 746 createTabOnUiThread(tabCreator); |
| 747 |
| 748 Tab tab0 = model.getTabAt(0); |
| 749 Tab tab1 = model.getTabAt(1); |
| 750 Tab tab2 = model.getTabAt(2); |
| 751 Tab tab3 = model.getTabAt(3); |
| 752 |
| 753 Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 754 |
| 755 // 1. |
| 756 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 757 |
| 758 // 2. |
| 759 closeTabOnUiThread(model, tab0, true); |
| 760 checkState(model, new Tab[] { tab1, tab2, tab3 }, tab3, new Tab[] { tab0
}, |
| 761 fullList, tab3); |
| 762 |
| 763 // 3. |
| 764 closeTabOnUiThread(model, tab1, true); |
| 765 checkState(model, new Tab[] { tab2, tab3 }, tab3, new Tab[] { tab1, tab0
}, |
| 766 fullList, tab3); |
| 767 |
| 768 // 4. |
| 769 closeTabOnUiThread(model, tab2, true); |
| 770 checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab2, tab1, tab0
}, |
| 771 fullList, tab3); |
| 772 |
| 773 // 5. |
| 774 closeTabOnUiThread(model, tab3, true); |
| 775 checkState(model, EMPTY, null, new Tab[] { tab3, tab2, tab1, tab0 }, ful
lList, tab0); |
| 776 |
| 777 // 6. |
| 778 cancelTabClosureOnUiThread(model, tab0); |
| 779 checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab3, tab2, tab1
}, |
| 780 fullList, tab0); |
| 781 |
| 782 // 7. |
| 783 cancelTabClosureOnUiThread(model, tab1); |
| 784 checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab3, tab2
}, |
| 785 fullList, tab1); |
| 786 |
| 787 // 8. |
| 788 cancelTabClosureOnUiThread(model, tab2); |
| 789 checkState(model, new Tab[] { tab0, tab1, tab2 }, tab2, new Tab[] { tab3
}, |
| 790 fullList, tab2); |
| 791 |
| 792 // 9. |
| 793 cancelTabClosureOnUiThread(model, tab3); |
| 794 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 795 |
| 796 // 10. |
| 797 closeTabOnUiThread(model, tab3, true); |
| 798 checkState(model, new Tab[] { tab0, tab1, tab2 }, tab2, new Tab[] { tab3
}, |
| 799 fullList, tab2); |
| 800 |
| 801 // 11. |
| 802 closeTabOnUiThread(model, tab2, true); |
| 803 checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab2, tab3
}, |
| 804 fullList, tab1); |
| 805 |
| 806 // 12. |
| 807 closeTabOnUiThread(model, tab1, true); |
| 808 checkState(model, new Tab[] { tab0 }, tab0, new Tab[] { tab1, tab2, tab3
}, |
| 809 fullList, tab0); |
| 810 |
| 811 // 13. |
| 812 closeTabOnUiThread(model, tab0, true); |
| 813 checkState(model, EMPTY, null, new Tab[] { tab0, tab1, tab2, tab3 }, ful
lList, tab0); |
| 814 |
| 815 // 14. |
| 816 cancelTabClosureOnUiThread(model, tab3); |
| 817 checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab0, tab1, tab2
}, |
| 818 fullList, tab3); |
| 819 |
| 820 // 15. |
| 821 cancelTabClosureOnUiThread(model, tab2); |
| 822 checkState(model, new Tab[] { tab2, tab3 }, tab2, new Tab[] { tab0, tab1
}, |
| 823 fullList, tab2); |
| 824 |
| 825 // 16. |
| 826 cancelTabClosureOnUiThread(model, tab1); |
| 827 checkState(model, new Tab[] { tab1, tab2, tab3 }, tab1, new Tab[] { tab0
}, |
| 828 fullList, tab1); |
| 829 |
| 830 // 17. |
| 831 cancelTabClosureOnUiThread(model, tab0); |
| 832 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab0, EMPTY, ful
lList, tab0); |
| 833 |
| 834 // 18. |
| 835 selectTabOnUiThread(model, tab3); |
| 836 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 837 |
| 838 // 19. |
| 839 closeTabOnUiThread(model, tab2, true); |
| 840 checkState(model, new Tab[] { tab0, tab1, tab3 }, tab3, new Tab[] { tab2
}, |
| 841 fullList, tab3); |
| 842 |
| 843 // 20. |
| 844 closeTabOnUiThread(model, tab0, true); |
| 845 checkState(model, new Tab[] { tab1, tab3 }, tab3, new Tab[] { tab0, tab2
}, |
| 846 fullList, tab3); |
| 847 |
| 848 // 21. |
| 849 closeTabOnUiThread(model, tab3, true); |
| 850 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab3, tab0, tab2
}, |
| 851 fullList, tab1); |
| 852 |
| 853 // 22. |
| 854 cancelTabClosureOnUiThread(model, tab2); |
| 855 checkState(model, new Tab[] { tab1, tab2 }, tab2, new Tab[] { tab3, tab0
}, |
| 856 fullList, tab2); |
| 857 |
| 858 // 23. |
| 859 cancelTabClosureOnUiThread(model, tab0); |
| 860 checkState(model, new Tab[] { tab0, tab1, tab2 }, tab0, new Tab[] { tab3
}, |
| 861 fullList, tab0); |
| 862 |
| 863 // 24. |
| 864 cancelTabClosureOnUiThread(model, tab3); |
| 865 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 866 } |
| 867 |
| 868 /** |
| 869 * Test restoring out of order with the following actions/expected states: |
| 870 * Action Model List Close List Compr
ehensive List |
| 871 * 1. Initial State [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 872 * 2. CloseTab(0, allow undo) [ 1 2 3s ] [ 0 ] [ 0 1
2 3s ] |
| 873 * 3. CloseTab(1, allow undo) [ 2 3s ] [ 1 0 ] [ 0 1
2 3s ] |
| 874 * 4. CloseTab(2, allow undo) [ 3s ] [ 2 1 0 ] [ 0 1
2 3s ] |
| 875 * 5. CloseTab(3, allow undo) - [ 3 2 1 0 ] [ 0s
1 2 3 ] |
| 876 * 6. CancelClose(2) [ 2s ] [ 3 1 0 ] [ 0 1
2s 3 ] |
| 877 * 7. CancelClose(1) [ 1s 2 ] [ 3 0 ] [ 0 1
s 2 3 ] |
| 878 * 8. CancelClose(3) [ 1 2 3s ] [ 0 ] [ 0 1
2 3s ] |
| 879 * 9. CancelClose(0) [ 0s 1 2 3 ] - [ 0s
1 2 3 ] |
| 880 * 10. CloseTab(1, allow undo) [ 0s 2 3 ] [ 1 ] [ 0s
1 2 3 ] |
| 881 * 11. CancelClose(1) [ 0 1s 2 3 ] - [ 0 1
s 2 3 ] |
| 882 * 12. CloseTab(3, disallow undo) [ 0 1s 2 ] - [ 0 1
s 2 ] |
| 883 * 13. CloseTab(1, allow undo) [ 0s 2 ] [ 1 ] [ 0s
1 2 ] |
| 884 * 14. CloseTab(0, allow undo) [ 2s ] [ 0 1 ] [ 0 1
2s ] |
| 885 * 15. CommitClose(0) [ 2s ] [ 1 ] [ 1 2
s ] |
| 886 * 16. CancelClose(1) [ 1s 2 ] - [ 1s
2 ] |
| 887 * 17. CloseTab(2, disallow undo) [ 1s ] - [ 1s
] |
| 888 * |
| 889 * @throws InterruptedException |
| 890 */ |
| 891 @MediumTest |
| 892 public void testOutOfOrder1() throws InterruptedException { |
| 893 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 894 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 895 createTabOnUiThread(tabCreator); |
| 896 createTabOnUiThread(tabCreator); |
| 897 createTabOnUiThread(tabCreator); |
| 898 |
| 899 Tab tab0 = model.getTabAt(0); |
| 900 Tab tab1 = model.getTabAt(1); |
| 901 Tab tab2 = model.getTabAt(2); |
| 902 Tab tab3 = model.getTabAt(3); |
| 903 |
| 904 Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 905 |
| 906 // 1. |
| 907 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 908 |
| 909 // 2. |
| 910 closeTabOnUiThread(model, tab0, true); |
| 911 checkState(model, new Tab[] { tab1, tab2, tab3 }, tab3, new Tab[] { tab0
}, |
| 912 fullList, tab3); |
| 913 |
| 914 // 3. |
| 915 closeTabOnUiThread(model, tab1, true); |
| 916 checkState(model, new Tab[] { tab2, tab3 }, tab3, new Tab[] { tab1, tab0
}, |
| 917 fullList, tab3); |
| 918 |
| 919 // 4. |
| 920 closeTabOnUiThread(model, tab2, true); |
| 921 checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab2, tab1, tab0
}, |
| 922 fullList, tab3); |
| 923 |
| 924 // 5. |
| 925 closeTabOnUiThread(model, tab3, true); |
| 926 checkState(model, EMPTY, null, new Tab[] { tab3, tab2, tab1, tab0 }, ful
lList, tab0); |
| 927 |
| 928 // 6. |
| 929 cancelTabClosureOnUiThread(model, tab2); |
| 930 checkState(model, new Tab[] { tab2 }, tab2, new Tab[] { tab3, tab1, tab0
}, |
| 931 fullList, tab2); |
| 932 |
| 933 // 7. |
| 934 cancelTabClosureOnUiThread(model, tab1); |
| 935 checkState(model, new Tab[] { tab1, tab2 }, tab1, new Tab[] { tab3, tab0
}, |
| 936 fullList, tab1); |
| 937 |
| 938 // 8. |
| 939 cancelTabClosureOnUiThread(model, tab3); |
| 940 checkState(model, new Tab[] { tab1, tab2, tab3 }, tab3, new Tab[] { tab0
}, |
| 941 fullList, tab3); |
| 942 |
| 943 // 9. |
| 944 cancelTabClosureOnUiThread(model, tab0); |
| 945 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab0, EMPTY, ful
lList, tab0); |
| 946 |
| 947 // 10. |
| 948 closeTabOnUiThread(model, tab1, true); |
| 949 checkState(model, new Tab[] { tab0, tab2, tab3 }, tab0, new Tab[] { tab1
}, |
| 950 fullList, tab0); |
| 951 |
| 952 // 11. |
| 953 cancelTabClosureOnUiThread(model, tab1); |
| 954 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab1, EMPTY, ful
lList, tab1); |
| 955 |
| 956 // 12. |
| 957 closeTabOnUiThread(model, tab3, false); |
| 958 fullList = new Tab[] { tab0, tab1, tab2 }; |
| 959 checkState(model, new Tab[] { tab0, tab1, tab2 }, tab1, EMPTY, fullList,
tab1); |
| 960 |
| 961 // 13. |
| 962 closeTabOnUiThread(model, tab1, true); |
| 963 checkState(model, new Tab[] { tab0, tab2 }, tab0, new Tab[] { tab1 }, fu
llList, |
| 964 tab0); |
| 965 |
| 966 // 14. |
| 967 closeTabOnUiThread(model, tab0, true); |
| 968 checkState(model, new Tab[] { tab2 }, tab2, new Tab[] { tab0, tab1 }, fu
llList, |
| 969 tab2); |
| 970 |
| 971 // 15. |
| 972 commitTabClosureOnUiThread(model, tab0); |
| 973 fullList = new Tab[] { tab1, tab2 }; |
| 974 checkState(model, new Tab[] { tab2 }, tab2, new Tab[] { tab1 }, fullList
, tab2); |
| 975 |
| 976 // 16. |
| 977 cancelTabClosureOnUiThread(model, tab1); |
| 978 checkState(model, new Tab[] { tab1, tab2 }, tab1, EMPTY, fullList, tab1)
; |
| 979 |
| 980 // 17. |
| 981 closeTabOnUiThread(model, tab2, false); |
| 982 fullList = new Tab[] { tab1 }; |
| 983 checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1); |
| 984 } |
| 985 |
| 986 /** |
| 987 * Test restoring out of order with the following actions/expected states: |
| 988 * Action Model List Close List Compr
ehensive List |
| 989 * 1. Initial State [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 990 * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1
2 3s ] |
| 991 * 3. CloseTab(3, allow undo) [ 0 2s ] [ 3 1 ] [ 0 1
2s 3 ] |
| 992 * 4. CancelClose(1) [ 0 1s 2 ] [ 3 ] [ 0 1
s 2 3 ] |
| 993 * 5. CloseTab(2, allow undo) [ 0 1s ] [ 2 3 ] [ 0 1
s 2 3 ] |
| 994 * 6. CloseTab(0, allow undo) [ 1s ] [ 0 2 3 ] [ 0 1
s 2 3 ] |
| 995 * 7. CommitClose(0) [ 1s ] [ 2 3 ] [ 1s
2 3 ] |
| 996 * 8. CancelClose(3) [ 1 3s ] [ 2 ] [ 1 2
3s ] |
| 997 * 9. CloseTab(1, allow undo) [ 3s ] [ 1 2 ] [ 1 2
3s ] |
| 998 * 10. CommitClose(2) [ 3s ] [ 1 ] [ 1 3
s ] |
| 999 * 11. CancelClose(1) [ 1s 3 ] - [ 1s
3 ] |
| 1000 * 12. CloseTab(3, allow undo) [ 1s ] [ 3 ] [ 1s
3 ] |
| 1001 * 13. CloseTab(1, allow undo) - [ 1 3 ] [ 1s
3 ] |
| 1002 * 14. CommitAll - - - |
| 1003 * |
| 1004 * @throws InterruptedException |
| 1005 */ |
| 1006 @MediumTest |
| 1007 public void testOutOfOrder2() throws InterruptedException { |
| 1008 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 1009 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 1010 createTabOnUiThread(tabCreator); |
| 1011 createTabOnUiThread(tabCreator); |
| 1012 createTabOnUiThread(tabCreator); |
| 1013 |
| 1014 Tab tab0 = model.getTabAt(0); |
| 1015 Tab tab1 = model.getTabAt(1); |
| 1016 Tab tab2 = model.getTabAt(2); |
| 1017 Tab tab3 = model.getTabAt(3); |
| 1018 |
| 1019 Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 1020 |
| 1021 // 1. |
| 1022 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 1023 |
| 1024 // 2. |
| 1025 closeTabOnUiThread(model, tab1, true); |
| 1026 checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, new Tab[] { tab1
}, |
| 1027 fullList, tab3); |
| 1028 |
| 1029 // 3. |
| 1030 closeTabOnUiThread(model, tab3, true); |
| 1031 checkState(model, new Tab[] { tab0, tab2 }, tab2, new Tab[] { tab3, tab1
}, |
| 1032 fullList, tab2); |
| 1033 |
| 1034 // 4. |
| 1035 cancelTabClosureOnUiThread(model, tab1); |
| 1036 checkState(model, new Tab[] { tab0, tab1, tab2 }, tab1, new Tab[] { tab3
}, |
| 1037 fullList, tab1); |
| 1038 |
| 1039 // 5. |
| 1040 closeTabOnUiThread(model, tab2, true); |
| 1041 checkState(model, new Tab[] { tab0, tab1 }, tab1, new Tab[] { tab2, tab3
}, |
| 1042 fullList, tab1); |
| 1043 |
| 1044 // 6. |
| 1045 closeTabOnUiThread(model, tab0, true); |
| 1046 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab0, tab2, tab3
}, |
| 1047 fullList, tab1); |
| 1048 |
| 1049 // 7. |
| 1050 commitTabClosureOnUiThread(model, tab0); |
| 1051 fullList = new Tab[] { tab1, tab2, tab3 }; |
| 1052 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab2, tab3 }, fu
llList, |
| 1053 tab1); |
| 1054 |
| 1055 // 8. |
| 1056 cancelTabClosureOnUiThread(model, tab3); |
| 1057 checkState(model, new Tab[] { tab1, tab3 }, tab3, new Tab[] { tab2 }, fu
llList, |
| 1058 tab3); |
| 1059 |
| 1060 // 9. |
| 1061 closeTabOnUiThread(model, tab1, true); |
| 1062 checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab1, tab2 }, fu
llList, |
| 1063 tab3); |
| 1064 |
| 1065 // 10. |
| 1066 commitTabClosureOnUiThread(model, tab2); |
| 1067 fullList = new Tab[] { tab1, tab3 }; |
| 1068 checkState(model, new Tab[] { tab3 }, tab3, new Tab[] { tab1 }, fullList
, tab3); |
| 1069 |
| 1070 // 11. |
| 1071 cancelTabClosureOnUiThread(model, tab1); |
| 1072 checkState(model, new Tab[] { tab1, tab3 }, tab1, EMPTY, fullList, tab1)
; |
| 1073 |
| 1074 // 12. |
| 1075 closeTabOnUiThread(model, tab3, true); |
| 1076 checkState(model, new Tab[] { tab1 }, tab1, new Tab[] { tab3 }, fullList
, tab1); |
| 1077 |
| 1078 // 13. |
| 1079 closeTabOnUiThread(model, tab1, true); |
| 1080 checkState(model, EMPTY, null, new Tab[] { tab1, tab3 }, fullList, tab1)
; |
| 1081 |
| 1082 // 14. |
| 1083 commitAllTabClosuresOnUiThread(model, new Tab[] { tab1, tab3 }); |
| 1084 checkState(model, EMPTY, null, EMPTY, EMPTY, null); |
| 1085 } |
| 1086 |
| 1087 /** |
| 1088 * Test undo {@link TabModel#closeAllTabs()} with the following actions/expe
cted states: |
| 1089 * Action Model List Close List Compr
ehensive List |
| 1090 * 1. Initial State [ 0 1 2 3s ] - [ 0
1 2 3s ] |
| 1091 * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0
1 2 3s ] |
| 1092 * 3. CloseTab(2, allow undo) [ 0 3s ] [ 2 1 ] [ 0
1 2 3s ] |
| 1093 * 4. CloseAll - [ 0 3 2 1 ] [ 0s
1 2 3 ] |
| 1094 * 5. CancelAllClose [ 0 1 2 3s ] - [ 0
1 2 3s ] |
| 1095 * 6. CloseAll - [ 0 1 2 3 ] [ 0s
1 2 3 ] |
| 1096 * 7. CommitAllClose - - - |
| 1097 * 8. CreateTab(0) [ 0s ] - [ 0s
] |
| 1098 * 9. CloseAll - [ 0 ] [ 0s
] |
| 1099 * |
| 1100 * @throws InterruptedException |
| 1101 */ |
| 1102 @MediumTest |
| 1103 public void testCloseAll() throws InterruptedException { |
| 1104 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 1105 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 1106 createTabOnUiThread(tabCreator); |
| 1107 createTabOnUiThread(tabCreator); |
| 1108 createTabOnUiThread(tabCreator); |
| 1109 |
| 1110 Tab tab0 = model.getTabAt(0); |
| 1111 Tab tab1 = model.getTabAt(1); |
| 1112 Tab tab2 = model.getTabAt(2); |
| 1113 Tab tab3 = model.getTabAt(3); |
| 1114 |
| 1115 Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 1116 |
| 1117 // 1. |
| 1118 checkState(model, fullList, tab3, EMPTY, fullList, tab3); |
| 1119 |
| 1120 // 2. |
| 1121 closeTabOnUiThread(model, tab1, true); |
| 1122 checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, new Tab[] { tab1
}, fullList, tab3); |
| 1123 |
| 1124 // 3. |
| 1125 closeTabOnUiThread(model, tab2, true); |
| 1126 checkState(model, new Tab[] { tab0, tab3 }, tab3, new Tab[] { tab1, tab2
}, fullList, tab3); |
| 1127 |
| 1128 // 4. |
| 1129 closeAllTabsOnUiThread(model); |
| 1130 checkState(model, EMPTY, null, fullList, fullList, tab0); |
| 1131 |
| 1132 // 5. |
| 1133 cancelAllTabClosuresOnUiThread(model, fullList); |
| 1134 checkState(model, fullList, tab3, EMPTY, fullList, tab3); |
| 1135 |
| 1136 // 6. |
| 1137 closeAllTabsOnUiThread(model); |
| 1138 checkState(model, EMPTY, null, fullList, fullList, tab0); |
| 1139 |
| 1140 // 7. |
| 1141 commitAllTabClosuresOnUiThread(model, fullList); |
| 1142 checkState(model, EMPTY, null, EMPTY, EMPTY, null); |
| 1143 assertTrue(tab0.isClosing()); |
| 1144 assertTrue(tab1.isClosing()); |
| 1145 assertTrue(tab2.isClosing()); |
| 1146 assertTrue(tab3.isClosing()); |
| 1147 assertFalse(tab0.isInitialized()); |
| 1148 assertFalse(tab1.isInitialized()); |
| 1149 assertFalse(tab2.isInitialized()); |
| 1150 assertFalse(tab3.isInitialized()); |
| 1151 |
| 1152 // 8. |
| 1153 createTabOnUiThread(tabCreator); |
| 1154 tab0 = model.getTabAt(0); |
| 1155 fullList = new Tab[] { tab0 }; |
| 1156 checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0); |
| 1157 |
| 1158 // 9. |
| 1159 closeAllTabsOnUiThread(model); |
| 1160 checkState(model, EMPTY, null, fullList, fullList, tab0); |
| 1161 assertTrue(tab0.isClosing()); |
| 1162 assertTrue(tab0.isInitialized()); |
| 1163 } |
| 1164 |
| 1165 /** |
| 1166 * Test {@link TabModel#closeTab(Tab)} when not allowing a close commits all
pending |
| 1167 * closes: |
| 1168 * Action Model List Close List Compr
ehensive List |
| 1169 * 1. Initial State [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 1170 * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1
2 3s ] |
| 1171 * 3. CloseTab(2, allow undo) [ 0 3s ] [ 2 1 ] [ 0 1
2 3s ] |
| 1172 * 4. CloseTab(3, disallow undo) [ 0s ] - [ 0s
] |
| 1173 * |
| 1174 * @throws InterruptedException |
| 1175 */ |
| 1176 @MediumTest |
| 1177 public void testCloseTab() throws InterruptedException { |
| 1178 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 1179 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 1180 createTabOnUiThread(tabCreator); |
| 1181 createTabOnUiThread(tabCreator); |
| 1182 createTabOnUiThread(tabCreator); |
| 1183 |
| 1184 Tab tab0 = model.getTabAt(0); |
| 1185 Tab tab1 = model.getTabAt(1); |
| 1186 Tab tab2 = model.getTabAt(2); |
| 1187 Tab tab3 = model.getTabAt(3); |
| 1188 |
| 1189 Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 1190 |
| 1191 // 1. |
| 1192 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 1193 |
| 1194 // 2. |
| 1195 closeTabOnUiThread(model, tab1, true); |
| 1196 checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, EMPTY, fullList,
tab3); |
| 1197 |
| 1198 // 3. |
| 1199 closeTabOnUiThread(model, tab2, true); |
| 1200 checkState(model, new Tab[] { tab0, tab3 }, tab3, EMPTY, fullList, tab3)
; |
| 1201 |
| 1202 // 4. |
| 1203 closeTabOnUiThread(model, tab3, false); |
| 1204 fullList = new Tab[] { tab0 }; |
| 1205 checkState(model, new Tab[] { tab0 }, tab0, EMPTY, fullList, tab0); |
| 1206 assertTrue(tab1.isClosing()); |
| 1207 assertTrue(tab2.isClosing()); |
| 1208 assertFalse(tab1.isInitialized()); |
| 1209 assertFalse(tab2.isInitialized()); |
| 1210 } |
| 1211 |
| 1212 /** |
| 1213 * Test {@link TabModel#moveTab(int, int)} commits all pending closes: |
| 1214 * Action Model List Close List Compr
ehensive List |
| 1215 * 1. Initial State [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 1216 * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1
2 3s ] |
| 1217 * 3. CloseTab(2, allow undo) [ 0 3s ] [ 2 1 ] [ 0 1
2 3s ] |
| 1218 * 4. MoveTab(0, 2) [ 3s 0 ] - [ 3s
0 ] |
| 1219 * |
| 1220 * @throws InterruptedException |
| 1221 */ |
| 1222 @MediumTest |
| 1223 public void testMoveTab() throws InterruptedException { |
| 1224 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 1225 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 1226 createTabOnUiThread(tabCreator); |
| 1227 createTabOnUiThread(tabCreator); |
| 1228 createTabOnUiThread(tabCreator); |
| 1229 |
| 1230 Tab tab0 = model.getTabAt(0); |
| 1231 Tab tab1 = model.getTabAt(1); |
| 1232 Tab tab2 = model.getTabAt(2); |
| 1233 Tab tab3 = model.getTabAt(3); |
| 1234 |
| 1235 Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 1236 |
| 1237 // 1. |
| 1238 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 1239 |
| 1240 // 2. |
| 1241 closeTabOnUiThread(model, tab1, true); |
| 1242 checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, EMPTY, fullList,
tab3); |
| 1243 |
| 1244 // 3. |
| 1245 closeTabOnUiThread(model, tab2, true); |
| 1246 checkState(model, new Tab[] { tab0, tab3 }, tab3, EMPTY, fullList, tab3)
; |
| 1247 |
| 1248 // 4. |
| 1249 moveTabOnUiThread(model, tab0, 2); |
| 1250 fullList = new Tab[] { tab3, tab0 }; |
| 1251 checkState(model, new Tab[] { tab3, tab0 }, tab3, EMPTY, fullList, tab3)
; |
| 1252 assertTrue(tab1.isClosing()); |
| 1253 assertTrue(tab2.isClosing()); |
| 1254 assertFalse(tab1.isInitialized()); |
| 1255 assertFalse(tab1.isInitialized()); |
| 1256 } |
| 1257 |
| 1258 /** |
| 1259 * Test adding a {@link Tab} to a {@link TabModel} commits all pending close
s: |
| 1260 * Action Model List Close List Compr
ehensive List |
| 1261 * 1. Initial State [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 1262 * 2. CloseTab(1, allow undo) [ 0 2 3s ] [ 1 ] [ 0 1
2 3s ] |
| 1263 * 3. CloseTab(2, allow undo) [ 0 3s ] [ 2 1 ] [ 0 1
2 3s ] |
| 1264 * 4. CreateTab(4) [ 0 3 4s ] - [ 0 3
4s ] |
| 1265 * 5. CloseTab(0, allow undo) [ 3 4s ] [ 0 ] [ 0 3
4s ] |
| 1266 * 6. CloseTab(3, allow undo) [ 4s ] [ 3 0 ] [ 0 3
4s ] |
| 1267 * 7. CloseTab(4, allow undo) - [ 4 3 0 ] [ 0s
3 4 ] |
| 1268 * 8. CreateTab(5) [ 5s ] - [ 5s
] |
| 1269 * @throws InterruptedException |
| 1270 */ |
| 1271 @MediumTest |
| 1272 public void testAddTab() throws InterruptedException { |
| 1273 TabModel model = getActivity().getTabModelSelector().getModel(false); |
| 1274 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 1275 createTabOnUiThread(tabCreator); |
| 1276 createTabOnUiThread(tabCreator); |
| 1277 createTabOnUiThread(tabCreator); |
| 1278 |
| 1279 Tab tab0 = model.getTabAt(0); |
| 1280 Tab tab1 = model.getTabAt(1); |
| 1281 Tab tab2 = model.getTabAt(2); |
| 1282 Tab tab3 = model.getTabAt(3); |
| 1283 |
| 1284 Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 1285 |
| 1286 // 1. |
| 1287 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 1288 |
| 1289 // 2. |
| 1290 closeTabOnUiThread(model, tab1, true); |
| 1291 checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, EMPTY, fullList,
tab3); |
| 1292 |
| 1293 // 3. |
| 1294 closeTabOnUiThread(model, tab2, true); |
| 1295 checkState(model, new Tab[] { tab0, tab3 }, tab3, EMPTY, fullList, tab3)
; |
| 1296 |
| 1297 // 4. |
| 1298 createTabOnUiThread(tabCreator); |
| 1299 Tab tab4 = model.getTabAt(2); |
| 1300 fullList = new Tab[] { tab0, tab3, tab4 }; |
| 1301 checkState(model, new Tab[] { tab0, tab3, tab4 }, tab4, EMPTY, fullList,
tab4); |
| 1302 assertTrue(tab1.isClosing()); |
| 1303 assertTrue(tab2.isClosing()); |
| 1304 assertFalse(tab1.isInitialized()); |
| 1305 assertFalse(tab2.isInitialized()); |
| 1306 |
| 1307 // 5. |
| 1308 closeTabOnUiThread(model, tab0, true); |
| 1309 checkState(model, new Tab[] { tab3, tab4 }, tab4, new Tab[] { tab0 }, fu
llList, |
| 1310 tab4); |
| 1311 |
| 1312 // 6. |
| 1313 closeTabOnUiThread(model, tab3, true); |
| 1314 checkState(model, new Tab[] { tab4 }, tab4, new Tab[] { tab3, tab0 }, fu
llList, |
| 1315 tab4); |
| 1316 |
| 1317 // 7. |
| 1318 closeTabOnUiThread(model, tab4, true); |
| 1319 checkState(model, EMPTY, null, new Tab[] { tab4, tab3, tab0 }, fullList,
tab0); |
| 1320 |
| 1321 // 8. |
| 1322 createTabOnUiThread(tabCreator); |
| 1323 Tab tab5 = model.getTabAt(0); |
| 1324 fullList = new Tab[] { tab5 }; |
| 1325 checkState(model, new Tab[] { tab5 }, tab5, EMPTY, fullList, tab5); |
| 1326 assertTrue(tab0.isClosing()); |
| 1327 assertTrue(tab3.isClosing()); |
| 1328 assertTrue(tab4.isClosing()); |
| 1329 assertFalse(tab0.isInitialized()); |
| 1330 assertFalse(tab3.isInitialized()); |
| 1331 assertFalse(tab4.isInitialized()); |
| 1332 } |
| 1333 |
| 1334 /** |
| 1335 * Test a {@link TabModel} where undo is not supported: |
| 1336 * Action Model List Close List Compr
ehensive List |
| 1337 * 1. Initial State [ 0 1 2 3s ] - [ 0 1
2 3s ] |
| 1338 * 2. CloseTab(1, allow undo) [ 0 2 3s ] - [ 0 2
3s ] |
| 1339 * 3. CloseAll - - - |
| 1340 * |
| 1341 * @throws InterruptedException |
| 1342 */ |
| 1343 @MediumTest |
| 1344 public void testUndoNotSupported() throws InterruptedException { |
| 1345 TabModel model = getActivity().getTabModelSelector().getModel(true); |
| 1346 ChromeTabCreator tabCreator = getActivity().getTabCreator(true); |
| 1347 createTabOnUiThread(tabCreator); |
| 1348 createTabOnUiThread(tabCreator); |
| 1349 createTabOnUiThread(tabCreator); |
| 1350 createTabOnUiThread(tabCreator); |
| 1351 |
| 1352 Tab tab0 = model.getTabAt(0); |
| 1353 Tab tab1 = model.getTabAt(1); |
| 1354 Tab tab2 = model.getTabAt(2); |
| 1355 Tab tab3 = model.getTabAt(3); |
| 1356 |
| 1357 Tab[] fullList = new Tab[] { tab0, tab1, tab2, tab3 }; |
| 1358 |
| 1359 // 1. |
| 1360 checkState(model, new Tab[] { tab0, tab1, tab2, tab3 }, tab3, EMPTY, ful
lList, tab3); |
| 1361 assertFalse(model.supportsPendingClosures()); |
| 1362 |
| 1363 // 2. |
| 1364 closeTabOnUiThread(model, tab1, true); |
| 1365 fullList = new Tab[] { tab0, tab2, tab3 }; |
| 1366 checkState(model, new Tab[] { tab0, tab2, tab3 }, tab3, EMPTY, fullList,
tab3); |
| 1367 assertTrue(tab1.isClosing()); |
| 1368 assertFalse(tab1.isInitialized()); |
| 1369 |
| 1370 // 3. |
| 1371 closeAllTabsOnUiThread(model); |
| 1372 checkState(model, EMPTY, null, EMPTY, EMPTY, null); |
| 1373 assertTrue(tab0.isClosing()); |
| 1374 assertTrue(tab2.isClosing()); |
| 1375 assertTrue(tab3.isClosing()); |
| 1376 assertFalse(tab0.isInitialized()); |
| 1377 assertFalse(tab2.isInitialized()); |
| 1378 assertFalse(tab3.isInitialized()); |
| 1379 } |
| 1380 |
| 1381 /** |
| 1382 * Test calling {@link TabModelSelectorImpl#saveState()} commits all pending
closures: |
| 1383 * Action Model List Close List Compr
ehensive List |
| 1384 * 1. Initial State [ 0 1s ] - [ 0 1
s ] |
| 1385 * 2. CloseTab(0, allow undo) [ 1s ] [ 0 ] [ 0 1
s ] |
| 1386 * 3. SaveState [ 1s ] - [ 1s
] |
| 1387 */ |
| 1388 @MediumTest |
| 1389 public void testSaveStateCommitsUndos() throws InterruptedException { |
| 1390 TabModelSelector selector = getActivity().getTabModelSelector(); |
| 1391 TabModel model = selector.getModel(false); |
| 1392 ChromeTabCreator tabCreator = getActivity().getTabCreator(false); |
| 1393 createTabOnUiThread(tabCreator); |
| 1394 |
| 1395 Tab tab0 = model.getTabAt(0); |
| 1396 Tab tab1 = model.getTabAt(1); |
| 1397 |
| 1398 Tab[] fullList = new Tab[] { tab0, tab1 }; |
| 1399 |
| 1400 // 1. |
| 1401 checkState(model, new Tab[] { tab0, tab1 }, tab1, EMPTY, fullList, tab1)
; |
| 1402 |
| 1403 // 2. |
| 1404 closeTabOnUiThread(model, tab0, true); |
| 1405 checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1); |
| 1406 |
| 1407 // 3. |
| 1408 saveStateOnUiThread(selector); |
| 1409 fullList = new Tab[] { tab1 }; |
| 1410 checkState(model, new Tab[] { tab1 }, tab1, EMPTY, fullList, tab1); |
| 1411 assertTrue(tab0.isClosing()); |
| 1412 assertFalse(tab0.isInitialized()); |
| 1413 } |
| 1414 } |
OLD | NEW |