1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <map>
621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <string>
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h"
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_split.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/defaults.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_tab_helper.h"
1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tabs/tab_strip_model.h"
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/tabs/tab_strip_model_delegate.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tabs/tab_strip_model_order_controller.h"
24201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/ui/browser.h"
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/new_tab_ui.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/test/testing_profile.h"
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/test_render_view_host.h"
31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_controller.h"
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h"
33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_details.h"
35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_observer_mock.h"
36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_registrar.h"
37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_source.h"
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/property_bag.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/system_monitor/system_monitor.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::_;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochnamespace {
454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Class used to delete a TabContents when another TabContents is destroyed.
474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass DeleteTabContentsOnDestroyedObserver : public NotificationObserver {
484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch public:
49201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DeleteTabContentsOnDestroyedObserver(TabContentsWrapper* source,
50201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                       TabContentsWrapper* tab_to_delete)
514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      : source_(source),
524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        tab_to_delete_(tab_to_delete) {
534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    registrar_.Add(this,
544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                   NotificationType::TAB_CONTENTS_DESTROYED,
55201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                   Source<TabContents>(source->tab_contents()));
564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void Observe(NotificationType type,
594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                       const NotificationSource& source,
604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                       const NotificationDetails& details) {
61201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* tab_to_delete = tab_to_delete_;
624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    tab_to_delete_ = NULL;
634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    delete tab_to_delete;
644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch private:
67201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* source_;
68201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* tab_to_delete_;
694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  NotificationRegistrar registrar_;
704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(DeleteTabContentsOnDestroyedObserver);
724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch};
734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}  // namespace
754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TabStripDummyDelegate : public TabStripModelDelegate {
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
78201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  explicit TabStripDummyDelegate(TabContentsWrapper* dummy)
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : dummy_contents_(dummy), can_close_(true), run_unload_(false) {}
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~TabStripDummyDelegate() {}
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_can_close(bool value) { can_close_ = value; }
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_run_unload_listener(bool value) { run_unload_ = value; }
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Overridden from TabStripModelDelegate:
86201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual TabContentsWrapper* AddBlankTab(bool foreground) {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
89201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual TabContentsWrapper* AddBlankTabAt(int index, bool foreground) {
90201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return NULL;
91201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
92201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual Browser* CreateNewStripWithContents(TabContentsWrapper* contents,
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              const gfx::Rect& window_bounds,
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                              const DockInfo& dock_info,
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                              bool maximize) {
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
98201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void ContinueDraggingDetachedTab(TabContentsWrapper* contents,
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const gfx::Rect& window_bounds,
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           const gfx::Rect& tab_bounds) {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int GetDragActions() const { return 0; }
103201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual TabContentsWrapper* CreateTabContentsForURL(
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const GURL& url,
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const GURL& referrer,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Profile* profile,
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      PageTransition::Type transition,
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bool defer_load,
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SiteInstance* instance) const {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (url == GURL(chrome::kChromeUINewTabURL))
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return dummy_contents_;
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool CanDuplicateContentsAt(int index) { return false; }
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void DuplicateContentsAt(int index) {}
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void CloseFrameAfterDragSession() {}
117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void CreateHistoricalTab(TabContentsWrapper* contents) {}
118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual bool RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return run_unload_;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool CanRestoreTab() { return false; }
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void RestoreTab() {}
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool CanCloseContentsAt(int index) { return can_close_ ; }
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool CanBookmarkAllTabs() const { return false; }
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void BookmarkAllTabs() {}
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual bool CanCloseTab() const { return true; }
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool UseVerticalTabs() const { return false; }
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ToggleUseVerticalTabs() {}
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual bool LargeIconsPermitted() const { return true; }
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A dummy TabContents we give to callers that expect us to actually build a
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Destinations tab for them.
134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* dummy_contents_;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Whether tabs can be closed.
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool can_close_;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Whether to report that we need to run an unload listener before closing.
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool run_unload_;
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(TabStripDummyDelegate);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass TabStripModelTest : public RenderViewHostTestHarness {
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* CreateTabContents() {
148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return Browser::TabContentsFactory(profile(), NULL, 0, NULL, NULL);
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* CreateTabContentsWithSharedRPH(
152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      TabContents* tab_contents) {
153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* retval = Browser::TabContentsFactory(profile(),
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        tab_contents->render_view_host()->site_instance(), MSG_ROUTING_NONE,
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        NULL, NULL);
156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    EXPECT_EQ(retval->tab_contents()->GetRenderProcessHost(),
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              tab_contents->GetRenderProcessHost());
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return retval;
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Forwards a URL "load" request through to our dummy TabContents
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // implementation.
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void LoadURL(TabContents* con, const std::wstring& url) {
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    controller().LoadURL(GURL(WideToUTF16(url)), GURL(), PageTransition::LINK);
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void GoBack(TabContents* contents) {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    controller().GoBack();
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void GoForward(TabContents* contents) {
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    controller().GoForward();
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SwitchTabTo(TabContents* contents) {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // contents()->DidBecomeSelected();
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sets the id of the specified contents.
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetID(TabContents* contents, int id) {
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetIDAccessor()->SetProperty(contents->property_bag(), id);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the id of the specified contents.
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetID(TabContents* contents) {
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return *GetIDAccessor()->GetProperty(contents->property_bag());
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the state of the given tab strip as a string. The state consists
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of the ID of each tab contents followed by a 'p' if pinned. For example,
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // if the model consists of two tabs with ids 2 and 1, with the first
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // tab pinned, this returns "2p 1".
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string GetPinnedState(const TabStripModel& model) {
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string actual;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < model.count(); ++i) {
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (i > 0)
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        actual += " ";
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
199201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      actual +=
200201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          base::IntToString(GetID(model.GetTabContentsAt(i)->tab_contents()));
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (model.IsAppTab(i))
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        actual += "a";
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (model.IsTabPinned(i))
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        actual += "p";
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return actual;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string GetIndicesClosedByCommandAsString(
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const TabStripModel& model,
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int index,
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ContextMenuCommand id) const {
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<int> indices = model.GetIndicesClosedByCommand(index, id);
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string result;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < indices.size(); ++i) {
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (i != 0)
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        result += " ";
2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      result += base::IntToString(indices[i]);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return result;
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void PrepareTabstripForSelectionTest(TabStripModel* model,
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                       int tab_count,
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                       int pinned_count,
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                       const std::string& selected_tabs) {
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (int i = 0; i < tab_count; ++i) {
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabContentsWrapper* contents = CreateTabContents();
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      SetID(contents->tab_contents(), i);
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      model->AppendTabContents(contents, true);
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (int i = 0; i < pinned_count; ++i)
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      model->SetTabPinned(i, true);
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabStripSelectionModel selection_model;
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::vector<std::string> selection;
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::SplitStringAlongWhitespace(selected_tabs, &selection);
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (size_t i = 0; i < selection.size(); ++i) {
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      int value;
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ASSERT_TRUE(base::StringToInt(selection[i], &value));
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      selection_model.AddIndexToSelection(value);
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    selection_model.set_active(selection_model.selected_indices()[0]);
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    model->SetSelectionFromModel(selection_model);
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PropertyAccessor<int>* GetIDAccessor() {
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    static PropertyAccessor<int> accessor;
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return &accessor;
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring test_dir_;
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring profile_path_;
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<TabContents*, int> foo_;
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // ProfileManager requires a ui::SystemMonitor.
26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui::SystemMonitor system_monitor;
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileManager pm_;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockTabStripModelObserver : public TabStripModelObserver {
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTabStripModelObserver() : empty_(true) {}
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~MockTabStripModelObserver() {
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    STLDeleteContainerPointers(states_.begin(), states_.end());
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum TabStripModelObserverAction {
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    INSERT,
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CLOSE,
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DETACH,
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SELECT,
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MOVE,
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CHANGE,
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PINNED,
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    REPLACED
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct State {
284201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    State(TabContentsWrapper* a_dst_contents,
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          int a_dst_index,
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          TabStripModelObserverAction a_action)
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        : src_contents(NULL),
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          dst_contents(a_dst_contents),
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          src_index(-1),
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          dst_index(a_dst_index),
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          user_gesture(false),
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          foreground(false),
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          action(a_action) {
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* src_contents;
297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* dst_contents;
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int src_index;
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int dst_index;
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool user_gesture;
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool foreground;
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabStripModelObserverAction action;
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetStateCount() const {
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return static_cast<int>(states_.size());
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  State* GetStateAt(int index) const {
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(index >= 0 && index < GetStateCount());
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return states_.at(index);
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool StateEquals(int index, const State& state) {
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State* s = GetStateAt(index);
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(state.src_contents, s->src_contents);
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(state.dst_contents, s->dst_contents);
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(state.src_index, s->src_index);
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(state.dst_index, s->dst_index);
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(state.user_gesture, s->user_gesture);
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(state.foreground, s->foreground);
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(state.action, s->action);
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return (s->src_contents == state.src_contents &&
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            s->dst_contents == state.dst_contents &&
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            s->src_index == state.src_index &&
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            s->dst_index == state.dst_index &&
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            s->user_gesture == state.user_gesture &&
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            s->foreground == state.foreground &&
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            s->action == state.action);
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabStripModelObserver implementation:
333201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void TabInsertedAt(TabContentsWrapper* contents,
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             int index,
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool foreground) {
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    empty_ = false;
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State* s = new State(contents, index, INSERT);
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s->foreground = foreground;
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.push_back(s);
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
341201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void TabSelectedAt(TabContentsWrapper* old_contents,
342201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                             TabContentsWrapper* new_contents,
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             int index,
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool user_gesture) {
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State* s = new State(new_contents, index, SELECT);
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s->src_contents = old_contents;
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s->user_gesture = user_gesture;
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.push_back(s);
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TabMoved(
351201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      TabContentsWrapper* contents, int from_index, int to_index) {
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State* s = new State(contents, to_index, MOVE);
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s->src_index = from_index;
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.push_back(s);
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  virtual void TabClosingAt(TabStripModel* tab_strip_model,
358201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            TabContentsWrapper* contents,
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                            int index) {
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.push_back(new State(contents, index, CLOSE));
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
362201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void TabDetachedAt(TabContentsWrapper* contents, int index) {
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.push_back(new State(contents, index, DETACH));
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
365201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void TabChangedAt(TabContentsWrapper* contents, int index,
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            TabChangeType change_type) {
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.push_back(new State(contents, index, CHANGE));
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
36972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void TabReplacedAt(TabStripModel* tab_strip_model,
37072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             TabContentsWrapper* old_contents,
37172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             TabContentsWrapper* new_contents,
37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             int index) {
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State* s = new State(new_contents, index, REPLACED);
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s ->src_contents = old_contents;
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.push_back(s);
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
377201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.push_back(new State(contents, index, PINNED));
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TabStripEmpty() {
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    empty_ = true;
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ClearStates() {
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    STLDeleteContainerPointers(states_.begin(), states_.end());
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    states_.clear();
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool empty() const { return empty_; }
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<State*> states_;
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool empty_;
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver);
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, TestBasicAPI) {
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTabStripModelObserver observer;
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddObserver(&observer);
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef MockTabStripModelObserver::State State;
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note! The ordering of these tests is important, each subsequent test
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // builds on the state established in the previous. This is important if you
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ever insert tests rather than append.
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test AppendTabContents, ContainsIndex
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(tabstrip.ContainsIndex(0));
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.AppendTabContents(contents1, true);
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(tabstrip.ContainsIndex(0));
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, tabstrip.count());
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(2, observer.GetStateCount());
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(contents1, 0, MockTabStripModelObserver::INSERT);
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s1.foreground = true;
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s2(contents1, 0, MockTabStripModelObserver::SELECT);
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s2.src_contents = NULL;
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(1, s2));
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test InsertTabContentsAt, foreground tab.
432201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tabstrip.InsertTabContentsAt(1, contents2, TabStripModel::ADD_ACTIVE);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(2, tabstrip.count());
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(2, observer.GetStateCount());
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(contents2, 1, MockTabStripModelObserver::INSERT);
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s1.foreground = true;
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s2(contents2, 1, MockTabStripModelObserver::SELECT);
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s2.src_contents = contents1;
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(1, s2));
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test InsertTabContentsAt, background tab.
448201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.InsertTabContentsAt(2, contents3, TabStripModel::ADD_NONE);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(3, tabstrip.count());
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, observer.GetStateCount());
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(contents3, 2, MockTabStripModelObserver::INSERT);
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s1.foreground = false;
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test ActivateTabAt
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tabstrip.ActivateTabAt(2, true);
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, observer.GetStateCount());
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(contents3, 2, MockTabStripModelObserver::SELECT);
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s1.src_contents = contents2;
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s1.user_gesture = true;
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test DetachTabContentsAt
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Detach
474201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* detached = tabstrip.DetachTabContentsAt(2);
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // ... and append again because we want this for later.
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.AppendTabContents(detached, true);
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(4, observer.GetStateCount());
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(detached, 2, MockTabStripModelObserver::DETACH);
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s2(contents2, 1, MockTabStripModelObserver::SELECT);
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s2.src_contents = contents3;
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s2.user_gesture = false;
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(1, s2));
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s3(detached, 2, MockTabStripModelObserver::INSERT);
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s3.foreground = true;
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(2, s3));
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s4(detached, 2, MockTabStripModelObserver::SELECT);
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s4.src_contents = contents2;
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s4.user_gesture = false;
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(3, s4));
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test CloseTabContentsAt
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Let's test nothing happens when the delegate veto the close.
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate.set_can_close(false);
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE));
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(3, tabstrip.count());
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, observer.GetStateCount());
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now let's close for real.
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate.set_can_close(true);
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE));
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(2, tabstrip.count());
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(3, observer.GetStateCount());
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(contents3, 2, MockTabStripModelObserver::CLOSE);
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s2(contents3, 2, MockTabStripModelObserver::DETACH);
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(1, s2));
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s3(contents2, 1, MockTabStripModelObserver::SELECT);
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s3.src_contents = contents3;
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s3.user_gesture = false;
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(2, s3));
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test MoveTabContentsAt, select_after_move == true
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.MoveTabContentsAt(1, 0, true);
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, observer.GetStateCount());
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(contents2, 0, MockTabStripModelObserver::MOVE);
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s1.src_index = 1;
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(0, tabstrip.active_index());
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test MoveTabContentsAt, select_after_move == false
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.MoveTabContentsAt(1, 0, false);
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, observer.GetStateCount());
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(contents1, 0, MockTabStripModelObserver::MOVE);
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    s1.src_index = 1;
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(1, tabstrip.active_index());
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.MoveTabContentsAt(0, 1, false);
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test Getters
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(contents2, tabstrip.GetSelectedTabContents());
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(contents2, tabstrip.GetTabContentsAt(0));
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(contents1, tabstrip.GetTabContentsAt(1));
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, tabstrip.GetIndexOfTabContents(contents2));
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, tabstrip.GetIndexOfTabContents(contents1));
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, tabstrip.GetIndexOfController(&contents2->controller()));
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, tabstrip.GetIndexOfController(&contents1->controller()));
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test UpdateTabContentsStateAt
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.UpdateTabContentsStateAt(0, TabStripModelObserver::ALL);
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, observer.GetStateCount());
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State s1(contents2, 0, MockTabStripModelObserver::CHANGE);
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, s1));
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test SelectNextTab, SelectPreviousTab, SelectLastTab
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure the second of the two tabs is selected first...
567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tabstrip.ActivateTabAt(1, true);
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SelectPreviousTab();
569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(0, tabstrip.active_index());
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SelectLastTab();
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(1, tabstrip.active_index());
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SelectNextTab();
573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(0, tabstrip.active_index());
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test CloseSelectedTabs
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tabstrip.CloseSelectedTabs();
579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // |CloseSelectedTabs| calls CloseTabContentsAt, we already tested that, now
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // just verify that the count and selected index have changed
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // appropriately...
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, tabstrip.count());
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(0, tabstrip.active_index());
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabStripModel should now be empty.
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Opener methods are tested below...
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.RemoveObserver(&observer);
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, TestBasicOpenerAPI) {
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is a basic test of opener functionality. opener_contents is created
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // as the first tab in the strip and then we create 5 other tabs in the
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // background with opener_contents set as their opener.
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
604201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* opener_contents = CreateTabContents();
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController* opener = &opener_contents->controller();
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(opener_contents, true);
607201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
608201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
609201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
610201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents4 = CreateTabContents();
611201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents5 = CreateTabContents();
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We use |InsertTabContentsAt| here instead of AppendTabContents so that
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // openership relationships are preserved.
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(tabstrip.count(), contents1,
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               TabStripModel::ADD_INHERIT_GROUP);
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(tabstrip.count(), contents2,
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               TabStripModel::ADD_INHERIT_GROUP);
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(tabstrip.count(), contents3,
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               TabStripModel::ADD_INHERIT_GROUP);
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(tabstrip.count(), contents4,
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               TabStripModel::ADD_INHERIT_GROUP);
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(tabstrip.count(), contents5,
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               TabStripModel::ADD_INHERIT_GROUP);
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // All the tabs should have the same opener.
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 1; i < tabstrip.count(); ++i)
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(opener, tabstrip.GetOpenerOfTabContentsAt(i));
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If there is a next adjacent item, then the index should be of that item.
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 1, false));
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the last tab in the group is closed, the preceding tab in the same
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // group should be selected.
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 5, false));
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tests the method that finds the last tab opened by the same opener in the
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // strip (this is the insertion index for the next background tab for the
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // specified opener).
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(5, tabstrip.GetIndexOfLastTabContentsOpenedBy(opener, 1));
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For a tab that has opened no other tabs, the return value should always be
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // -1...
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController* o1 = &contents1->controller();
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfNextTabContentsOpenedBy(o1, 3, false));
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfLastTabContentsOpenedBy(o1, 3));
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ForgetAllOpeners should destroy all opener relationships.
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.ForgetAllOpeners();
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 1, false));
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 5, false));
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfLastTabContentsOpenedBy(opener, 1));
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
657201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic int GetInsertionIndex(TabStripModel* tabstrip,
658201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                             TabContentsWrapper* contents) {
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return tabstrip->order_controller()->DetermineInsertionIndex(
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents, PageTransition::LINK, false);
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void InsertTabContentses(TabStripModel* tabstrip,
664201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                TabContentsWrapper* contents1,
665201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                TabContentsWrapper* contents2,
666201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                TabContentsWrapper* contents3) {
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip->InsertTabContentsAt(GetInsertionIndex(tabstrip, contents1),
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                contents1, TabStripModel::ADD_INHERIT_GROUP);
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip->InsertTabContentsAt(GetInsertionIndex(tabstrip, contents2),
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                contents2, TabStripModel::ADD_INHERIT_GROUP);
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip->InsertTabContentsAt(GetInsertionIndex(tabstrip, contents3),
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                contents3, TabStripModel::ADD_INHERIT_GROUP);
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests opening background tabs.
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, TestLTRInsertionOptions) {
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
681201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* opener_contents = CreateTabContents();
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(opener_contents, true);
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
684201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
685201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
686201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test LTR
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents1, tabstrip.GetTabContentsAt(1));
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents2, tabstrip.GetTabContentsAt(2));
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents3, tabstrip.GetTabContentsAt(3));
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests inserting tabs with InsertAfter set to false.
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, InsertBefore) {
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.SetInsertionPolicy(TabStripModel::INSERT_BEFORE);
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
705201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
706201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
707201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The order should be reversed.
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents3, tabstrip.GetTabContentsAt(0));
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents2, tabstrip.GetTabContentsAt(1));
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents1, tabstrip.GetTabContentsAt(2));
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests opening background tabs with InsertAfter set to false.
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, InsertBeforeOpeners) {
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.SetInsertionPolicy(TabStripModel::INSERT_BEFORE);
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
726201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* opener_contents = CreateTabContents();
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(opener_contents, true);
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
729201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
730201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
731201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The order should be reversed.
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents3, tabstrip.GetTabContentsAt(0));
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents2, tabstrip.GetTabContentsAt(1));
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents1, tabstrip.GetTabContentsAt(2));
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This test constructs a tabstrip, and then simulates loading several tabs in
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the background from link clicks on the first tab. Then it simulates opening
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a new tab from the first tab in the foreground via a link click, verifies
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// that this tab is opened adjacent to the opener, then closes it.
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Finally it tests that a tab opened for some non-link purpose openes at the
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// end of the strip, not bundled to any existing context.
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, TestInsertionIndexDetermination) {
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
755201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* opener_contents = CreateTabContents();
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController* opener = &opener_contents->controller();
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(opener_contents, true);
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open some other random unrelated tab in the background to monkey with our
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // insertion index.
761201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* other_contents = CreateTabContents();
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(other_contents, false);
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
764201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
765201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
766201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start by testing LTR
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(opener_contents, tabstrip.GetTabContentsAt(0));
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents1, tabstrip.GetTabContentsAt(1));
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents2, tabstrip.GetTabContentsAt(2));
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(contents3, tabstrip.GetTabContentsAt(3));
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(other_contents, tabstrip.GetTabContentsAt(4));
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The opener API should work...
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 2, false));
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 3, false));
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, tabstrip.GetIndexOfLastTabContentsOpenedBy(opener, 1));
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now open a foreground tab from a link. It should be opened adjacent to the
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // opener tab.
783201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* fg_link_contents = CreateTabContents();
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int insert_index = tabstrip.order_controller()->DetermineInsertionIndex(
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      fg_link_contents, PageTransition::LINK, true);
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, insert_index);
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(insert_index, fg_link_contents,
788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               TabStripModel::ADD_ACTIVE |
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               TabStripModel::ADD_INHERIT_GROUP);
790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, tabstrip.active_index());
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(fg_link_contents, tabstrip.GetSelectedTabContents());
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now close this contents. The selection should move to the opener contents.
794ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
795ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now open a new empty tab. It should open at the end of the strip.
798201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* fg_nonlink_contents = CreateTabContents();
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  insert_index = tabstrip.order_controller()->DetermineInsertionIndex(
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      fg_nonlink_contents, PageTransition::AUTO_BOOKMARK, true);
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(tabstrip.count(), insert_index);
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We break the opener relationship...
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(insert_index, fg_nonlink_contents,
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               TabStripModel::ADD_NONE);
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now select it, so that user_gesture == true causes the opener relationship
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to be forgotten...
807ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(tabstrip.count() - 1, true);
808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(tabstrip.count() - 1, tabstrip.active_index());
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(fg_nonlink_contents, tabstrip.GetSelectedTabContents());
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Verify that all opener relationships are forgotten.
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 2, false));
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 3, false));
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfNextTabContentsOpenedBy(opener, 3, false));
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(-1, tabstrip.GetIndexOfLastTabContentsOpenedBy(opener, 1));
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that selection is shifted to the correct tab when a tab is closed.
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// If a tab is in the background when it is closed, the selection does not
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// change.
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// If a tab is in the foreground (selected),
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   If that tab does not have an opener, selection shifts to the right.
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   If the tab has an opener,
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//     The next tab (scanning LTR) in the entire strip that has the same opener
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//     is selected
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//     If there are no other tabs that have the same opener,
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//       The opener is selected
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, TestSelectOnClose) {
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
837201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* opener_contents = CreateTabContents();
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(opener_contents, true);
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
840201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
841201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
842201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that we use Detach instead of Close throughout this test to avoid
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // having to keep reconstructing these TabContentses.
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First test that closing tabs that are in the background doesn't adjust the
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // current selection.
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.DetachTabContentsAt(1);
853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = tabstrip.count() - 1; i >= 1; --i)
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.DetachTabContentsAt(i);
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now test that when a tab doesn't have an opener, selection shifts to the
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // right when the tab is closed.
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.ForgetAllOpeners();
864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(1, true);
865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, tabstrip.active_index());
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.DetachTabContentsAt(1);
867ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, tabstrip.active_index());
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.DetachTabContentsAt(1);
869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, tabstrip.active_index());
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.DetachTabContentsAt(1);
871ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = tabstrip.count() - 1; i >= 1; --i)
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.DetachTabContentsAt(i);
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now test that when a tab does have an opener, it selects the next tab
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // opened by the same opener scanning LTR when it is closed.
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(2, false);
881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, tabstrip.active_index());
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE);
883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, tabstrip.active_index());
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE);
885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, tabstrip.active_index());
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseTabContentsAt(1, TabStripModel::CLOSE_NONE);
887ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Finally test that when a tab has no "siblings" that the opener is
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // selected.
890201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* other_contents = CreateTabContents();
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(1, other_contents, TabStripModel::ADD_NONE);
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, tabstrip.count());
893201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* opened_contents = CreateTabContents();
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.InsertTabContentsAt(2, opened_contents,
895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               TabStripModel::ADD_ACTIVE |
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               TabStripModel::ADD_INHERIT_GROUP);
897ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, tabstrip.active_index());
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE);
899ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
900ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests IsContextMenuCommandEnabled and ExecuteContextMenuCommand with
906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// CommandCloseTab.
907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(TabStripModelTest, CommandCloseTab) {
908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripDummyDelegate delegate(NULL);
909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripModel tabstrip(&delegate, profile());
910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Make sure can_close is honored.
913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 1, 0, "0"));
915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  0, TabStripModel::CommandCloseTab));
917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate.set_can_close(false);
918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   0, TabStripModel::CommandCloseTab));
920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate.set_can_close(true);
921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTab);
922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(tabstrip.empty());
923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Make sure close on a tab that is selected effects all the selected tabs.
925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1"));
927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  0, TabStripModel::CommandCloseTab));
929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTab);
930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should have closed tabs 0 and 1.
931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("2", GetPinnedState(tabstrip));
932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Select two tabs and make close on a tab that isn't selected doesn't effect
937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // selected tabs.
938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1"));
940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  2, TabStripModel::CommandCloseTab));
942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(2, TabStripModel::CommandCloseTab);
943ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should have closed tab 2.
944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("0 1", GetPinnedState(tabstrip));
945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
946ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
947ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
948ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Tests with 3 tabs, one pinned, two tab selected, one of which is pinned.
949ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
950ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 1, "0 1"));
951ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
952ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  0, TabStripModel::CommandCloseTab));
953ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTab);
954ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should have closed tab 2.
955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("2", GetPinnedState(tabstrip));
956ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
957ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
958ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
959ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
960ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests IsContextMenuCommandEnabled and ExecuteContextMenuCommand with
961ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// CommandCloseTabs.
962ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(TabStripModelTest, CommandCloseOtherTabs) {
963ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripDummyDelegate delegate(NULL);
964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripModel tabstrip(&delegate, profile());
965ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create three tabs, select two tabs, CommandCloseOtherTabs should be enabled
968ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // and close two tabs.
969ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
970ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1"));
971ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  0, TabStripModel::CommandCloseOtherTabs));
973ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseOtherTabs);
974ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("0 1", GetPinnedState(tabstrip));
975ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
977ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Select two tabs, CommandCloseOtherTabs should be enabled and invoking it
979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // with a non-selected index should close the two other tabs.
980ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1"));
982ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
983ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  2, TabStripModel::CommandCloseOtherTabs));
984ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseOtherTabs);
985ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("0 1", GetPinnedState(tabstrip));
986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
987ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
988ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
989ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Select all, CommandCloseOtherTabs should not be enabled.
990ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1 2"));
992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(tabstrip.IsContextMenuCommandEnabled(
993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  2, TabStripModel::CommandCloseOtherTabs));
994ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
995ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
996ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Three tabs, pin one, select the two non-pinned.
998ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 1, "1 2"));
1000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(tabstrip.IsContextMenuCommandEnabled(
1001ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  1, TabStripModel::CommandCloseOtherTabs));
1002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If we don't pass in the pinned index, the command should be enabled.
1003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  0, TabStripModel::CommandCloseOtherTabs));
1005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
1006ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
1007ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1008ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // 3 tabs, one pinned.
1009ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
1010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 1, "1"));
1011ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1012ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  1, TabStripModel::CommandCloseOtherTabs));
1013ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1014ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  0, TabStripModel::CommandCloseOtherTabs));
1015ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(1, TabStripModel::CommandCloseOtherTabs);
1016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The pinned tab shouldn't be closed.
1017ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("0p 1", GetPinnedState(tabstrip));
1018ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
1019ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
1020ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1022ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests IsContextMenuCommandEnabled and ExecuteContextMenuCommand with
1023ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// CommandCloseTabsToRight.
1024ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(TabStripModelTest, CommandCloseTabsToRight) {
1025ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripDummyDelegate delegate(NULL);
1026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripModel tabstrip(&delegate, profile());
1027ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
1028ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1029ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create three tabs, select last two tabs, CommandCloseTabsToRight should
1030ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // only be enabled for the first tab.
1031ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
1032ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "1 2"));
1033ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1034ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  0, TabStripModel::CommandCloseTabsToRight));
1035ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(tabstrip.IsContextMenuCommandEnabled(
1036ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   1, TabStripModel::CommandCloseTabsToRight));
1037ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(tabstrip.IsContextMenuCommandEnabled(
1038ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   2, TabStripModel::CommandCloseTabsToRight));
1039ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTabsToRight);
1040ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("0", GetPinnedState(tabstrip));
1041ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseAllTabs();
1042ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
1043ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1044ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1045ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests IsContextMenuCommandEnabled and ExecuteContextMenuCommand with
1046ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// CommandTogglePinned.
1047ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(TabStripModelTest, CommandTogglePinned) {
1048ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripDummyDelegate delegate(NULL);
1049ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripModel tabstrip(&delegate, profile());
1050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.empty());
1051ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1052ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create three tabs with one pinned, pin the first two.
1053ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NO_FATAL_FAILURE(
1054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PrepareTabstripForSelectionTest(&tabstrip, 3, 1, "0 1"));
1055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1056ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  0, TabStripModel::CommandTogglePinned));
1057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  1, TabStripModel::CommandTogglePinned));
1059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  2, TabStripModel::CommandTogglePinned));
1061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandTogglePinned);
1062ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("0p 1p 2", GetPinnedState(tabstrip));
1063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1064ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Execute CommandTogglePinned again, this should unpin.
1065ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandTogglePinned);
1066ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("0 1 2", GetPinnedState(tabstrip));
1067ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1068ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Pin the last.
1069ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ExecuteContextMenuCommand(2, TabStripModel::CommandTogglePinned);
1070ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ("2p 0 1", GetPinnedState(tabstrip));
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests the following context menu commands:
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//  - Close Tab
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//  - Close Other Tabs
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//  - Close Tabs To Right
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, TestContextMenuCloseCommands) {
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1085201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* opener_contents = CreateTabContents();
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(opener_contents, true);
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1088201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
1089201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
1090201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
1093ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
1094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.ExecuteContextMenuCommand(2, TabStripModel::CommandCloseTab);
1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, tabstrip.count());
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTabsToRight);
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, tabstrip.count());
1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(opener_contents, tabstrip.GetSelectedTabContents());
1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* dummy_contents = CreateTabContents();
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(dummy_contents, false);
1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents1 = CreateTabContents();
1106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents2 = CreateTabContents();
1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents3 = CreateTabContents();
1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertTabContentses(&tabstrip, contents1, contents2, contents3);
1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(5, tabstrip.count());
1110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int dummy_index = tabstrip.count() - 1;
1112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(dummy_index, true);
1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(dummy_contents, tabstrip.GetSelectedTabContents());
1114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.ExecuteContextMenuCommand(dummy_index,
1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     TabStripModel::CommandCloseOtherTabs);
1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, tabstrip.count());
1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(dummy_contents, tabstrip.GetSelectedTabContents());
1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests GetIndicesClosedByCommand.
1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, GetIndicesClosedByCommand) {
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
1131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
1132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
1133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents4 = CreateTabContents();
1134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents5 = CreateTabContents();
1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents1, true);
1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents2, true);
1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents3, true);
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents4, true);
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents5, true);
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("4 3 2 1", GetIndicesClosedByCommandAsString(
1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                tabstrip, 0, TabStripModel::CommandCloseTabsToRight));
1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("4 3 2", GetIndicesClosedByCommandAsString(
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                tabstrip, 1, TabStripModel::CommandCloseTabsToRight));
1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("4 3 2 1", GetIndicesClosedByCommandAsString(
1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                tabstrip, 0, TabStripModel::CommandCloseOtherTabs));
1149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("4 3 2 0", GetIndicesClosedByCommandAsString(
1150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                tabstrip, 1, TabStripModel::CommandCloseOtherTabs));
1151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pin the first two tabs. Pinned tabs shouldn't be closed by the close other
1153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // commands.
1154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.SetTabPinned(0, true);
1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.SetTabPinned(1, true);
1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("4 3 2", GetIndicesClosedByCommandAsString(
1158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                tabstrip, 0, TabStripModel::CommandCloseTabsToRight));
1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("4 3", GetIndicesClosedByCommandAsString(
1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                tabstrip, 2, TabStripModel::CommandCloseTabsToRight));
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("4 3 2", GetIndicesClosedByCommandAsString(
1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                tabstrip, 0, TabStripModel::CommandCloseOtherTabs));
1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("4 3", GetIndicesClosedByCommandAsString(
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                tabstrip, 2, TabStripModel::CommandCloseOtherTabs));
1166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests whether or not TabContentses are inserted in the correct position
1172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// using this "smart" function with a simulated middle click action on a series
1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of links on the home page.
1174c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, AddTabContents_MiddleClickLinksAndClose) {
1175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the Home Page
1180201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* homepage_contents = CreateTabContents();
1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      homepage_contents, -1, PageTransition::AUTO_BOOKMARK,
1183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open some other tab, by user typing.
1186201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* typed_page_contents = CreateTabContents();
1187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      typed_page_contents, -1, PageTransition::TYPED,
1189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, tabstrip.count());
1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Re-select the home page.
1194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(0, true);
1195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a bunch of tabs by simulating middle clicking on links on the home
1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // page.
1198201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* middle_click_contents1 = CreateTabContents();
1199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      middle_click_contents1, -1, PageTransition::LINK,
1201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1202201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* middle_click_contents2 = CreateTabContents();
1203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      middle_click_contents2, -1, PageTransition::LINK,
1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* middle_click_contents3 = CreateTabContents();
1207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      middle_click_contents3, -1, PageTransition::LINK,
1209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(5, tabstrip.count());
1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(homepage_contents, tabstrip.GetTabContentsAt(0));
1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(middle_click_contents1, tabstrip.GetTabContentsAt(1));
1215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(middle_click_contents2, tabstrip.GetTabContentsAt(2));
1216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(middle_click_contents3, tabstrip.GetTabContentsAt(3));
1217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(typed_page_contents, tabstrip.GetTabContentsAt(4));
1218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now simulate seleting a tab in the middle of the group of tabs opened from
1220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the home page and start closing them. Each TabContents in the group should
1221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be closed, right to left. This test is constructed to start at the middle
1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabContents in the group to make sure the cursor wraps around to the first
1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabContents in the group before closing the opener or any other
1224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabContents.
1225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(2, true);
1226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(middle_click_contents3, tabstrip.GetSelectedTabContents());
1228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(middle_click_contents1, tabstrip.GetSelectedTabContents());
1230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(homepage_contents, tabstrip.GetSelectedTabContents());
1232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(typed_page_contents, tabstrip.GetSelectedTabContents());
1234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, tabstrip.count());
1236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests whether or not a TabContents created by a left click on a link that
1242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// opens a new tab is inserted correctly adjacent to the tab that spawned it.
1243c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, AddTabContents_LeftClickPopup) {
1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the Home Page
1249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* homepage_contents = CreateTabContents();
1250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      homepage_contents, -1, PageTransition::AUTO_BOOKMARK,
1252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open some other tab, by user typing.
1255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* typed_page_contents = CreateTabContents();
1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      typed_page_contents, -1, PageTransition::TYPED,
1258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, tabstrip.count());
1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Re-select the home page.
1263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(0, true);
1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a tab by simulating a left click on a link that opens in a new tab.
1266201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* left_click_contents = CreateTabContents();
1267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(left_click_contents, -1, PageTransition::LINK,
1268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          TabStripModel::ADD_ACTIVE);
1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Verify the state meets our expectations.
1271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, tabstrip.count());
1272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(homepage_contents, tabstrip.GetTabContentsAt(0));
1273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(left_click_contents, tabstrip.GetTabContentsAt(1));
1274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(typed_page_contents, tabstrip.GetTabContentsAt(2));
1275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The newly created tab should be selected.
1277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(left_click_contents, tabstrip.GetSelectedTabContents());
1278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // After closing the selected tab, the selection should move to the left, to
1280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the opener.
1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(homepage_contents, tabstrip.GetSelectedTabContents());
1283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, tabstrip.count());
1285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests whether or not new tabs that should split context (typed pages,
1291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// generated urls, also blank tabs) open at the end of the tabstrip instead of
1292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in the middle.
1293c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, AddTabContents_CreateNewBlankTab) {
1294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the Home Page
1299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* homepage_contents = CreateTabContents();
1300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      homepage_contents, -1, PageTransition::AUTO_BOOKMARK,
1302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open some other tab, by user typing.
1305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* typed_page_contents = CreateTabContents();
1306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      typed_page_contents, -1, PageTransition::TYPED,
1308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, tabstrip.count());
1311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Re-select the home page.
1313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(0, true);
1314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a new blank tab in the foreground.
1316201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* new_blank_contents = CreateTabContents();
1317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(new_blank_contents, -1, PageTransition::TYPED,
1318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          TabStripModel::ADD_ACTIVE);
1319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Verify the state of the tabstrip.
1321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3, tabstrip.count());
1322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(homepage_contents, tabstrip.GetTabContentsAt(0));
1323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(typed_page_contents, tabstrip.GetTabContentsAt(1));
1324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(new_blank_contents, tabstrip.GetTabContentsAt(2));
1325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now open a couple more blank tabs in the background.
1327201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* background_blank_contents1 = CreateTabContents();
1328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      background_blank_contents1, -1, PageTransition::TYPED,
1330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* background_blank_contents2 = CreateTabContents();
1332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      background_blank_contents2, -1, PageTransition::GENERATED,
1334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(5, tabstrip.count());
1336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(homepage_contents, tabstrip.GetTabContentsAt(0));
1337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(typed_page_contents, tabstrip.GetTabContentsAt(1));
1338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(new_blank_contents, tabstrip.GetTabContentsAt(2));
1339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(background_blank_contents1, tabstrip.GetTabContentsAt(3));
1340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(background_blank_contents2, tabstrip.GetTabContentsAt(4));
1341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests whether opener state is correctly forgotten when the user switches
1347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// context.
1348c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, AddTabContents_ForgetOpeners) {
1349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the Home Page
1354201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* homepage_contents = CreateTabContents();
1355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      homepage_contents, -1, PageTransition::AUTO_BOOKMARK,
1357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open some other tab, by user typing.
1360201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* typed_page_contents = CreateTabContents();
1361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      typed_page_contents, -1, PageTransition::TYPED,
1363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2, tabstrip.count());
1366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Re-select the home page.
1368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(0, true);
1369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a bunch of tabs by simulating middle clicking on links on the home
1371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // page.
1372201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* middle_click_contents1 = CreateTabContents();
1373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      middle_click_contents1, -1, PageTransition::LINK,
1375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1376201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* middle_click_contents2 = CreateTabContents();
1377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      middle_click_contents2, -1, PageTransition::LINK,
1379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1380201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* middle_click_contents3 = CreateTabContents();
1381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      middle_click_contents3, -1, PageTransition::LINK,
1383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Break out of the context by selecting a tab in a different context.
1386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(typed_page_contents, tabstrip.GetTabContentsAt(4));
1387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.SelectLastTab();
1388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(typed_page_contents, tabstrip.GetSelectedTabContents());
1389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Step back into the context by selecting a tab inside it.
1391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.ActivateTabAt(2, true);
1392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(middle_click_contents2, tabstrip.GetSelectedTabContents());
1393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now test that closing tabs selects to the right until there are no more,
1395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // then to the left, as if there were no context (context has been
1396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // successfully forgotten).
1397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(middle_click_contents3, tabstrip.GetSelectedTabContents());
1399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(typed_page_contents, tabstrip.GetSelectedTabContents());
1401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(middle_click_contents1, tabstrip.GetSelectedTabContents());
1403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tabstrip.CloseSelectedTabs();
1404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(homepage_contents, tabstrip.GetSelectedTabContents());
1405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, tabstrip.count());
1407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Added for http://b/issue?id=958960
1413c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, AppendContentsReselectionTest) {
1414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* fake_destinations_tab =
1415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      new TabContents(profile(), NULL, 0, NULL, NULL);
1416201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper wrapper(fake_destinations_tab);
1417201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabStripDummyDelegate delegate(&wrapper);
1418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open the Home Page
1422201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* homepage_contents = CreateTabContents();
1423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      homepage_contents, -1, PageTransition::AUTO_BOOKMARK,
1425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open some other tab, by user typing.
1428201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* typed_page_contents = CreateTabContents();
1429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddTabContents(
1430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      typed_page_contents, -1, PageTransition::TYPED,
1431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::ADD_NONE);
1432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The selected tab should still be the first.
1434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
1435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now simulate a link click that opens a new tab (by virtue of target=_blank)
1437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and make sure the right tab gets selected when the new tab is closed.
1438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* target_blank_contents = CreateTabContents();
1439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(target_blank_contents, true);
1440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, tabstrip.active_index());
1441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE);
1442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, tabstrip.active_index());
1443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // clean up after ourselves
1445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Added for http://b/issue?id=1027661
1449c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, ReselectionConsidersChildrenTest) {
1450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel strip(&delegate, profile());
1452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open page A
1454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_a_contents = CreateTabContents();
1455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(
1456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      page_a_contents, -1, PageTransition::AUTO_BOOKMARK,
1457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_ACTIVE);
1458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate middle click to open page A.A and A.B
1460201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_a_a_contents = CreateTabContents();
1461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_a_a_contents, -1, PageTransition::LINK,
1462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_a_b_contents = CreateTabContents();
1464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_a_b_contents, -1, PageTransition::LINK,
1465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Select page A.A
1468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ActivateTabAt(1, true);
1469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(page_a_a_contents, strip.GetSelectedTabContents());
1470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate a middle click to open page A.A.A
1472201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_a_a_a_contents = CreateTabContents();
1473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_a_a_a_contents, -1, PageTransition::LINK,
1474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(page_a_a_a_contents, strip.GetTabContentsAt(2));
1477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close page A.A
1479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.CloseTabContentsAt(strip.active_index(), TabStripModel::CLOSE_NONE);
1480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Page A.A.A should be selected, NOT A.B
1482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(page_a_a_a_contents, strip.GetSelectedTabContents());
1483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close page A.A.A
1485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.CloseTabContentsAt(strip.active_index(), TabStripModel::CLOSE_NONE);
1486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Page A.B should be selected
1488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(page_a_b_contents, strip.GetSelectedTabContents());
1489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close page A.B
1491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.CloseTabContentsAt(strip.active_index(), TabStripModel::CLOSE_NONE);
1492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Page A should be selected
1494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(page_a_contents, strip.GetSelectedTabContents());
1495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clean up.
1497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseAllTabs();
1498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1500c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, AddTabContents_NewTabAtEndOfStripInheritsGroup) {
1501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel strip(&delegate, profile());
1503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open page A
1505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_a_contents = CreateTabContents();
1506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_a_contents, -1, PageTransition::START_PAGE,
1507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
1508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open pages B, C and D in the background from links on page A...
1510201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_b_contents = CreateTabContents();
1511201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_c_contents = CreateTabContents();
1512201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_d_contents = CreateTabContents();
1513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_b_contents, -1, PageTransition::LINK,
1514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_c_contents, -1, PageTransition::LINK,
1516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_d_contents, -1, PageTransition::LINK,
1518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Switch to page B's tab.
1521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ActivateTabAt(1, true);
1522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a New Tab at the end of the strip (simulate Ctrl+T)
1524201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* new_tab_contents = CreateTabContents();
1525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(new_tab_contents, -1, PageTransition::TYPED,
1526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
1527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, strip.GetIndexOfTabContents(new_tab_contents));
1529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(4, strip.active_index());
1530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close the New Tab that was just opened. We should be returned to page B's
1532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tab...
1533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseTabContentsAt(4, TabStripModel::CLOSE_NONE);
1534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, strip.active_index());
1536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a non-New Tab tab at the end of the strip, with a TYPED transition.
1538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is like typing a URL in the address bar and pressing Alt+Enter. The
1539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // behavior should be the same as above.
1540201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_e_contents = CreateTabContents();
1541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_e_contents, -1, PageTransition::TYPED,
1542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
1543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, strip.GetIndexOfTabContents(page_e_contents));
1545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(4, strip.active_index());
1546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close the Tab. Selection should shift back to page B's Tab.
1548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseTabContentsAt(4, TabStripModel::CLOSE_NONE);
1549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, strip.active_index());
1551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a non-New Tab tab at the end of the strip, with some other
1553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // transition. This is like right clicking on a bookmark and choosing "Open
1554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in New Tab". No opener relationship should be preserved between this Tab
1555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and the one that was active when the gesture was performed.
1556201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_f_contents = CreateTabContents();
1557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_f_contents, -1, PageTransition::AUTO_BOOKMARK,
1558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
1559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(4, strip.GetIndexOfTabContents(page_f_contents));
1561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(4, strip.active_index());
1562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close the Tab. The next-adjacent should be selected.
1564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseTabContentsAt(4, TabStripModel::CLOSE_NONE);
1565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(3, strip.active_index());
1567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clean up.
1569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseAllTabs();
1570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A test of navigations in a tab that is part of a group of opened from some
1573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// parent tab. If the navigations are link clicks, the group relationship of
1574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the tab to its parent are preserved. If they are of any other type, they are
1575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// not preserved.
1576c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, NavigationForgetsOpeners) {
1577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel strip(&delegate, profile());
1579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open page A
1581201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_a_contents = CreateTabContents();
1582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_a_contents, -1, PageTransition::START_PAGE,
1583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
1584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open pages B, C and D in the background from links on page A...
1586201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_b_contents = CreateTabContents();
1587201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_c_contents = CreateTabContents();
1588201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_d_contents = CreateTabContents();
1589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_b_contents, -1, PageTransition::LINK,
1590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_c_contents, -1, PageTransition::LINK,
1592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_d_contents, -1, PageTransition::LINK,
1594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open page E in a different opener group from page A.
1597201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_e_contents = CreateTabContents();
1598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_e_contents, -1, PageTransition::START_PAGE,
1599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the TabStripModel that we are navigating page D via a link click.
1602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ActivateTabAt(3, true);
1603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.TabNavigating(page_d_contents, PageTransition::LINK);
1604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close page D, page C should be selected. (part of same group).
1606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseTabContentsAt(3, TabStripModel::CLOSE_NONE);
1607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(2, strip.active_index());
1608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell the TabStripModel that we are navigating in page C via a bookmark.
1610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.TabNavigating(page_c_contents, PageTransition::AUTO_BOOKMARK);
1611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close page C, page E should be selected. (C is no longer part of the
1613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A-B-C-D group, selection moves to the right).
1614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseTabContentsAt(2, TabStripModel::CLOSE_NONE);
1615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(page_e_contents, strip.GetTabContentsAt(strip.active_index()));
1616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseAllTabs();
1618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A test that the forgetting behavior tested in NavigationForgetsOpeners above
1621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// doesn't cause the opener relationship for a New Tab opened at the end of the
1622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TabStrip to be reset (Test 1 below), unless another any other tab is
1623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// seelcted (Test 2 below).
1624c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, NavigationForgettingDoesntAffectNewTab) {
1625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel strip(&delegate, profile());
1627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a tab and several tabs from it, then select one of the tabs that was
1629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // opened.
1630201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_a_contents = CreateTabContents();
1631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_a_contents, -1, PageTransition::START_PAGE,
1632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
1633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1634201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_b_contents = CreateTabContents();
1635201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_c_contents = CreateTabContents();
1636201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* page_d_contents = CreateTabContents();
1637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_b_contents, -1, PageTransition::LINK,
1638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_c_contents, -1, PageTransition::LINK,
1640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(page_d_contents, -1, PageTransition::LINK,
1642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabStripModel::ADD_NONE);
1643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ActivateTabAt(2, true);
1645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TEST 1: If the user is in a group of tabs and opens a new tab at the end
1647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of the strip, closing that new tab will select the tab that they were
1648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // last on.
1649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now simulate opening a new tab at the end of the TabStrip.
1651201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* new_tab_contents1 = CreateTabContents();
1652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(new_tab_contents1, -1, PageTransition::TYPED,
1653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
1654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // At this point, if we close this tab the last selected one should be
1656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // re-selected.
1657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseTabContentsAt(strip.count() - 1, TabStripModel::CLOSE_NONE);
1658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(page_c_contents, strip.GetTabContentsAt(strip.active_index()));
1659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TEST 2: If the user is in a group of tabs and opens a new tab at the end
1661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of the strip, selecting any other tab in the strip will cause that new
1662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // tab's opener relationship to be forgotten.
1663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a new tab again.
1665201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* new_tab_contents2 = CreateTabContents();
1666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.AddTabContents(new_tab_contents2, -1, PageTransition::TYPED,
1667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
1668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now select the first tab.
1670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ActivateTabAt(0, true);
1671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now select the last tab.
1673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ActivateTabAt(strip.count() - 1, true);
1674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now close the last tab. The next adjacent should be selected.
1676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseTabContentsAt(strip.count() - 1, TabStripModel::CLOSE_NONE);
1677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(page_d_contents, strip.GetTabContentsAt(strip.active_index()));
1678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  strip.CloseAllTabs();
1680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that fast shutdown is attempted appropriately.
1683c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, FastShutdown) {
1684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTabStripModelObserver observer;
1687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddObserver(&observer);
1688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure fast shutdown is attempted when tabs that share a RPH are shut
1692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // down.
1693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1694201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* contents1 = CreateTabContents();
1695201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* contents2 =
1696201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        CreateTabContentsWithSharedRPH(contents1->tab_contents());
1697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1698201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SetID(contents1->tab_contents(), 1);
1699201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SetID(contents2->tab_contents(), 2);
1700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.AppendTabContents(contents1, true);
1702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.AppendTabContents(contents2, true);
1703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Turn on the fake unload listener so the tabs don't actually get shut
1705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // down when we call CloseAllTabs()---we need to be able to check that
1706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // fast shutdown was attempted.
1707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate.set_run_unload_listener(true);
1708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.CloseAllTabs();
1709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // On a mock RPH this checks whether we *attempted* fast shutdown.
1710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // A real RPH would reject our attempt since there is an unload handler.
1711201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    EXPECT_TRUE(contents1->tab_contents()->
1712201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        GetRenderProcessHost()->fast_shutdown_started());
1713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(2, tabstrip.count());
1714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delegate.set_run_unload_listener(false);
1716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.CloseAllTabs();
1717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(tabstrip.empty());
1718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure fast shutdown is not attempted when only some tabs that share a
1721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // RPH are shut down.
1722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1723201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* contents1 = CreateTabContents();
1724201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* contents2 =
1725201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        CreateTabContentsWithSharedRPH(contents1->tab_contents());
1726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1727201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SetID(contents1->tab_contents(), 1);
1728201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SetID(contents2->tab_contents(), 2);
1729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.AppendTabContents(contents1, true);
1731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.AppendTabContents(contents2, true);
1732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.CloseTabContentsAt(1, TabStripModel::CLOSE_NONE);
1734201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    EXPECT_FALSE(contents1->tab_contents()->
1735201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        GetRenderProcessHost()->fast_shutdown_started());
1736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1, tabstrip.count());
1737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.CloseAllTabs();
1739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(tabstrip.empty());
1740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests various permutations of apps.
1744c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, Apps) {
1745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTabStripModelObserver observer;
1748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddObserver(&observer);
1749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef MockTabStripModelObserver::State State;
1753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
1755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath path(FILE_PATH_LITERAL("c:\\foo"));
1756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_POSIX)
1757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath path(FILE_PATH_LITERAL("/foo"));
1758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1759513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<Extension> extension_app(new Extension(path,
1760513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                                       Extension::INVALID));
1761513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  extension_app->launch_web_url_ = "http://www.google.com";
1762201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
1763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents1->extension_tab_helper()->SetExtensionApp(extension_app);
1764201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
1765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents2->extension_tab_helper()->SetExtensionApp(extension_app);
1766201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
1767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1768201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetID(contents1->tab_contents(), 1);
1769201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetID(contents2->tab_contents(), 2);
1770201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetID(contents3->tab_contents(), 3);
1771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note! The ordering of these tests is important, each subsequent test
1773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // builds on the state established in the previous. This is important if you
1774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ever insert tests rather than append.
1775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initial state, tab3 only and selected.
1777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents3, true);
1778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observer.ClearStates();
1780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Attempt to insert tab1 (an app tab) at position 1. This isn't a legal
1782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // position and tab1 should end up at position 0.
1783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.InsertTabContentsAt(1, contents1, TabStripModel::ADD_NONE);
1785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1, observer.GetStateCount());
1787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents1, 0, MockTabStripModelObserver::INSERT);
1788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state.
17913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ("1ap 3", GetPinnedState(tabstrip));
1792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Insert tab 2 at position 1.
1797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.InsertTabContentsAt(1, contents2, TabStripModel::ADD_NONE);
1799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1, observer.GetStateCount());
1801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents2, 1, MockTabStripModelObserver::INSERT);
1802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state.
18053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ("1ap 2ap 3", GetPinnedState(tabstrip));
1806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to move tab 3 to position 0. This isn't legal and should be ignored.
1811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.MoveTabContentsAt(2, 0, false);
1813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(0, observer.GetStateCount());
1815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state didn't change.
18173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ("1ap 2ap 3", GetPinnedState(tabstrip));
1818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to move tab 0 to position 3. This isn't legal and should be ignored.
1823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.MoveTabContentsAt(0, 2, false);
1825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(0, observer.GetStateCount());
1827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state didn't change.
18293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ("1ap 2ap 3", GetPinnedState(tabstrip));
1830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to move tab 0 to position 1. This is a legal move.
1835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.MoveTabContentsAt(0, 1, false);
1837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1, observer.GetStateCount());
1839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents1, 1, MockTabStripModelObserver::MOVE);
1840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    state.src_index = 0;
1841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state didn't change.
18443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ("2ap 1ap 3", GetPinnedState(tabstrip));
1845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Remove tab3 and insert at position 0. It should be forced to position 2.
1850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.DetachTabContentsAt(2);
1852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.InsertTabContentsAt(0, contents3, TabStripModel::ADD_NONE);
1855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1, observer.GetStateCount());
1857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents3, 2, MockTabStripModelObserver::INSERT);
1858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state didn't change.
18613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_EQ("2ap 1ap 3", GetPinnedState(tabstrip));
1862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
1867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests various permutations of pinning tabs.
1870c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(TabStripModelTest, Pinning) {
1871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripDummyDelegate delegate(NULL);
1872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabStripModel tabstrip(&delegate, profile());
1873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockTabStripModelObserver observer;
1874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AddObserver(&observer);
1875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(tabstrip.empty());
1877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef MockTabStripModelObserver::State State;
1879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1880201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
1881201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
1882201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents3 = CreateTabContents();
1883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1884201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetID(contents1->tab_contents(), 1);
1885201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetID(contents2->tab_contents(), 2);
1886201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetID(contents3->tab_contents(), 3);
1887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note! The ordering of these tests is important, each subsequent test
1889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // builds on the state established in the previous. This is important if you
1890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ever insert tests rather than append.
1891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initial state, three tabs, first selected.
1893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents1, true);
1894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents2, false);
1895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.AppendTabContents(contents3, false);
1896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observer.ClearStates();
1898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pin the first tab, this shouldn't visually reorder anything.
1900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SetTabPinned(0, true);
1902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // As the order didn't change, we should get a pinned notification.
1904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1, observer.GetStateCount());
1905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents1, 0, MockTabStripModelObserver::PINNED);
1906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state.
1909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("1p 2 3", GetPinnedState(tabstrip));
1910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Unpin the first tab.
1915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SetTabPinned(0, false);
1917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // As the order didn't change, we should get a pinned notification.
1919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1, observer.GetStateCount());
1920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents1, 0, MockTabStripModelObserver::PINNED);
1921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state.
1924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("1 2 3", GetPinnedState(tabstrip));
1925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pin the 3rd tab, which should move it to the front.
1930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SetTabPinned(2, true);
1932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1933513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The pinning should have resulted in a move and a pinned notification.
1934513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    ASSERT_EQ(2, observer.GetStateCount());
1935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents3, 0, MockTabStripModelObserver::MOVE);
1936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    state.src_index = 2;
1937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1939513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    state = State(contents3, 0, MockTabStripModelObserver::PINNED);
1940513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    EXPECT_TRUE(observer.StateEquals(1, state));
1941513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state.
1943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("3p 1 2", GetPinnedState(tabstrip));
1944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pin the tab "1", which shouldn't move anything.
1949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SetTabPinned(1, true);
1951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // As the order didn't change, we should get a pinned notification.
1953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1, observer.GetStateCount());
1954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents1, 1, MockTabStripModelObserver::PINNED);
1955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state.
1958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("3p 1p 2", GetPinnedState(tabstrip));
1959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to move tab "2" to the front, it should be ignored.
1964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.MoveTabContentsAt(2, 0, false);
1966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // As the order didn't change, we should get a pinned notification.
1968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(0, observer.GetStateCount());
1969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state.
1971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("3p 1p 2", GetPinnedState(tabstrip));
1972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Unpin tab "3", which implicitly moves it to the end.
1977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SetTabPinned(0, false);
1979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1980513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    ASSERT_EQ(2, observer.GetStateCount());
1981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents3, 1, MockTabStripModelObserver::MOVE);
1982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    state.src_index = 0;
1983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
1984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1985513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    state = State(contents3, 1, MockTabStripModelObserver::PINNED);
1986513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    EXPECT_TRUE(observer.StateEquals(1, state));
1987513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // And verify the state.
1989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("1p 3 2", GetPinnedState(tabstrip));
1990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
1992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Unpin tab "3", nothing should happen.
1995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SetTabPinned(1, false);
1997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(0, observer.GetStateCount());
1999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("1p 3 2", GetPinnedState(tabstrip));
2001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
2003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pin "3" and "1".
2006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
2007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SetTabPinned(0, true);
2008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.SetTabPinned(1, true);
2009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("1p 3p 2", GetPinnedState(tabstrip));
2011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    observer.ClearStates();
2013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2015201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents4 = CreateTabContents();
2016201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetID(contents4->tab_contents(), 4);
2017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Insert "4" between "1" and "3". As "1" and "4" are pinned, "4" should end
2019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // up after them.
2020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
2021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabstrip.InsertTabContentsAt(1, contents4, TabStripModel::ADD_NONE);
2022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_EQ(1, observer.GetStateCount());
2024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state(contents4, 2, MockTabStripModelObserver::INSERT);
2025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(observer.StateEquals(0, state));
2026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("1p 3p 4 2", GetPinnedState(tabstrip));
2028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip.CloseAllTabs();
2031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Makes sure the TabStripModel calls the right observer methods during a
20343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// replace.
20353345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(TabStripModelTest, ReplaceSendsSelected) {
20363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  typedef MockTabStripModelObserver::State State;
20373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TabStripDummyDelegate delegate(NULL);
20393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TabStripModel strip(&delegate, profile());
20403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2041201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* first_contents = CreateTabContents();
20423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  strip.AddTabContents(first_contents, -1, PageTransition::TYPED,
2043ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       TabStripModel::ADD_ACTIVE);
20443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockTabStripModelObserver tabstrip_observer;
20463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  strip.AddObserver(&tabstrip_observer);
20473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2048201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* new_contents = CreateTabContents();
2049201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  delete strip.ReplaceTabContentsAt(0, new_contents);
20503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(2, tabstrip_observer.GetStateCount());
20523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // First event should be for replaced.
20543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  State state(new_contents, 0, MockTabStripModelObserver::REPLACED);
20553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state.src_contents = first_contents;
20563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(tabstrip_observer.StateEquals(0, state));
20573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // And the second for selected.
20593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state = State(new_contents, 0, MockTabStripModelObserver::SELECT);
20603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state.src_contents = first_contents;
20613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(tabstrip_observer.StateEquals(1, state));
20623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Now add another tab and replace it, making sure we don't get a selected
20643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // event this time.
2065201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* third_contents = CreateTabContents();
20663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  strip.AddTabContents(third_contents, 1, PageTransition::TYPED,
20673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       TabStripModel::ADD_NONE);
20683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tabstrip_observer.ClearStates();
20703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // And replace it.
20723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  new_contents = CreateTabContents();
2073201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  delete strip.ReplaceTabContentsAt(1, new_contents);
20743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(1, tabstrip_observer.GetStateCount());
20763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state = State(new_contents, 1, MockTabStripModelObserver::REPLACED);
20783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  state.src_contents = third_contents;
20793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(tabstrip_observer.StateEquals(0, state));
20803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  strip.CloseAllTabs();
20823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
20834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
20844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Makes sure TabStripModel handles the case of deleting a tab while removing
20854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// another tab.
20864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST_F(TabStripModelTest, DeleteFromDestroy) {
20874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  TabStripDummyDelegate delegate(NULL);
20884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  TabStripModel strip(&delegate, profile());
2089201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents1 = CreateTabContents();
2090201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents2 = CreateTabContents();
20914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  strip.AppendTabContents(contents1, true);
20924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  strip.AppendTabContents(contents2, true);
20934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // DeleteTabContentsOnDestroyedObserver deletes contents1 when contents2 sends
20944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // out notification that it is being destroyed.
20954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DeleteTabContentsOnDestroyedObserver observer(contents2, contents1);
20964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  strip.CloseAllTabs();
20974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
2098ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2099ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(TabStripModelTest, MoveSelectedTabsTo) {
2100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  struct TestData {
2101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Number of tabs the tab strip should have.
2102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const int tab_count;
2103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Number of pinned tabs.
2105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const int pinned_count;
2106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Index of the tabs to select.
2108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string selected_tabs;
2109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Index to move the tabs to.
2111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const int target_index;
2112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Expected state after the move (space separated list of indices).
2114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string state_after_move;
2115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } test_data[] = {
2116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // 1 selected tab.
2117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 2, 0, "0", 1, "1 0" },
2118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 3, 0, "0", 2, "1 2 0" },
2119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 3, 0, "2", 0, "2 0 1" },
2120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 3, 0, "2", 1, "0 2 1" },
2121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 3, 0, "0 1", 0, "0 1 2" },
2122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // 2 selected tabs.
2124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 6, 0, "4 5", 1, "0 4 5 1 2 3" },
2125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 3, 0, "0 1", 1, "2 0 1" },
2126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 4, 0, "0 2", 1, "1 0 2 3" },
2127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 6, 0, "0 1", 3, "2 3 4 0 1 5" },
2128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // 3 selected tabs.
2130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 6, 0, "0 2 3", 3, "1 4 5 0 2 3" },
2131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 7, 0, "4 5 6", 1, "0 4 5 6 1 2 3" },
2132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 7, 0, "1 5 6", 4, "0 2 3 4 1 5 6" },
2133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // 5 selected tabs.
2135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 8, 0, "0 2 3 6 7", 3, "1 4 5 0 2 3 6 7" },
2136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // 7 selected tabs
2138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 16, 0, "0 1 2 3 4 7 9", 8, "5 6 8 10 11 12 13 14 0 1 2 3 4 7 9 15" },
2139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // With pinned tabs.
2141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 6, 2, "2 3", 2, "0p 1p 2 3 4 5" },
2142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 6, 2, "0 4", 3, "1p 0p 2 3 4 5" },
2143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 6, 3, "1 2 4", 0, "1p 2p 0p 4 3 5" },
2144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 8, 3, "1 3 4", 4, "0p 2p 1p 5 6 3 4 7" },
2145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 7, 4, "2 3 4", 3, "0p 1p 2p 3p 5 4 6" },
2147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
2148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
2150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabStripDummyDelegate delegate(NULL);
2151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabStripModel strip(&delegate, profile());
2152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_NO_FATAL_FAILURE(
2153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        PrepareTabstripForSelectionTest(&strip, test_data[i].tab_count,
2154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        test_data[i].pinned_count,
2155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        test_data[i].selected_tabs));
2156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    strip.MoveSelectedTabsTo(test_data[i].target_index);
2157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(test_data[i].state_after_move, GetPinnedState(strip)) << i;
2158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    strip.CloseAllTabs();
2159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(TabStripModelTest, CloseSelectedTabs) {
2163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripDummyDelegate delegate(NULL);
2164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripModel strip(&delegate, profile());
2165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabContentsWrapper* contents1 = CreateTabContents();
2166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabContentsWrapper* contents2 = CreateTabContents();
2167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabContentsWrapper* contents3 = CreateTabContents();
2168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.AppendTabContents(contents1, true);
2169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.AppendTabContents(contents2, true);
2170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.AppendTabContents(contents3, true);
2171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ToggleSelectionAt(1);
2172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.CloseSelectedTabs();
2173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, strip.count());
2174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, strip.active_index());
2175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.CloseAllTabs();
2176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Verifies that if we change the selection from a multi selection to a single
2179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// selection, but not in a way that changes the selected_index that
2180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TabSelectedAt is still invoked.
2181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(TabStripModelTest, MultipleToSingle) {
2182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripDummyDelegate delegate(NULL);
2183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabStripModel strip(&delegate, profile());
2184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabContentsWrapper* contents1 = CreateTabContents();
2185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabContentsWrapper* contents2 = CreateTabContents();
2186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.AppendTabContents(contents1, false);
2187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.AppendTabContents(contents2, false);
2188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ToggleSelectionAt(0);
2189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ToggleSelectionAt(1);
2190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockTabStripModelObserver observer;
2192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.AddObserver(&observer);
2193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // This changes the selection (0 is no longer selected) but the selected_index
2194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // still remains at 1.
2195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.ActivateTabAt(1, true);
2196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(1, observer.GetStateCount());
2197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockTabStripModelObserver::State s(
2198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      contents2, 1, MockTabStripModelObserver::SELECT);
2199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  s.src_contents = contents2;
2200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  s.user_gesture = true;
2201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(observer.StateEquals(0, s));
2202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.RemoveObserver(&observer);
2203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  strip.CloseAllTabs();
2204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2205