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

Unified Diff: chrome/browser/ui/tabs/mru_tab_controller_unittest.cc

Issue 10117016: Implementation for switching between recently used tabs using ctrl tilde or quoteleft. Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Uploading patch for review after rebase. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/tabs/mru_tab_controller_unittest.cc
diff --git a/chrome/browser/ui/tabs/mru_tab_controller_unittest.cc b/chrome/browser/ui/tabs/mru_tab_controller_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2d99bfcbb6713461f254a54ebed1cd2cc6bf5091
--- /dev/null
+++ b/chrome/browser/ui/tabs/mru_tab_controller_unittest.cc
@@ -0,0 +1,288 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/tabs/mru_tab_controller.h"
+
+#include <map>
+#include <string>
+
+#include "base/stl_util.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/browser/ui/tab_contents/tab_contents.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
+#include "chrome/browser/ui/tabs/tab_strip_model_order_controller.h"
+#include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/test_browser_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using content::BrowserThread;
+using content::SiteInstance;
+using content::WebContents;
+
+class TabStripDummyDelegate : public TestTabStripModelDelegate {
+ public:
+ explicit TabStripDummyDelegate(TabContents* dummy)
+ : dummy_contents_(dummy),
+ can_close_(true),
+ run_unload_(false) {}
+ virtual ~TabStripDummyDelegate() {}
+
+ void set_can_close(bool value) { can_close_ = value; }
+ void set_run_unload_listener(bool value) { run_unload_ = value; }
+
+ // Overridden from TabStripModelDelegate:
+ virtual TabContents* CreateTabContentsForURL(
+ const GURL& url,
+ const content::Referrer& referrer,
+ Profile* profile,
+ content::PageTransition transition,
+ bool defer_load,
+ SiteInstance* instance) const OVERRIDE {
+ if (url == GURL(chrome::kChromeUINewTabURL))
+ return dummy_contents_;
+ return NULL;
+ }
+ virtual bool RunUnloadListenerBeforeClosing(TabContents* contents) OVERRIDE {
+ return run_unload_;
+ }
+ virtual bool CanCloseContents(std::vector<int>* indices) OVERRIDE {
+ if (!can_close_)
+ indices->clear();
+ return can_close_;
+ }
+
+ private:
+ // A dummy TabContents we give to callers that expect us to actually
+ // build a Destinations tab for them.
+ TabContents* dummy_contents_;
+
+ // Whether tabs can be closed.
+ bool can_close_;
+
+ // Whether to report that we need to run an unload listener before closing.
+ bool run_unload_;
+
+ DISALLOW_COPY_AND_ASSIGN(TabStripDummyDelegate);
+};
+
+class MRUTabControllerTest : public ChromeRenderViewHostTestHarness {
+ public:
+ MRUTabControllerTest() : browser_thread_(BrowserThread::UI, &message_loop_) {
+ }
+
+ TabContents* CreateTabContents() {
+ return chrome::TabContentsFactory(
+ profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
+ }
+
+ TabContents* CreateTabContentsWithSharedRPH(
+ WebContents* web_contents) {
+ TabContents* retval = chrome::TabContentsFactory(profile(),
+ web_contents->GetRenderViewHost()->GetSiteInstance(), MSG_ROUTING_NONE,
+ NULL, NULL);
+ EXPECT_EQ(retval->web_contents()->GetRenderProcessHost(),
+ web_contents->GetRenderProcessHost());
+ return retval;
+ }
+
+ // Forwards a URL "load" request through to our dummy TabContents
+ // implementation.
+ void LoadURL(WebContents* con, const std::wstring& url) {
+ controller().LoadURL(GURL(WideToUTF16(url)), content::Referrer(),
+ content::PAGE_TRANSITION_LINK, std::string());
+ }
+
+ void GoBack(WebContents* contents) {
+ controller().GoBack();
+ }
+
+ void GoForward(WebContents* contents) {
+ controller().GoForward();
+ }
+
+ void SwitchTabTo(WebContents* contents) {
+ // contents()->DidBecomeSelected();
+ }
+
+ // Sets the id of the specified contents.
+ void SetID(WebContents* contents, int id) {
+ GetIDAccessor()->SetProperty(contents->GetPropertyBag(), id);
+ }
+
+ // Returns the id of the specified contents.
+ int GetID(WebContents* contents) {
+ return *GetIDAccessor()->GetProperty(contents->GetPropertyBag());
+ }
+
+ // Returns the state of the given tab strip as a string. The state consists
+ // of the ID of each tab contents followed by a 'p' if pinned. For example,
+ // if the model consists of two tabs with ids 2 and 1, with the first
+ // tab pinned, this returns "2p 1".
+ std::string GetPinnedState(const TabStripModel& model) {
+ std::string actual;
+ for (int i = 0; i < model.count(); ++i) {
+ if (i > 0)
+ actual += " ";
+
+ actual +=
+ base::IntToString(GetID(model.GetTabContentsAt(i)->web_contents()));
+
+ if (model.IsAppTab(i))
+ actual += "a";
+
+ if (model.IsTabPinned(i))
+ actual += "p";
+ }
+ return actual;
+ }
+
+ std::string GetIndicesClosedByCommandAsString(
+ const TabStripModel& model,
+ int index,
+ TabStripModel::ContextMenuCommand id) const {
+ std::vector<int> indices = model.GetIndicesClosedByCommand(index, id);
+ std::string result;
+ for (size_t i = 0; i < indices.size(); ++i) {
+ if (i != 0)
+ result += " ";
+ result += base::IntToString(indices[i]);
+ }
+ return result;
+ }
+
+ void PrepareTabstripForSelectionTest(TabStripModel* model,
+ int tab_count,
+ int pinned_count,
+ const std::string& selected_tabs) {
+ for (int i = 0; i < tab_count; ++i) {
+ TabContents* contents = CreateTabContents();
+ SetID(contents->web_contents(), i);
+ model->AppendTabContents(contents, true);
+ }
+ for (int i = 0; i < pinned_count; ++i)
+ model->SetTabPinned(i, true);
+
+ TabStripSelectionModel selection_model;
+ std::vector<std::string> selection;
+ base::SplitStringAlongWhitespace(selected_tabs, &selection);
+ for (size_t i = 0; i < selection.size(); ++i) {
+ int value;
+ ASSERT_TRUE(base::StringToInt(selection[i], &value));
+ selection_model.AddIndexToSelection(value);
+ }
+ selection_model.set_active(selection_model.selected_indices()[0]);
+ model->SetSelectionFromModel(selection_model);
+ }
+
+ private:
+ base::PropertyAccessor<int>* GetIDAccessor() {
+ static base::PropertyAccessor<int> accessor;
+ return &accessor;
+ }
+
+ content::TestBrowserThread browser_thread_;
+
+ std::wstring test_dir_;
+ std::wstring profile_path_;
+};
+
+static int GetInsertionIndex(TabStripModel* tabstrip,
+ TabContents* contents) {
+ return tabstrip->order_controller()->DetermineInsertionIndex(
+ contents, content::PAGE_TRANSITION_LINK, false);
+}
+
+static void InsertTabContentses(TabStripModel* tabstrip,
+ TabContents* contents1,
+ TabContents* contents2,
+ TabContents* contents3) {
+ tabstrip->InsertTabContentsAt(GetInsertionIndex(tabstrip, contents1),
+ contents1, TabStripModel::ADD_INHERIT_GROUP);
+ tabstrip->InsertTabContentsAt(GetInsertionIndex(tabstrip, contents2),
+ contents2, TabStripModel::ADD_INHERIT_GROUP);
+ tabstrip->InsertTabContentsAt(GetInsertionIndex(tabstrip, contents3),
+ contents3, TabStripModel::ADD_INHERIT_GROUP);
+}
+
+// Test toggling between mru tabs
+TEST_F(MRUTabControllerTest, ToggleMRUTabs) {
+ TabStripDummyDelegate delegate(NULL);
+ TabStripModel tabstrip(&delegate, profile());
+ MRUTabController controller(&tabstrip);
+
+ EXPECT_TRUE(tabstrip.empty());
+
+ TabContents* opener_contents = CreateTabContents();
+ tabstrip.AppendTabContents(opener_contents, true);
+
+ TabContents* contents1 = CreateTabContents();
+ TabContents* contents2 = CreateTabContents();
+ TabContents* contents3 = CreateTabContents();
+
+ InsertTabContentses(&tabstrip, contents1, contents2, contents3);
+ EXPECT_EQ(contents1, tabstrip.GetTabContentsAt(1));
+ EXPECT_EQ(contents2, tabstrip.GetTabContentsAt(2));
+ EXPECT_EQ(contents3, tabstrip.GetTabContentsAt(3));
+
+ EXPECT_EQ(0, tabstrip.active_index());
+ tabstrip.ActivateTabAt(2, true);
+ EXPECT_EQ(2, tabstrip.active_index());
+
+ EXPECT_EQ(0, tabstrip.GetIndexOfTabContents(controller.GetPreviousMRUTab()));
+
+ tabstrip.CloseAllTabs();
+ // TabStripModel should now be empty.
+ EXPECT_TRUE(tabstrip.empty());
+}
+
+// Test toggling between mru tabs
+TEST_F(MRUTabControllerTest, PauseStackAndToggle) {
+ TabStripDummyDelegate delegate(NULL);
+ TabStripModel tabstrip(&delegate, profile());
+ MRUTabController controller(&tabstrip);
+
+ EXPECT_TRUE(tabstrip.empty());
+
+ TabContents* opener_contents = CreateTabContents();
+ tabstrip.AppendTabContents(opener_contents, true);
+
+ TabContents* contents1 = CreateTabContents();
+ TabContents* contents2 = CreateTabContents();
+ TabContents* contents3 = CreateTabContents();
+
+ InsertTabContentses(&tabstrip, contents1, contents2, contents3);
+ EXPECT_EQ(contents1, tabstrip.GetTabContentsAt(1));
+ EXPECT_EQ(contents2, tabstrip.GetTabContentsAt(2));
+ EXPECT_EQ(contents3, tabstrip.GetTabContentsAt(3));
+
+ EXPECT_EQ(0, tabstrip.active_index());
+ controller.PauseStackUpdates();
+ tabstrip.ActivateTabAt(1, true);
+ EXPECT_EQ(1, tabstrip.active_index());
+ tabstrip.ActivateTabAt(2, true);
+ EXPECT_EQ(2, tabstrip.active_index());
+ tabstrip.ActivateTabAt(3, true);
+ EXPECT_EQ(3, tabstrip.active_index());
+
+ // Commit the active tab changes now.
+ controller.CommitActiveTabChanges();
+ tabstrip.ActivateTabAt(0, true);
+ EXPECT_EQ(0, tabstrip.active_index());
+
+ // Previous MRU tab would be 3
+ EXPECT_EQ(3, tabstrip.GetIndexOfTabContents(controller.GetPreviousMRUTab()));
+
+ tabstrip.CloseAllTabs();
+ // TabStripModel should now be empty.
+ EXPECT_TRUE(tabstrip.empty());
+}

Powered by Google App Engine
This is Rietveld 408576698