Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698