This source file includes following definitions.
- tab_strip_
- WebContentsDestroyed
- set_run_unload_listener
- RunUnloadListenerBeforeClosing
- id
- ManageDialog
- ShowDialog
- HideDialog
- CloseDialog
- FocusDialog
- PulseDialog
- HostChanged
- TabInsertedAt
- SetWebContentsBlocked
- CreateWebContents
- CreateWebContentsWithSharedRPH
- SetID
- GetID
- GetTabStripStateString
- GetIndicesClosedByCommandAsString
- PrepareTabstripForSelectionTest
- model_
- GetStateCount
- GetStateAt
- StateEquals
- TabInsertedAt
- ActiveTabChanged
- TabSelectionChanged
- TabMoved
- TabClosingAt
- TabDetachedAt
- TabDeactivated
- TabChangedAt
- TabReplacedAt
- TabPinnedStateChanged
- TabStripEmpty
- TabStripModelDeleted
- ClearStates
- empty
- deleted
- model
- TEST_F
- TEST_F
- GetInsertionIndex
- InsertWebContentses
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include <map>
#include <string>
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.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/browser/ui/webui/ntp/new_tab_ui.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 "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "extensions/common/extension.h"
#include "testing/gtest/include/gtest/gtest.h"
using content::SiteInstance;
using content::WebContents;
using extensions::Extension;
using web_modal::NativeWebContentsModalDialog;
namespace {
class DeleteWebContentsOnDestroyedObserver
: public content::WebContentsObserver {
public:
DeleteWebContentsOnDestroyedObserver(WebContents* source,
WebContents* tab_to_delete,
TabStripModel* tab_strip)
: WebContentsObserver(source),
tab_to_delete_(tab_to_delete),
tab_strip_(tab_strip) {
}
virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
WebContents* tab_to_delete = tab_to_delete_;
tab_to_delete_ = NULL;
TabStripModel* tab_strip_to_delete = tab_strip_;
tab_strip_ = NULL;
delete tab_to_delete;
delete tab_strip_to_delete;
}
private:
WebContents* tab_to_delete_;
TabStripModel* tab_strip_;
DISALLOW_COPY_AND_ASSIGN(DeleteWebContentsOnDestroyedObserver);
};
class TabStripDummyDelegate : public TestTabStripModelDelegate {
public:
TabStripDummyDelegate() : run_unload_(false) {}
virtual ~TabStripDummyDelegate() {}
void set_run_unload_listener(bool value) { run_unload_ = value; }
virtual bool RunUnloadListenerBeforeClosing(WebContents* contents) OVERRIDE {
return run_unload_;
}
private:
bool run_unload_;
DISALLOW_COPY_AND_ASSIGN(TabStripDummyDelegate);
};
const char kTabStripModelTestIDUserDataKey[] = "TabStripModelTestIDUserData";
class TabStripModelTestIDUserData : public base::SupportsUserData::Data {
public:
explicit TabStripModelTestIDUserData(int id) : id_(id) {}
virtual ~TabStripModelTestIDUserData() {}
int id() { return id_; }
private:
int id_;
};
class DummyNativeWebContentsModalDialogManager
: public web_modal::NativeWebContentsModalDialogManager {
public:
explicit DummyNativeWebContentsModalDialogManager(
web_modal::NativeWebContentsModalDialogManagerDelegate* delegate)
: delegate_(delegate) {}
virtual ~DummyNativeWebContentsModalDialogManager() {}
virtual void ManageDialog(NativeWebContentsModalDialog dialog) OVERRIDE {}
virtual void ShowDialog(NativeWebContentsModalDialog dialog) OVERRIDE {}
virtual void HideDialog(NativeWebContentsModalDialog dialog) OVERRIDE {}
virtual void CloseDialog(NativeWebContentsModalDialog dialog) OVERRIDE {
delegate_->WillClose(dialog);
}
virtual void FocusDialog(NativeWebContentsModalDialog dialog) OVERRIDE {}
virtual void PulseDialog(NativeWebContentsModalDialog dialog) OVERRIDE {}
virtual void HostChanged(
web_modal::WebContentsModalDialogHost* new_host) OVERRIDE {}
private:
web_modal::NativeWebContentsModalDialogManagerDelegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(DummyNativeWebContentsModalDialogManager);
};
class TabBlockedStateTestBrowser
: public TabStripModelObserver,
public web_modal::WebContentsModalDialogManagerDelegate {
public:
explicit TabBlockedStateTestBrowser(TabStripModel* tab_strip_model)
: tab_strip_model_(tab_strip_model) {
tab_strip_model_->AddObserver(this);
}
virtual ~TabBlockedStateTestBrowser() {
tab_strip_model_->RemoveObserver(this);
}
private:
virtual void TabInsertedAt(WebContents* contents,
int index,
bool foreground) OVERRIDE {
web_modal::WebContentsModalDialogManager* manager =
web_modal::WebContentsModalDialogManager::FromWebContents(contents);
if (manager)
manager->SetDelegate(this);
}
virtual void SetWebContentsBlocked(content::WebContents* contents,
bool blocked) OVERRIDE {
int index = tab_strip_model_->GetIndexOfWebContents(contents);
ASSERT_GE(index, 0);
tab_strip_model_->SetTabBlocked(index, blocked);
}
TabStripModel* tab_strip_model_;
DISALLOW_COPY_AND_ASSIGN(TabBlockedStateTestBrowser);
};
}
class TabStripModelTest : public ChromeRenderViewHostTestHarness {
public:
WebContents* CreateWebContents() {
return WebContents::Create(WebContents::CreateParams(profile()));
}
WebContents* CreateWebContentsWithSharedRPH(WebContents* web_contents) {
WebContents::CreateParams create_params(
profile(), web_contents->GetRenderViewHost()->GetSiteInstance());
WebContents* retval = WebContents::Create(create_params);
EXPECT_EQ(retval->GetRenderProcessHost(),
web_contents->GetRenderProcessHost());
return retval;
}
void SetID(WebContents* contents, int id) {
contents->SetUserData(&kTabStripModelTestIDUserDataKey,
new TabStripModelTestIDUserData(id));
}
int GetID(WebContents* contents) {
TabStripModelTestIDUserData* user_data =
static_cast<TabStripModelTestIDUserData*>(
contents->GetUserData(&kTabStripModelTestIDUserDataKey));
return user_data ? user_data->id() : -1;
}
std::string GetTabStripStateString(const TabStripModel& model) {
std::string actual;
for (int i = 0; i < model.count(); ++i) {
if (i > 0)
actual += " ";
actual += base::IntToString(GetID(model.GetWebContentsAt(i)));
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) {
WebContents* contents = CreateWebContents();
SetID(contents, i);
model->AppendWebContents(contents, true);
}
for (int i = 0; i < pinned_count; ++i)
model->SetTabPinned(i, true);
ui::ListSelectionModel 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);
}
};
class MockTabStripModelObserver : public TabStripModelObserver {
public:
explicit MockTabStripModelObserver(TabStripModel* model)
: empty_(true),
deleted_(false),
model_(model) {}
virtual ~MockTabStripModelObserver() {}
enum TabStripModelObserverAction {
INSERT,
CLOSE,
DETACH,
ACTIVATE,
DEACTIVATE,
SELECT,
MOVE,
CHANGE,
PINNED,
REPLACED
};
struct State {
State(WebContents* a_dst_contents,
int a_dst_index,
TabStripModelObserverAction a_action)
: src_contents(NULL),
dst_contents(a_dst_contents),
src_index(-1),
dst_index(a_dst_index),
change_reason(CHANGE_REASON_NONE),
foreground(false),
action(a_action) {
}
WebContents* src_contents;
WebContents* dst_contents;
int src_index;
int dst_index;
int change_reason;
bool foreground;
TabStripModelObserverAction action;
};
int GetStateCount() const {
return static_cast<int>(states_.size());
}
State GetStateAt(int index) const {
DCHECK(index >= 0 && index < GetStateCount());
return states_[index];
}
bool StateEquals(int index, const State& state) {
State s = GetStateAt(index);
return (s.src_contents == state.src_contents &&
s.dst_contents == state.dst_contents &&
s.src_index == state.src_index &&
s.dst_index == state.dst_index &&
s.change_reason == state.change_reason &&
s.foreground == state.foreground &&
s.action == state.action);
}
virtual void TabInsertedAt(WebContents* contents,
int index,
bool foreground) OVERRIDE {
empty_ = false;
State s(contents, index, INSERT);
s.foreground = foreground;
states_.push_back(s);
}
virtual void ActiveTabChanged(WebContents* old_contents,
WebContents* new_contents,
int index,
int reason) OVERRIDE {
State s(new_contents, index, ACTIVATE);
s.src_contents = old_contents;
s.change_reason = reason;
states_.push_back(s);
}
virtual void TabSelectionChanged(
TabStripModel* tab_strip_model,
const ui::ListSelectionModel& old_model) OVERRIDE {
State s(model()->GetActiveWebContents(), model()->active_index(), SELECT);
s.src_contents = model()->GetWebContentsAt(old_model.active());
s.src_index = old_model.active();
states_.push_back(s);
}
virtual void TabMoved(WebContents* contents,
int from_index,
int to_index) OVERRIDE {
State s(contents, to_index, MOVE);
s.src_index = from_index;
states_.push_back(s);
}
virtual void TabClosingAt(TabStripModel* tab_strip_model,
WebContents* contents,
int index) OVERRIDE {
states_.push_back(State(contents, index, CLOSE));
}
virtual void TabDetachedAt(WebContents* contents, int index) OVERRIDE {
states_.push_back(State(contents, index, DETACH));
}
virtual void TabDeactivated(WebContents* contents) OVERRIDE {
states_.push_back(State(contents, model()->active_index(), DEACTIVATE));
}
virtual void TabChangedAt(WebContents* contents,
int index,
TabChangeType change_type) OVERRIDE {
states_.push_back(State(contents, index, CHANGE));
}
virtual void TabReplacedAt(TabStripModel* tab_strip_model,
WebContents* old_contents,
WebContents* new_contents,
int index) OVERRIDE {
State s(new_contents, index, REPLACED);
s.src_contents = old_contents;
states_.push_back(s);
}
virtual void TabPinnedStateChanged(WebContents* contents,
int index) OVERRIDE {
states_.push_back(State(contents, index, PINNED));
}
virtual void TabStripEmpty() OVERRIDE {
empty_ = true;
}
virtual void TabStripModelDeleted() OVERRIDE {
deleted_ = true;
}
void ClearStates() {
states_.clear();
}
bool empty() const { return empty_; }
bool deleted() const { return deleted_; }
TabStripModel* model() { return model_; }
private:
std::vector<State> states_;
bool empty_;
bool deleted_;
TabStripModel* model_;
DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver);
};
TEST_F(TabStripModelTest, TestBasicAPI) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
MockTabStripModelObserver observer(&tabstrip);
tabstrip.AddObserver(&observer);
EXPECT_TRUE(tabstrip.empty());
typedef MockTabStripModelObserver::State State;
WebContents* contents1 = CreateWebContents();
SetID(contents1, 1);
{
EXPECT_FALSE(tabstrip.ContainsIndex(0));
tabstrip.AppendWebContents(contents1, true);
EXPECT_TRUE(tabstrip.ContainsIndex(0));
EXPECT_EQ(1, tabstrip.count());
EXPECT_EQ(3, observer.GetStateCount());
State s1(contents1, 0, MockTabStripModelObserver::INSERT);
s1.foreground = true;
EXPECT_TRUE(observer.StateEquals(0, s1));
State s2(contents1, 0, MockTabStripModelObserver::ACTIVATE);
EXPECT_TRUE(observer.StateEquals(1, s2));
State s3(contents1, 0, MockTabStripModelObserver::SELECT);
s3.src_contents = NULL;
s3.src_index = ui::ListSelectionModel::kUnselectedIndex;
EXPECT_TRUE(observer.StateEquals(2, s3));
observer.ClearStates();
}
EXPECT_EQ("1", GetTabStripStateString(tabstrip));
WebContents* contents2 = CreateWebContents();
SetID(contents2, 2);
{
tabstrip.InsertWebContentsAt(1, contents2, TabStripModel::ADD_ACTIVE);
EXPECT_EQ(2, tabstrip.count());
EXPECT_EQ(4, observer.GetStateCount());
State s1(contents2, 1, MockTabStripModelObserver::INSERT);
s1.foreground = true;
EXPECT_TRUE(observer.StateEquals(0, s1));
State s2(contents1, 0, MockTabStripModelObserver::DEACTIVATE);
EXPECT_TRUE(observer.StateEquals(1, s2));
State s3(contents2, 1, MockTabStripModelObserver::ACTIVATE);
s3.src_contents = contents1;
EXPECT_TRUE(observer.StateEquals(2, s3));
State s4(contents2, 1, MockTabStripModelObserver::SELECT);
s4.src_contents = contents1;
s4.src_index = 0;
EXPECT_TRUE(observer.StateEquals(3, s4));
observer.ClearStates();
}
EXPECT_EQ("1 2", GetTabStripStateString(tabstrip));
WebContents* contents3 = CreateWebContents();
SetID(contents3, 3);
{
tabstrip.InsertWebContentsAt(2, contents3, TabStripModel::ADD_NONE);
EXPECT_EQ(3, tabstrip.count());
EXPECT_EQ(1, observer.GetStateCount());
State s1(contents3, 2, MockTabStripModelObserver::INSERT);
s1.foreground = false;
EXPECT_TRUE(observer.StateEquals(0, s1));
observer.ClearStates();
}
EXPECT_EQ("1 2 3", GetTabStripStateString(tabstrip));
{
tabstrip.ActivateTabAt(2, true);
EXPECT_EQ(3, observer.GetStateCount());
State s1(contents2, 1, MockTabStripModelObserver::DEACTIVATE);
EXPECT_TRUE(observer.StateEquals(0, s1));
State s2(contents3, 2, MockTabStripModelObserver::ACTIVATE);
s2.src_contents = contents2;
s2.change_reason = TabStripModelObserver::CHANGE_REASON_USER_GESTURE;
EXPECT_TRUE(observer.StateEquals(1, s2));
State s3(contents3, 2, MockTabStripModelObserver::SELECT);
s3.src_contents = contents2;
s3.src_index = 1;
EXPECT_TRUE(observer.StateEquals(2, s3));
observer.ClearStates();
}
EXPECT_EQ("1 2 3", GetTabStripStateString(tabstrip));
{
WebContents* detached = tabstrip.DetachWebContentsAt(2);
tabstrip.AppendWebContents(detached, true);
EXPECT_EQ(8, observer.GetStateCount());
State s1(detached, 2, MockTabStripModelObserver::DETACH);
EXPECT_TRUE(observer.StateEquals(0, s1));
State s2(detached, ui::ListSelectionModel::kUnselectedIndex,
MockTabStripModelObserver::DEACTIVATE);
EXPECT_TRUE(observer.StateEquals(1, s2));
State s3(contents2, 1, MockTabStripModelObserver::ACTIVATE);
s3.src_contents = contents3;
s3.change_reason = TabStripModelObserver::CHANGE_REASON_NONE;
EXPECT_TRUE(observer.StateEquals(2, s3));
State s4(contents2, 1, MockTabStripModelObserver::SELECT);
s4.src_contents = NULL;
s4.src_index = ui::ListSelectionModel::kUnselectedIndex;
EXPECT_TRUE(observer.StateEquals(3, s4));
State s5(detached, 2, MockTabStripModelObserver::INSERT);
s5.foreground = true;
EXPECT_TRUE(observer.StateEquals(4, s5));
State s6(contents2, 1, MockTabStripModelObserver::DEACTIVATE);
EXPECT_TRUE(observer.StateEquals(5, s6));
State s7(detached, 2, MockTabStripModelObserver::ACTIVATE);
s7.src_contents = contents2;
s7.change_reason = TabStripModelObserver::CHANGE_REASON_NONE;
EXPECT_TRUE(observer.StateEquals(6, s7));
State s8(detached, 2, MockTabStripModelObserver::SELECT);
s8.src_contents = contents2;
s8.src_index = 1;
EXPECT_TRUE(observer.StateEquals(7, s8));
observer.ClearStates();
}
EXPECT_EQ("1 2 3", GetTabStripStateString(tabstrip));
{
EXPECT_TRUE(tabstrip.CloseWebContentsAt(2, TabStripModel::CLOSE_NONE));
EXPECT_EQ(2, tabstrip.count());
EXPECT_EQ(5, observer.GetStateCount());
State s1(contents3, 2, MockTabStripModelObserver::CLOSE);
EXPECT_TRUE(observer.StateEquals(0, s1));
State s2(contents3, 2, MockTabStripModelObserver::DETACH);
EXPECT_TRUE(observer.StateEquals(1, s2));
State s3(contents3, ui::ListSelectionModel::kUnselectedIndex,
MockTabStripModelObserver::DEACTIVATE);
EXPECT_TRUE(observer.StateEquals(2, s3));
State s4(contents2, 1, MockTabStripModelObserver::ACTIVATE);
s4.src_contents = contents3;
s4.change_reason = TabStripModelObserver::CHANGE_REASON_NONE;
EXPECT_TRUE(observer.StateEquals(3, s4));
State s5(contents2, 1, MockTabStripModelObserver::SELECT);
s5.src_contents = NULL;
s5.src_index = ui::ListSelectionModel::kUnselectedIndex;
EXPECT_TRUE(observer.StateEquals(4, s5));
observer.ClearStates();
}
EXPECT_EQ("1 2", GetTabStripStateString(tabstrip));
{
tabstrip.MoveWebContentsAt(1, 0, true);
EXPECT_EQ(1, observer.GetStateCount());
State s1(contents2, 0, MockTabStripModelObserver::MOVE);
s1.src_index = 1;
EXPECT_TRUE(observer.StateEquals(0, s1));
EXPECT_EQ(0, tabstrip.active_index());
observer.ClearStates();
}
EXPECT_EQ("2 1", GetTabStripStateString(tabstrip));
{
tabstrip.MoveWebContentsAt(1, 0, false);
EXPECT_EQ(1, observer.GetStateCount());
State s1(contents1, 0, MockTabStripModelObserver::MOVE);
s1.src_index = 1;
EXPECT_TRUE(observer.StateEquals(0, s1));
EXPECT_EQ(1, tabstrip.active_index());
tabstrip.MoveWebContentsAt(0, 1, false);
observer.ClearStates();
}
EXPECT_EQ("2 1", GetTabStripStateString(tabstrip));
{
EXPECT_EQ(contents2, tabstrip.GetActiveWebContents());
EXPECT_EQ(contents2, tabstrip.GetWebContentsAt(0));
EXPECT_EQ(contents1, tabstrip.GetWebContentsAt(1));
EXPECT_EQ(0, tabstrip.GetIndexOfWebContents(contents2));
EXPECT_EQ(1, tabstrip.GetIndexOfWebContents(contents1));
}
{
tabstrip.UpdateWebContentsStateAt(0, TabStripModelObserver::ALL);
EXPECT_EQ(1, observer.GetStateCount());
State s1(contents2, 0, MockTabStripModelObserver::CHANGE);
EXPECT_TRUE(observer.StateEquals(0, s1));
observer.ClearStates();
}
{
tabstrip.ActivateTabAt(1, true);
tabstrip.SelectPreviousTab();
EXPECT_EQ(0, tabstrip.active_index());
tabstrip.SelectLastTab();
EXPECT_EQ(1, tabstrip.active_index());
tabstrip.SelectNextTab();
EXPECT_EQ(0, tabstrip.active_index());
}
{
tabstrip.CloseSelectedTabs();
EXPECT_EQ(1, tabstrip.count());
EXPECT_EQ(0, tabstrip.active_index());
}
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
tabstrip.RemoveObserver(&observer);
}
TEST_F(TabStripModelTest, TestBasicOpenerAPI) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* opener = CreateWebContents();
tabstrip.AppendWebContents(opener, true);
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
WebContents* contents4 = CreateWebContents();
WebContents* contents5 = CreateWebContents();
tabstrip.InsertWebContentsAt(tabstrip.count(), contents1,
TabStripModel::ADD_INHERIT_GROUP);
tabstrip.InsertWebContentsAt(tabstrip.count(), contents2,
TabStripModel::ADD_INHERIT_GROUP);
tabstrip.InsertWebContentsAt(tabstrip.count(), contents3,
TabStripModel::ADD_INHERIT_GROUP);
tabstrip.InsertWebContentsAt(tabstrip.count(), contents4,
TabStripModel::ADD_INHERIT_GROUP);
tabstrip.InsertWebContentsAt(tabstrip.count(), contents5,
TabStripModel::ADD_INHERIT_GROUP);
for (int i = 1; i < tabstrip.count(); ++i)
EXPECT_EQ(opener, tabstrip.GetOpenerOfWebContentsAt(i));
EXPECT_EQ(2, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 1, false));
EXPECT_EQ(4, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 5, false));
EXPECT_EQ(5, tabstrip.GetIndexOfLastWebContentsOpenedBy(opener, 1));
EXPECT_EQ(-1,
tabstrip.GetIndexOfNextWebContentsOpenedBy(contents1, 3, false));
EXPECT_EQ(-1,
tabstrip.GetIndexOfLastWebContentsOpenedBy(contents1, 3));
tabstrip.ForgetAllOpeners();
EXPECT_EQ(-1, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 1, false));
EXPECT_EQ(-1, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 5, false));
EXPECT_EQ(-1, tabstrip.GetIndexOfLastWebContentsOpenedBy(opener, 1));
for (int i = 0; i < tabstrip.count() - 1; ++i)
tabstrip.SetOpenerOfWebContentsAt(i, contents5);
for (int i = 0; i < tabstrip.count() - 1; ++i)
EXPECT_EQ(contents5, tabstrip.GetOpenerOfWebContentsAt(i));
EXPECT_EQ(2, tabstrip.GetIndexOfNextWebContentsOpenedBy(contents5, 1, false));
EXPECT_EQ(3, tabstrip.GetIndexOfNextWebContentsOpenedBy(contents5, 4, false));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
static int GetInsertionIndex(TabStripModel* tabstrip) {
return tabstrip->order_controller()->DetermineInsertionIndex(
content::PAGE_TRANSITION_LINK, false);
}
static void InsertWebContentses(TabStripModel* tabstrip,
WebContents* contents1,
WebContents* contents2,
WebContents* contents3) {
tabstrip->InsertWebContentsAt(GetInsertionIndex(tabstrip),
contents1,
TabStripModel::ADD_INHERIT_GROUP);
tabstrip->InsertWebContentsAt(GetInsertionIndex(tabstrip),
contents2,
TabStripModel::ADD_INHERIT_GROUP);
tabstrip->InsertWebContentsAt(GetInsertionIndex(tabstrip),
contents3,
TabStripModel::ADD_INHERIT_GROUP);
}
TEST_F(TabStripModelTest, TestLTRInsertionOptions) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* opener = CreateWebContents();
tabstrip.AppendWebContents(opener, true);
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
InsertWebContentses(&tabstrip, contents1, contents2, contents3);
EXPECT_EQ(contents1, tabstrip.GetWebContentsAt(1));
EXPECT_EQ(contents2, tabstrip.GetWebContentsAt(2));
EXPECT_EQ(contents3, tabstrip.GetWebContentsAt(3));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, TestInsertionIndexDetermination) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* opener = CreateWebContents();
tabstrip.AppendWebContents(opener, true);
WebContents* other = CreateWebContents();
tabstrip.AppendWebContents(other, false);
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
InsertWebContentses(&tabstrip, contents1, contents2, contents3);
EXPECT_EQ(opener, tabstrip.GetWebContentsAt(0));
EXPECT_EQ(contents1, tabstrip.GetWebContentsAt(1));
EXPECT_EQ(contents2, tabstrip.GetWebContentsAt(2));
EXPECT_EQ(contents3, tabstrip.GetWebContentsAt(3));
EXPECT_EQ(other, tabstrip.GetWebContentsAt(4));
EXPECT_EQ(3, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 2, false));
EXPECT_EQ(2, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 3, false));
EXPECT_EQ(3, tabstrip.GetIndexOfLastWebContentsOpenedBy(opener, 1));
WebContents* fg_link_contents = CreateWebContents();
int insert_index = tabstrip.order_controller()->DetermineInsertionIndex(
content::PAGE_TRANSITION_LINK, true);
EXPECT_EQ(1, insert_index);
tabstrip.InsertWebContentsAt(insert_index, fg_link_contents,
TabStripModel::ADD_ACTIVE |
TabStripModel::ADD_INHERIT_GROUP);
EXPECT_EQ(1, tabstrip.active_index());
EXPECT_EQ(fg_link_contents, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(0, tabstrip.active_index());
WebContents* fg_nonlink_contents = CreateWebContents();
insert_index = tabstrip.order_controller()->DetermineInsertionIndex(
content::PAGE_TRANSITION_AUTO_BOOKMARK, true);
EXPECT_EQ(tabstrip.count(), insert_index);
tabstrip.InsertWebContentsAt(insert_index,
fg_nonlink_contents,
TabStripModel::ADD_NONE);
tabstrip.ActivateTabAt(tabstrip.count() - 1, true);
EXPECT_EQ(tabstrip.count() - 1, tabstrip.active_index());
EXPECT_EQ(fg_nonlink_contents, tabstrip.GetActiveWebContents());
EXPECT_EQ(-1, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 2, false));
EXPECT_EQ(-1, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 3, false));
EXPECT_EQ(-1, tabstrip.GetIndexOfNextWebContentsOpenedBy(opener, 3, false));
EXPECT_EQ(-1, tabstrip.GetIndexOfLastWebContentsOpenedBy(opener, 1));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, TestSelectOnClose) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* opener = CreateWebContents();
tabstrip.AppendWebContents(opener, true);
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
InsertWebContentses(&tabstrip, contents1, contents2, contents3);
EXPECT_EQ(0, tabstrip.active_index());
tabstrip.DetachWebContentsAt(1);
EXPECT_EQ(0, tabstrip.active_index());
for (int i = tabstrip.count() - 1; i >= 1; --i)
tabstrip.DetachWebContentsAt(i);
InsertWebContentses(&tabstrip, contents1, contents2, contents3);
EXPECT_EQ(0, tabstrip.active_index());
tabstrip.ForgetAllOpeners();
tabstrip.ActivateTabAt(1, true);
EXPECT_EQ(1, tabstrip.active_index());
tabstrip.DetachWebContentsAt(1);
EXPECT_EQ(1, tabstrip.active_index());
tabstrip.DetachWebContentsAt(1);
EXPECT_EQ(1, tabstrip.active_index());
tabstrip.DetachWebContentsAt(1);
EXPECT_EQ(0, tabstrip.active_index());
for (int i = tabstrip.count() - 1; i >= 1; --i)
tabstrip.DetachWebContentsAt(i);
InsertWebContentses(&tabstrip, contents1, contents2, contents3);
EXPECT_EQ(0, tabstrip.active_index());
tabstrip.ActivateTabAt(2, false);
EXPECT_EQ(2, tabstrip.active_index());
tabstrip.CloseWebContentsAt(2, TabStripModel::CLOSE_NONE);
EXPECT_EQ(2, tabstrip.active_index());
tabstrip.CloseWebContentsAt(2, TabStripModel::CLOSE_NONE);
EXPECT_EQ(1, tabstrip.active_index());
tabstrip.CloseWebContentsAt(1, TabStripModel::CLOSE_NONE);
EXPECT_EQ(0, tabstrip.active_index());
WebContents* other_contents = CreateWebContents();
tabstrip.InsertWebContentsAt(1, other_contents,
TabStripModel::ADD_NONE);
EXPECT_EQ(2, tabstrip.count());
WebContents* opened_contents = CreateWebContents();
tabstrip.InsertWebContentsAt(2, opened_contents,
TabStripModel::ADD_ACTIVE |
TabStripModel::ADD_INHERIT_GROUP);
EXPECT_EQ(2, tabstrip.active_index());
tabstrip.CloseWebContentsAt(2, TabStripModel::CLOSE_NONE);
EXPECT_EQ(0, tabstrip.active_index());
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, CommandCloseTab) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 1, 0, "0"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
0, TabStripModel::CommandCloseTab));
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTab);
ASSERT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
0, TabStripModel::CommandCloseTab));
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTab);
EXPECT_EQ("2", GetTabStripStateString(tabstrip));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
2, TabStripModel::CommandCloseTab));
tabstrip.ExecuteContextMenuCommand(2, TabStripModel::CommandCloseTab);
EXPECT_EQ("0 1", GetTabStripStateString(tabstrip));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 1, "0 1"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
0, TabStripModel::CommandCloseTab));
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTab);
EXPECT_EQ("2", GetTabStripStateString(tabstrip));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, CommandCloseOtherTabs) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
0, TabStripModel::CommandCloseOtherTabs));
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseOtherTabs);
EXPECT_EQ("0 1", GetTabStripStateString(tabstrip));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
2, TabStripModel::CommandCloseOtherTabs));
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseOtherTabs);
EXPECT_EQ("0 1", GetTabStripStateString(tabstrip));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "0 1 2"));
EXPECT_FALSE(tabstrip.IsContextMenuCommandEnabled(
2, TabStripModel::CommandCloseOtherTabs));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 1, "1 2"));
EXPECT_FALSE(tabstrip.IsContextMenuCommandEnabled(
1, TabStripModel::CommandCloseOtherTabs));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
0, TabStripModel::CommandCloseOtherTabs));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 1, "1"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1, TabStripModel::CommandCloseOtherTabs));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
0, TabStripModel::CommandCloseOtherTabs));
tabstrip.ExecuteContextMenuCommand(1, TabStripModel::CommandCloseOtherTabs);
EXPECT_EQ("0p 1", GetTabStripStateString(tabstrip));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, CommandCloseTabsToRight) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 0, "1 2"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
0, TabStripModel::CommandCloseTabsToRight));
EXPECT_FALSE(tabstrip.IsContextMenuCommandEnabled(
1, TabStripModel::CommandCloseTabsToRight));
EXPECT_FALSE(tabstrip.IsContextMenuCommandEnabled(
2, TabStripModel::CommandCloseTabsToRight));
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTabsToRight);
EXPECT_EQ("0", GetTabStripStateString(tabstrip));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, CommandTogglePinned) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&tabstrip, 3, 1, "0 1"));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
0, TabStripModel::CommandTogglePinned));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
1, TabStripModel::CommandTogglePinned));
EXPECT_TRUE(tabstrip.IsContextMenuCommandEnabled(
2, TabStripModel::CommandTogglePinned));
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandTogglePinned);
EXPECT_EQ("0p 1p 2", GetTabStripStateString(tabstrip));
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandTogglePinned);
EXPECT_EQ("0 1 2", GetTabStripStateString(tabstrip));
tabstrip.ExecuteContextMenuCommand(2, TabStripModel::CommandTogglePinned);
EXPECT_EQ("2p 0 1", GetTabStripStateString(tabstrip));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, TestContextMenuCloseCommands) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* opener = CreateWebContents();
tabstrip.AppendWebContents(opener, true);
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
InsertWebContentses(&tabstrip, contents1, contents2, contents3);
EXPECT_EQ(0, tabstrip.active_index());
tabstrip.ExecuteContextMenuCommand(2, TabStripModel::CommandCloseTab);
EXPECT_EQ(3, tabstrip.count());
tabstrip.ExecuteContextMenuCommand(0, TabStripModel::CommandCloseTabsToRight);
EXPECT_EQ(1, tabstrip.count());
EXPECT_EQ(opener, tabstrip.GetActiveWebContents());
WebContents* dummy = CreateWebContents();
tabstrip.AppendWebContents(dummy, false);
contents1 = CreateWebContents();
contents2 = CreateWebContents();
contents3 = CreateWebContents();
InsertWebContentses(&tabstrip, contents1, contents2, contents3);
EXPECT_EQ(5, tabstrip.count());
int dummy_index = tabstrip.count() - 1;
tabstrip.ActivateTabAt(dummy_index, true);
EXPECT_EQ(dummy, tabstrip.GetActiveWebContents());
tabstrip.ExecuteContextMenuCommand(dummy_index,
TabStripModel::CommandCloseOtherTabs);
EXPECT_EQ(1, tabstrip.count());
EXPECT_EQ(dummy, tabstrip.GetActiveWebContents());
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, GetIndicesClosedByCommand) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
WebContents* contents4 = CreateWebContents();
WebContents* contents5 = CreateWebContents();
tabstrip.AppendWebContents(contents1, true);
tabstrip.AppendWebContents(contents2, true);
tabstrip.AppendWebContents(contents3, true);
tabstrip.AppendWebContents(contents4, true);
tabstrip.AppendWebContents(contents5, true);
EXPECT_EQ("4 3 2 1", GetIndicesClosedByCommandAsString(
tabstrip, 0, TabStripModel::CommandCloseTabsToRight));
EXPECT_EQ("4 3 2", GetIndicesClosedByCommandAsString(
tabstrip, 1, TabStripModel::CommandCloseTabsToRight));
EXPECT_EQ("4 3 2 1", GetIndicesClosedByCommandAsString(
tabstrip, 0, TabStripModel::CommandCloseOtherTabs));
EXPECT_EQ("4 3 2 0", GetIndicesClosedByCommandAsString(
tabstrip, 1, TabStripModel::CommandCloseOtherTabs));
tabstrip.SetTabPinned(0, true);
tabstrip.SetTabPinned(1, true);
EXPECT_EQ("4 3 2", GetIndicesClosedByCommandAsString(
tabstrip, 0, TabStripModel::CommandCloseTabsToRight));
EXPECT_EQ("4 3", GetIndicesClosedByCommandAsString(
tabstrip, 2, TabStripModel::CommandCloseTabsToRight));
EXPECT_EQ("4 3 2", GetIndicesClosedByCommandAsString(
tabstrip, 0, TabStripModel::CommandCloseOtherTabs));
EXPECT_EQ("4 3", GetIndicesClosedByCommandAsString(
tabstrip, 2, TabStripModel::CommandCloseOtherTabs));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, AddWebContents_MiddleClickLinksAndClose) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* homepage_contents = CreateWebContents();
tabstrip.AddWebContents(
homepage_contents, -1, content::PAGE_TRANSITION_AUTO_BOOKMARK,
TabStripModel::ADD_ACTIVE);
WebContents* typed_page_contents = CreateWebContents();
tabstrip.AddWebContents(
typed_page_contents, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(2, tabstrip.count());
tabstrip.ActivateTabAt(0, true);
WebContents* middle_click_contents1 = CreateWebContents();
tabstrip.AddWebContents(
middle_click_contents1, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
WebContents* middle_click_contents2 = CreateWebContents();
tabstrip.AddWebContents(
middle_click_contents2, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
WebContents* middle_click_contents3 = CreateWebContents();
tabstrip.AddWebContents(
middle_click_contents3, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
EXPECT_EQ(5, tabstrip.count());
EXPECT_EQ(homepage_contents, tabstrip.GetWebContentsAt(0));
EXPECT_EQ(middle_click_contents1, tabstrip.GetWebContentsAt(1));
EXPECT_EQ(middle_click_contents2, tabstrip.GetWebContentsAt(2));
EXPECT_EQ(middle_click_contents3, tabstrip.GetWebContentsAt(3));
EXPECT_EQ(typed_page_contents, tabstrip.GetWebContentsAt(4));
tabstrip.ActivateTabAt(2, true);
tabstrip.CloseSelectedTabs();
EXPECT_EQ(middle_click_contents3, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(middle_click_contents1, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(homepage_contents, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(typed_page_contents, tabstrip.GetActiveWebContents());
EXPECT_EQ(1, tabstrip.count());
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, AddWebContents_LeftClickPopup) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* homepage_contents = CreateWebContents();
tabstrip.AddWebContents(
homepage_contents, -1, content::PAGE_TRANSITION_AUTO_BOOKMARK,
TabStripModel::ADD_ACTIVE);
WebContents* typed_page_contents = CreateWebContents();
tabstrip.AddWebContents(
typed_page_contents, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(2, tabstrip.count());
tabstrip.ActivateTabAt(0, true);
WebContents* left_click_contents = CreateWebContents();
tabstrip.AddWebContents(left_click_contents, -1,
content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(3, tabstrip.count());
EXPECT_EQ(homepage_contents, tabstrip.GetWebContentsAt(0));
EXPECT_EQ(left_click_contents, tabstrip.GetWebContentsAt(1));
EXPECT_EQ(typed_page_contents, tabstrip.GetWebContentsAt(2));
EXPECT_EQ(left_click_contents, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(homepage_contents, tabstrip.GetActiveWebContents());
EXPECT_EQ(2, tabstrip.count());
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, AddWebContents_CreateNewBlankTab) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* homepage_contents = CreateWebContents();
tabstrip.AddWebContents(
homepage_contents, -1, content::PAGE_TRANSITION_AUTO_BOOKMARK,
TabStripModel::ADD_ACTIVE);
WebContents* typed_page_contents = CreateWebContents();
tabstrip.AddWebContents(
typed_page_contents, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(2, tabstrip.count());
tabstrip.ActivateTabAt(0, true);
WebContents* new_blank_contents = CreateWebContents();
tabstrip.AddWebContents(new_blank_contents, -1,
content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(3, tabstrip.count());
EXPECT_EQ(homepage_contents, tabstrip.GetWebContentsAt(0));
EXPECT_EQ(typed_page_contents, tabstrip.GetWebContentsAt(1));
EXPECT_EQ(new_blank_contents, tabstrip.GetWebContentsAt(2));
WebContents* background_blank_contents1 = CreateWebContents();
tabstrip.AddWebContents(
background_blank_contents1, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_NONE);
WebContents* background_blank_contents2 = CreateWebContents();
tabstrip.AddWebContents(
background_blank_contents2, -1, content::PAGE_TRANSITION_GENERATED,
TabStripModel::ADD_NONE);
EXPECT_EQ(5, tabstrip.count());
EXPECT_EQ(homepage_contents, tabstrip.GetWebContentsAt(0));
EXPECT_EQ(typed_page_contents, tabstrip.GetWebContentsAt(1));
EXPECT_EQ(new_blank_contents, tabstrip.GetWebContentsAt(2));
EXPECT_EQ(background_blank_contents1, tabstrip.GetWebContentsAt(3));
EXPECT_EQ(background_blank_contents2, tabstrip.GetWebContentsAt(4));
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, AddWebContents_ForgetOpeners) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* homepage_contents = CreateWebContents();
tabstrip.AddWebContents(
homepage_contents, -1, content::PAGE_TRANSITION_AUTO_BOOKMARK,
TabStripModel::ADD_ACTIVE);
WebContents* typed_page_contents = CreateWebContents();
tabstrip.AddWebContents(
typed_page_contents, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(2, tabstrip.count());
tabstrip.ActivateTabAt(0, true);
WebContents* middle_click_contents1 = CreateWebContents();
tabstrip.AddWebContents(
middle_click_contents1, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
WebContents* middle_click_contents2 = CreateWebContents();
tabstrip.AddWebContents(
middle_click_contents2, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
WebContents* middle_click_contents3 = CreateWebContents();
tabstrip.AddWebContents(
middle_click_contents3, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
EXPECT_EQ(typed_page_contents, tabstrip.GetWebContentsAt(4));
tabstrip.SelectLastTab();
EXPECT_EQ(typed_page_contents, tabstrip.GetActiveWebContents());
tabstrip.ActivateTabAt(2, true);
EXPECT_EQ(middle_click_contents2, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(middle_click_contents3, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(typed_page_contents, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(middle_click_contents1, tabstrip.GetActiveWebContents());
tabstrip.CloseSelectedTabs();
EXPECT_EQ(homepage_contents, tabstrip.GetActiveWebContents());
EXPECT_EQ(1, tabstrip.count());
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
TEST_F(TabStripModelTest, AppendContentsReselectionTest) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
EXPECT_TRUE(tabstrip.empty());
WebContents* homepage_contents = CreateWebContents();
tabstrip.AddWebContents(
homepage_contents, -1, content::PAGE_TRANSITION_AUTO_BOOKMARK,
TabStripModel::ADD_ACTIVE);
WebContents* typed_page_contents = CreateWebContents();
tabstrip.AddWebContents(
typed_page_contents, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_NONE);
EXPECT_EQ(0, tabstrip.active_index());
WebContents* target_blank = CreateWebContents();
tabstrip.AppendWebContents(target_blank, true);
EXPECT_EQ(2, tabstrip.active_index());
tabstrip.CloseWebContentsAt(2, TabStripModel::CLOSE_NONE);
EXPECT_EQ(0, tabstrip.active_index());
tabstrip.CloseAllTabs();
}
TEST_F(TabStripModelTest, ReselectionConsidersChildrenTest) {
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* page_a_contents = CreateWebContents();
strip.AddWebContents(
page_a_contents, -1, content::PAGE_TRANSITION_AUTO_BOOKMARK,
TabStripModel::ADD_ACTIVE);
WebContents* page_a_a_contents = CreateWebContents();
strip.AddWebContents(page_a_a_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
WebContents* page_a_b_contents = CreateWebContents();
strip.AddWebContents(page_a_b_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.ActivateTabAt(1, true);
EXPECT_EQ(page_a_a_contents, strip.GetActiveWebContents());
WebContents* page_a_a_a_contents = CreateWebContents();
strip.AddWebContents(page_a_a_a_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
EXPECT_EQ(page_a_a_a_contents, strip.GetWebContentsAt(2));
strip.CloseWebContentsAt(strip.active_index(), TabStripModel::CLOSE_NONE);
EXPECT_EQ(page_a_a_a_contents, strip.GetActiveWebContents());
strip.CloseWebContentsAt(strip.active_index(), TabStripModel::CLOSE_NONE);
EXPECT_EQ(page_a_b_contents, strip.GetActiveWebContents());
strip.CloseWebContentsAt(strip.active_index(), TabStripModel::CLOSE_NONE);
EXPECT_EQ(page_a_contents, strip.GetActiveWebContents());
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, AddWebContents_NewTabAtEndOfStripInheritsGroup) {
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* page_a_contents = CreateWebContents();
strip.AddWebContents(page_a_contents, -1,
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
TabStripModel::ADD_ACTIVE);
WebContents* page_b_contents = CreateWebContents();
WebContents* page_c_contents = CreateWebContents();
WebContents* page_d_contents = CreateWebContents();
strip.AddWebContents(page_b_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.AddWebContents(page_c_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.AddWebContents(page_d_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.ActivateTabAt(1, true);
WebContents* new_contents = CreateWebContents();
strip.AddWebContents(new_contents, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(4, strip.GetIndexOfWebContents(new_contents));
EXPECT_EQ(4, strip.active_index());
strip.CloseWebContentsAt(4, TabStripModel::CLOSE_NONE);
EXPECT_EQ(1, strip.active_index());
WebContents* page_e_contents = CreateWebContents();
strip.AddWebContents(page_e_contents, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(4, strip.GetIndexOfWebContents(page_e_contents));
EXPECT_EQ(4, strip.active_index());
strip.CloseWebContentsAt(4, TabStripModel::CLOSE_NONE);
EXPECT_EQ(1, strip.active_index());
WebContents* page_f_contents = CreateWebContents();
strip.AddWebContents(page_f_contents, -1,
content::PAGE_TRANSITION_AUTO_BOOKMARK,
TabStripModel::ADD_ACTIVE);
EXPECT_EQ(4, strip.GetIndexOfWebContents(page_f_contents));
EXPECT_EQ(4, strip.active_index());
strip.CloseWebContentsAt(4, TabStripModel::CLOSE_NONE);
EXPECT_EQ(3, strip.active_index());
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, NavigationForgetsOpeners) {
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* page_a_contents = CreateWebContents();
strip.AddWebContents(page_a_contents, -1,
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
TabStripModel::ADD_ACTIVE);
WebContents* page_b_contents = CreateWebContents();
WebContents* page_c_contents = CreateWebContents();
WebContents* page_d_contents = CreateWebContents();
strip.AddWebContents(page_b_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.AddWebContents(page_c_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.AddWebContents(page_d_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
WebContents* page_e_contents = CreateWebContents();
strip.AddWebContents(page_e_contents, -1,
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
TabStripModel::ADD_NONE);
strip.ActivateTabAt(3, true);
strip.TabNavigating(page_d_contents, content::PAGE_TRANSITION_LINK);
strip.CloseWebContentsAt(3, TabStripModel::CLOSE_NONE);
EXPECT_EQ(2, strip.active_index());
strip.TabNavigating(page_c_contents, content::PAGE_TRANSITION_AUTO_BOOKMARK);
strip.CloseWebContentsAt(2, TabStripModel::CLOSE_NONE);
EXPECT_EQ(page_e_contents, strip.GetWebContentsAt(strip.active_index()));
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, NavigationForgettingDoesntAffectNewTab) {
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* page_a_contents = CreateWebContents();
strip.AddWebContents(page_a_contents, -1,
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
TabStripModel::ADD_ACTIVE);
WebContents* page_b_contents = CreateWebContents();
WebContents* page_c_contents = CreateWebContents();
WebContents* page_d_contents = CreateWebContents();
strip.AddWebContents(page_b_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.AddWebContents(page_c_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.AddWebContents(page_d_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
strip.ActivateTabAt(2, true);
WebContents* new_contents1 = CreateWebContents();
strip.AddWebContents(new_contents1, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
strip.CloseWebContentsAt(strip.count() - 1, TabStripModel::CLOSE_NONE);
EXPECT_EQ(page_c_contents, strip.GetWebContentsAt(strip.active_index()));
WebContents* new_contents2 = CreateWebContents();
strip.AddWebContents(new_contents2, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
strip.ActivateTabAt(0, true);
strip.ActivateTabAt(strip.count() - 1, true);
strip.CloseWebContentsAt(strip.count() - 1, TabStripModel::CLOSE_NONE);
EXPECT_EQ(page_d_contents, strip.GetWebContentsAt(strip.active_index()));
strip.CloseAllTabs();
}
#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
#define MAYBE_FastShutdown \
DISABLED_FastShutdown
#else
#define MAYBE_FastShutdown \
FastShutdown
#endif
TEST_F(TabStripModelTest, MAYBE_FastShutdown) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
MockTabStripModelObserver observer(&tabstrip);
tabstrip.AddObserver(&observer);
EXPECT_TRUE(tabstrip.empty());
{
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContentsWithSharedRPH(contents1);
SetID(contents1, 1);
SetID(contents2, 2);
tabstrip.AppendWebContents(contents1, true);
tabstrip.AppendWebContents(contents2, true);
delegate.set_run_unload_listener(true);
tabstrip.CloseAllTabs();
EXPECT_TRUE(contents1->GetRenderProcessHost()->FastShutdownStarted());
EXPECT_EQ(2, tabstrip.count());
delegate.set_run_unload_listener(false);
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
{
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContentsWithSharedRPH(contents1);
SetID(contents1, 1);
SetID(contents2, 2);
tabstrip.AppendWebContents(contents1, true);
tabstrip.AppendWebContents(contents2, true);
tabstrip.CloseWebContentsAt(1, TabStripModel::CLOSE_NONE);
EXPECT_FALSE(contents1->GetRenderProcessHost()->FastShutdownStarted());
EXPECT_EQ(1, tabstrip.count());
tabstrip.CloseAllTabs();
EXPECT_TRUE(tabstrip.empty());
}
}
TEST_F(TabStripModelTest, Apps) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
MockTabStripModelObserver observer(&tabstrip);
tabstrip.AddObserver(&observer);
EXPECT_TRUE(tabstrip.empty());
typedef MockTabStripModelObserver::State State;
#if defined(OS_WIN)
base::FilePath path(FILE_PATH_LITERAL("c:\\foo"));
#elif defined(OS_POSIX)
base::FilePath path(FILE_PATH_LITERAL("/foo"));
#endif
base::DictionaryValue manifest;
manifest.SetString("name", "hi!");
manifest.SetString("version", "1");
manifest.SetString("app.launch.web_url", "http://www.google.com");
std::string error;
scoped_refptr<Extension> extension_app(
Extension::Create(path, extensions::Manifest::INVALID_LOCATION,
manifest, Extension::NO_FLAGS, &error));
WebContents* contents1 = CreateWebContents();
extensions::TabHelper::CreateForWebContents(contents1);
extensions::TabHelper::FromWebContents(contents1)
->SetExtensionApp(extension_app.get());
WebContents* contents2 = CreateWebContents();
extensions::TabHelper::CreateForWebContents(contents2);
extensions::TabHelper::FromWebContents(contents2)
->SetExtensionApp(extension_app.get());
WebContents* contents3 = CreateWebContents();
SetID(contents1, 1);
SetID(contents2, 2);
SetID(contents3, 3);
tabstrip.AppendWebContents(contents3, true);
observer.ClearStates();
{
tabstrip.InsertWebContentsAt(1, contents1, TabStripModel::ADD_NONE);
ASSERT_EQ(1, observer.GetStateCount());
State state(contents1, 0, MockTabStripModelObserver::INSERT);
EXPECT_TRUE(observer.StateEquals(0, state));
EXPECT_EQ("1ap 3", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.InsertWebContentsAt(1, contents2, TabStripModel::ADD_NONE);
ASSERT_EQ(1, observer.GetStateCount());
State state(contents2, 1, MockTabStripModelObserver::INSERT);
EXPECT_TRUE(observer.StateEquals(0, state));
EXPECT_EQ("1ap 2ap 3", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.MoveWebContentsAt(2, 0, false);
ASSERT_EQ(0, observer.GetStateCount());
EXPECT_EQ("1ap 2ap 3", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.MoveWebContentsAt(0, 2, false);
ASSERT_EQ(0, observer.GetStateCount());
EXPECT_EQ("1ap 2ap 3", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.MoveWebContentsAt(0, 1, false);
ASSERT_EQ(1, observer.GetStateCount());
State state(contents1, 1, MockTabStripModelObserver::MOVE);
state.src_index = 0;
EXPECT_TRUE(observer.StateEquals(0, state));
EXPECT_EQ("2ap 1ap 3", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.DetachWebContentsAt(2);
observer.ClearStates();
tabstrip.InsertWebContentsAt(0, contents3, TabStripModel::ADD_NONE);
ASSERT_EQ(1, observer.GetStateCount());
State state(contents3, 2, MockTabStripModelObserver::INSERT);
EXPECT_TRUE(observer.StateEquals(0, state));
EXPECT_EQ("2ap 1ap 3", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
tabstrip.CloseAllTabs();
}
TEST_F(TabStripModelTest, Pinning) {
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
MockTabStripModelObserver observer(&tabstrip);
tabstrip.AddObserver(&observer);
EXPECT_TRUE(tabstrip.empty());
typedef MockTabStripModelObserver::State State;
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
SetID(contents1, 1);
SetID(contents2, 2);
SetID(contents3, 3);
tabstrip.AppendWebContents(contents1, true);
tabstrip.AppendWebContents(contents2, false);
tabstrip.AppendWebContents(contents3, false);
observer.ClearStates();
{
tabstrip.SetTabPinned(0, true);
ASSERT_EQ(1, observer.GetStateCount());
State state(contents1, 0, MockTabStripModelObserver::PINNED);
EXPECT_TRUE(observer.StateEquals(0, state));
EXPECT_EQ("1p 2 3", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.SetTabPinned(0, false);
ASSERT_EQ(1, observer.GetStateCount());
State state(contents1, 0, MockTabStripModelObserver::PINNED);
EXPECT_TRUE(observer.StateEquals(0, state));
EXPECT_EQ("1 2 3", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.SetTabPinned(2, true);
ASSERT_EQ(2, observer.GetStateCount());
State state(contents3, 0, MockTabStripModelObserver::MOVE);
state.src_index = 2;
EXPECT_TRUE(observer.StateEquals(0, state));
state = State(contents3, 0, MockTabStripModelObserver::PINNED);
EXPECT_TRUE(observer.StateEquals(1, state));
EXPECT_EQ("3p 1 2", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.SetTabPinned(1, true);
ASSERT_EQ(1, observer.GetStateCount());
State state(contents1, 1, MockTabStripModelObserver::PINNED);
EXPECT_TRUE(observer.StateEquals(0, state));
EXPECT_EQ("3p 1p 2", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.MoveWebContentsAt(2, 0, false);
ASSERT_EQ(0, observer.GetStateCount());
EXPECT_EQ("3p 1p 2", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.SetTabPinned(0, false);
ASSERT_EQ(2, observer.GetStateCount());
State state(contents3, 1, MockTabStripModelObserver::MOVE);
state.src_index = 0;
EXPECT_TRUE(observer.StateEquals(0, state));
state = State(contents3, 1, MockTabStripModelObserver::PINNED);
EXPECT_TRUE(observer.StateEquals(1, state));
EXPECT_EQ("1p 3 2", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.SetTabPinned(1, false);
ASSERT_EQ(0, observer.GetStateCount());
EXPECT_EQ("1p 3 2", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
{
tabstrip.SetTabPinned(0, true);
tabstrip.SetTabPinned(1, true);
EXPECT_EQ("1p 3p 2", GetTabStripStateString(tabstrip));
observer.ClearStates();
}
WebContents* contents4 = CreateWebContents();
SetID(contents4, 4);
{
tabstrip.InsertWebContentsAt(1, contents4, TabStripModel::ADD_NONE);
ASSERT_EQ(1, observer.GetStateCount());
State state(contents4, 2, MockTabStripModelObserver::INSERT);
EXPECT_TRUE(observer.StateEquals(0, state));
EXPECT_EQ("1p 3p 4 2", GetTabStripStateString(tabstrip));
}
tabstrip.CloseAllTabs();
}
TEST_F(TabStripModelTest, ReplaceSendsSelected) {
typedef MockTabStripModelObserver::State State;
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* first_contents = CreateWebContents();
strip.AddWebContents(first_contents, -1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_ACTIVE);
MockTabStripModelObserver tabstrip_observer(&strip);
strip.AddObserver(&tabstrip_observer);
WebContents* new_contents = CreateWebContents();
delete strip.ReplaceWebContentsAt(0, new_contents);
ASSERT_EQ(2, tabstrip_observer.GetStateCount());
State state(new_contents, 0, MockTabStripModelObserver::REPLACED);
state.src_contents = first_contents;
EXPECT_TRUE(tabstrip_observer.StateEquals(0, state));
state = State(new_contents, 0, MockTabStripModelObserver::ACTIVATE);
state.src_contents = first_contents;
state.change_reason = TabStripModelObserver::CHANGE_REASON_REPLACED;
EXPECT_TRUE(tabstrip_observer.StateEquals(1, state));
WebContents* third_contents = CreateWebContents();
strip.AddWebContents(third_contents, 1, content::PAGE_TRANSITION_TYPED,
TabStripModel::ADD_NONE);
tabstrip_observer.ClearStates();
new_contents = CreateWebContents();
delete strip.ReplaceWebContentsAt(1, new_contents);
ASSERT_EQ(1, tabstrip_observer.GetStateCount());
state = State(new_contents, 1, MockTabStripModelObserver::REPLACED);
state.src_contents = third_contents;
EXPECT_TRUE(tabstrip_observer.StateEquals(0, state));
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, DiscardWebContentsAt) {
typedef MockTabStripModelObserver::State State;
TabStripDummyDelegate delegate;
TabStripModel tabstrip(&delegate, profile());
WebContents* contents1 = CreateWebContents();
tabstrip.AppendWebContents(contents1, true);
WebContents* contents2 = CreateWebContents();
tabstrip.AppendWebContents(contents2, true);
MockTabStripModelObserver tabstrip_observer(&tabstrip);
tabstrip.AddObserver(&tabstrip_observer);
WebContents* null_contents1 = tabstrip.DiscardWebContentsAt(0);
ASSERT_EQ(2, tabstrip.count());
EXPECT_TRUE(tabstrip.IsTabDiscarded(0));
EXPECT_FALSE(tabstrip.IsTabDiscarded(1));
ASSERT_EQ(null_contents1, tabstrip.GetWebContentsAt(0));
ASSERT_EQ(contents2, tabstrip.GetWebContentsAt(1));
ASSERT_EQ(1, tabstrip_observer.GetStateCount());
State state1(null_contents1, 0, MockTabStripModelObserver::REPLACED);
state1.src_contents = contents1;
EXPECT_TRUE(tabstrip_observer.StateEquals(0, state1));
tabstrip_observer.ClearStates();
WebContents* null_contents2 = tabstrip.DiscardWebContentsAt(0);
ASSERT_EQ(2, tabstrip.count());
EXPECT_TRUE(tabstrip.IsTabDiscarded(0));
EXPECT_FALSE(tabstrip.IsTabDiscarded(1));
ASSERT_EQ(null_contents2, tabstrip.GetWebContentsAt(0));
ASSERT_EQ(contents2, tabstrip.GetWebContentsAt(1));
ASSERT_EQ(1, tabstrip_observer.GetStateCount());
State state2(null_contents2, 0, MockTabStripModelObserver::REPLACED);
state2.src_contents = null_contents1;
EXPECT_TRUE(tabstrip_observer.StateEquals(0, state2));
tabstrip_observer.ClearStates();
tabstrip.ActivateTabAt(0, true );
ASSERT_EQ(2, tabstrip.count());
EXPECT_FALSE(tabstrip.IsTabDiscarded(0));
EXPECT_FALSE(tabstrip.IsTabDiscarded(1));
tabstrip.DiscardWebContentsAt(0);
ASSERT_EQ(2, tabstrip.count());
EXPECT_FALSE(tabstrip.IsTabDiscarded(0));
EXPECT_FALSE(tabstrip.IsTabDiscarded(1));
tabstrip.CloseAllTabs();
}
TEST_F(TabStripModelTest, DeleteFromDestroy) {
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
strip.AppendWebContents(contents1, true);
strip.AppendWebContents(contents2, true);
DeleteWebContentsOnDestroyedObserver observer(contents2, contents1, NULL);
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, DeleteTabStripFromDestroy) {
TabStripDummyDelegate delegate;
TabStripModel* strip = new TabStripModel(&delegate, profile());
MockTabStripModelObserver tab_strip_model_observer(strip);
strip->AddObserver(&tab_strip_model_observer);
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
strip->AppendWebContents(contents1, true);
strip->AppendWebContents(contents2, true);
DeleteWebContentsOnDestroyedObserver observer(contents2, contents1, strip);
strip->CloseAllTabs();
EXPECT_TRUE(tab_strip_model_observer.empty());
EXPECT_TRUE(tab_strip_model_observer.deleted());
}
TEST_F(TabStripModelTest, MoveSelectedTabsTo) {
struct TestData {
const int tab_count;
const int pinned_count;
const std::string selected_tabs;
const int target_index;
const std::string state_after_move;
} test_data[] = {
{ 2, 0, "0", 1, "1 0" },
{ 3, 0, "0", 2, "1 2 0" },
{ 3, 0, "2", 0, "2 0 1" },
{ 3, 0, "2", 1, "0 2 1" },
{ 3, 0, "0 1", 0, "0 1 2" },
{ 6, 0, "4 5", 1, "0 4 5 1 2 3" },
{ 3, 0, "0 1", 1, "2 0 1" },
{ 4, 0, "0 2", 1, "1 0 2 3" },
{ 6, 0, "0 1", 3, "2 3 4 0 1 5" },
{ 6, 0, "0 2 3", 3, "1 4 5 0 2 3" },
{ 7, 0, "4 5 6", 1, "0 4 5 6 1 2 3" },
{ 7, 0, "1 5 6", 4, "0 2 3 4 1 5 6" },
{ 8, 0, "0 2 3 6 7", 3, "1 4 5 0 2 3 6 7" },
{ 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" },
{ 6, 2, "2 3", 2, "0p 1p 2 3 4 5" },
{ 6, 2, "0 4", 3, "1p 0p 2 3 4 5" },
{ 6, 3, "1 2 4", 0, "1p 2p 0p 4 3 5" },
{ 8, 3, "1 3 4", 4, "0p 2p 1p 5 6 3 4 7" },
{ 7, 4, "2 3 4", 3, "0p 1p 2p 3p 5 4 6" },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
ASSERT_NO_FATAL_FAILURE(
PrepareTabstripForSelectionTest(&strip, test_data[i].tab_count,
test_data[i].pinned_count,
test_data[i].selected_tabs));
strip.MoveSelectedTabsTo(test_data[i].target_index);
EXPECT_EQ(test_data[i].state_after_move,
GetTabStripStateString(strip)) << i;
strip.CloseAllTabs();
}
}
TEST_F(TabStripModelTest, MoveSelectedTabsTo_ForgetGroups) {
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* page_a_contents = CreateWebContents();
strip.AddWebContents(page_a_contents, -1,
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
TabStripModel::ADD_ACTIVE);
WebContents* page_a1_contents = CreateWebContents();
strip.AddWebContents(page_a1_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
WebContents* page_b_contents = CreateWebContents();
strip.AddWebContents(page_b_contents, -1,
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
TabStripModel::ADD_ACTIVE);
WebContents* page_b1_contents = CreateWebContents();
strip.AddWebContents(page_b1_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
EXPECT_EQ(page_a_contents, strip.GetWebContentsAt(0));
EXPECT_EQ(page_a1_contents, strip.GetWebContentsAt(1));
EXPECT_EQ(page_b_contents, strip.GetWebContentsAt(2));
EXPECT_EQ(page_b1_contents, strip.GetWebContentsAt(3));
strip.MoveSelectedTabsTo(0);
WebContents* page_b2_contents = CreateWebContents();
strip.AddWebContents(page_b2_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
EXPECT_EQ(page_b_contents, strip.GetWebContentsAt(0));
EXPECT_EQ(page_b2_contents, strip.GetWebContentsAt(1));
EXPECT_EQ(page_a_contents, strip.GetWebContentsAt(2));
EXPECT_EQ(page_a1_contents, strip.GetWebContentsAt(3));
EXPECT_EQ(page_b1_contents, strip.GetWebContentsAt(4));
strip.ActivateTabAt(2, true);
EXPECT_EQ(page_a_contents, strip.GetActiveWebContents());
WebContents* page_a2_contents = CreateWebContents();
strip.AddWebContents(page_a2_contents, -1, content::PAGE_TRANSITION_LINK,
TabStripModel::ADD_NONE);
EXPECT_EQ(page_b_contents, strip.GetWebContentsAt(0));
EXPECT_EQ(page_b2_contents, strip.GetWebContentsAt(1));
EXPECT_EQ(page_a_contents, strip.GetWebContentsAt(2));
EXPECT_EQ(page_a1_contents, strip.GetWebContentsAt(3));
EXPECT_EQ(page_a2_contents, strip.GetWebContentsAt(4));
EXPECT_EQ(page_b1_contents, strip.GetWebContentsAt(5));
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, CloseSelectedTabs) {
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
strip.AppendWebContents(contents1, true);
strip.AppendWebContents(contents2, true);
strip.AppendWebContents(contents3, true);
strip.ToggleSelectionAt(1);
strip.CloseSelectedTabs();
EXPECT_EQ(1, strip.count());
EXPECT_EQ(0, strip.active_index());
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, MultipleSelection) {
typedef MockTabStripModelObserver::State State;
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
MockTabStripModelObserver observer(&strip);
WebContents* contents0 = CreateWebContents();
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
WebContents* contents3 = CreateWebContents();
strip.AppendWebContents(contents0, false);
strip.AppendWebContents(contents1, false);
strip.AppendWebContents(contents2, false);
strip.AppendWebContents(contents3, false);
strip.AddObserver(&observer);
strip.ActivateTabAt(3, true);
ASSERT_EQ(2, observer.GetStateCount());
ASSERT_EQ(observer.GetStateAt(0).action,
MockTabStripModelObserver::ACTIVATE);
State s1(contents3, 3, MockTabStripModelObserver::SELECT);
EXPECT_TRUE(observer.StateEquals(1, s1));
observer.ClearStates();
strip.ExtendSelectionTo(0);
ASSERT_EQ(3, observer.GetStateCount());
ASSERT_EQ(observer.GetStateAt(0).action,
MockTabStripModelObserver::DEACTIVATE);
ASSERT_EQ(observer.GetStateAt(1).action,
MockTabStripModelObserver::ACTIVATE);
State s2(contents0, 0, MockTabStripModelObserver::SELECT);
s2.src_contents = contents3;
s2.src_index = 3;
EXPECT_TRUE(observer.StateEquals(2, s2));
observer.ClearStates();
strip.ToggleSelectionAt(0);
EXPECT_EQ(1, strip.active_index());
EXPECT_EQ(3U, strip.selection_model().size());
EXPECT_EQ(4, strip.count());
ASSERT_EQ(3, observer.GetStateCount());
ASSERT_EQ(observer.GetStateAt(0).action,
MockTabStripModelObserver::DEACTIVATE);
ASSERT_EQ(observer.GetStateAt(1).action,
MockTabStripModelObserver::ACTIVATE);
ASSERT_EQ(observer.GetStateAt(2).action,
MockTabStripModelObserver::SELECT);
observer.ClearStates();
strip.ToggleSelectionAt(0);
EXPECT_EQ(0, strip.active_index());
EXPECT_EQ(4U, strip.selection_model().size());
EXPECT_EQ(4, strip.count());
ASSERT_EQ(3, observer.GetStateCount());
ASSERT_EQ(observer.GetStateAt(0).action,
MockTabStripModelObserver::DEACTIVATE);
ASSERT_EQ(observer.GetStateAt(1).action,
MockTabStripModelObserver::ACTIVATE);
ASSERT_EQ(observer.GetStateAt(2).action,
MockTabStripModelObserver::SELECT);
observer.ClearStates();
strip.CloseWebContentsAt(1, TabStripModel::CLOSE_NONE);
EXPECT_EQ(3, strip.count());
ASSERT_EQ(3, observer.GetStateCount());
ASSERT_EQ(observer.GetStateAt(0).action,
MockTabStripModelObserver::CLOSE);
ASSERT_EQ(observer.GetStateAt(1).action,
MockTabStripModelObserver::DETACH);
ASSERT_EQ(observer.GetStateAt(2).action,
MockTabStripModelObserver::SELECT);
observer.ClearStates();
strip.CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
EXPECT_EQ(2, strip.count());
ASSERT_EQ(5, observer.GetStateCount());
ASSERT_EQ(observer.GetStateAt(0).action,
MockTabStripModelObserver::CLOSE);
ASSERT_EQ(observer.GetStateAt(1).action,
MockTabStripModelObserver::DETACH);
ASSERT_EQ(observer.GetStateAt(2).action,
MockTabStripModelObserver::DEACTIVATE);
ASSERT_EQ(observer.GetStateAt(3).action,
MockTabStripModelObserver::ACTIVATE);
ASSERT_EQ(observer.GetStateAt(4).action,
MockTabStripModelObserver::SELECT);
observer.ClearStates();
strip.ToggleSelectionAt(1);
ASSERT_EQ(1, observer.GetStateCount());
ASSERT_EQ(observer.GetStateAt(0).action,
MockTabStripModelObserver::SELECT);
observer.ClearStates();
strip.ToggleSelectionAt(0);
ASSERT_EQ(0, observer.GetStateCount());
strip.RemoveObserver(&observer);
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, MultipleToSingle) {
typedef MockTabStripModelObserver::State State;
TabStripDummyDelegate delegate;
TabStripModel strip(&delegate, profile());
WebContents* contents1 = CreateWebContents();
WebContents* contents2 = CreateWebContents();
strip.AppendWebContents(contents1, false);
strip.AppendWebContents(contents2, false);
strip.ToggleSelectionAt(0);
strip.ToggleSelectionAt(1);
MockTabStripModelObserver observer(&strip);
strip.AddObserver(&observer);
strip.ActivateTabAt(1, true);
ASSERT_EQ(1, observer.GetStateCount());
State s(contents2, 1, MockTabStripModelObserver::SELECT);
s.src_contents = contents2;
s.src_index = 1;
s.change_reason = TabStripModelObserver::CHANGE_REASON_NONE;
EXPECT_TRUE(observer.StateEquals(0, s));
strip.RemoveObserver(&observer);
strip.CloseAllTabs();
}
TEST_F(TabStripModelTest, TabBlockedState) {
TabStripDummyDelegate dummy_tab_strip_delegate;
TabStripModel strip_src(&dummy_tab_strip_delegate, profile());
TabBlockedStateTestBrowser browser_src(&strip_src);
WebContents* contents1 = CreateWebContents();
web_modal::WebContentsModalDialogManager::CreateForWebContents(contents1);
strip_src.AppendWebContents(contents1, false);
WebContents* contents2 = CreateWebContents();
web_modal::WebContentsModalDialogManager::CreateForWebContents(contents2);
strip_src.AppendWebContents(contents2, false);
TabStripModel strip_dst(&dummy_tab_strip_delegate, profile());
TabBlockedStateTestBrowser browser_dst(&strip_dst);
web_modal::WebContentsModalDialogManager* modal_dialog_manager =
web_modal::WebContentsModalDialogManager::FromWebContents(contents2);
web_modal::WebContentsModalDialogManager::TestApi test_api(
modal_dialog_manager);
test_api.ResetNativeManager(
new DummyNativeWebContentsModalDialogManager(modal_dialog_manager));
modal_dialog_manager->ShowDialog(
reinterpret_cast<NativeWebContentsModalDialog>(0));
EXPECT_TRUE(strip_src.IsTabBlocked(1));
WebContents* moved_contents = strip_src.DetachWebContentsAt(1);
EXPECT_EQ(contents2, moved_contents);
strip_dst.AppendWebContents(moved_contents, true);
EXPECT_TRUE(strip_dst.IsTabBlocked(0));
strip_dst.CloseAllTabs();
strip_src.CloseAllTabs();
}