| Index: chrome/browser/ui/views/sidebar/browser_sidebar_tab_strip_controller_unittest.cc
 | 
| ===================================================================
 | 
| --- chrome/browser/ui/views/sidebar/browser_sidebar_tab_strip_controller_unittest.cc	(revision 0)
 | 
| +++ chrome/browser/ui/views/sidebar/browser_sidebar_tab_strip_controller_unittest.cc	(revision 0)
 | 
| @@ -0,0 +1,300 @@
 | 
| +// Copyright (c) 2010 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 <vector>
 | 
| +
 | 
| +#include "base/scoped_ptr.h"
 | 
| +#include "base/stl_util-inl.h"
 | 
| +#include "base/string_util.h"
 | 
| +#include "chrome/browser/browser_thread.h"
 | 
| +#include "chrome/browser/profiles/profile.h"
 | 
| +#include "chrome/browser/profiles/profile_manager.h"
 | 
| +#include "chrome/browser/sidebar/sidebar_container.h"
 | 
| +#include "chrome/browser/sidebar/sidebar_model.h"
 | 
| +#include "chrome/browser/tab_contents/tab_contents.h"
 | 
| +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
 | 
| +#include "chrome/browser/ui/views/sidebar/browser_sidebar_tab_strip_controller.h"
 | 
| +#include "chrome/browser/ui/views/sidebar/sidebar_base_tab_strip.h"
 | 
| +#include "chrome/browser/ui/views/sidebar/sidebar_tab_strip_controller.h"
 | 
| +#include "chrome/browser/ui/views/sidebar/sidebar_tab_test_helper.h"
 | 
| +#include "chrome/test/testing_profile.h"
 | 
| +#include "ipc/ipc_message.h"
 | 
| +#include "testing/gmock/include/gmock/gmock.h"
 | 
| +#include "testing/gtest/include/gtest/gtest.h"
 | 
| +
 | 
| +using testing::_;
 | 
| +using testing::AnyNumber;
 | 
| +using testing::Exactly;
 | 
| +using testing::InSequence;
 | 
| +using testing::Return;
 | 
| +
 | 
| +namespace {
 | 
| +
 | 
| +// Fake content ids.
 | 
| +const char kContentId1[] = "1";
 | 
| +const char kContentId2[] = "12";
 | 
| +const char kContentId3[] = "13";
 | 
| +
 | 
| +}  // namespace
 | 
| +
 | 
| +// Test harness for BrowserSidebarTabStripController tests.
 | 
| +// Creates all necessary mocks and real objects and binds them together
 | 
| +// to create a simulated environment for the controller under test.
 | 
| +class BrowserSidebarTabStripControllerTest : public testing::Test {
 | 
| + public:
 | 
| +  BrowserSidebarTabStripControllerTest()
 | 
| +      : ui_thread_(BrowserThread::UI, &message_loop_) {
 | 
| +  }
 | 
| +
 | 
| +  virtual void SetUp() {
 | 
| +    profile_.reset(new TestingProfile());
 | 
| +    tabs_.push_back(new TabContentsWrapper(
 | 
| +        new TabContents(profile_.get(), NULL, MSG_ROUTING_NONE, NULL, NULL)));
 | 
| +    tabs_.push_back(new TabContentsWrapper(
 | 
| +        new TabContents(profile_.get(), NULL, MSG_ROUTING_NONE, NULL, NULL)));
 | 
| +    tabs_.push_back(new TabContentsWrapper(
 | 
| +        new TabContents(profile_.get(), NULL, MSG_ROUTING_NONE, NULL, NULL)));
 | 
| +
 | 
| +    // Create all mocks and build the ownership graph.
 | 
| +    model_.reset(new MockSidebarModel());
 | 
| +    delegate_.reset(new MockSidebarTabStripControllerDelegate());
 | 
| +
 | 
| +    controller_ =
 | 
| +        new BrowserSidebarTabStripController(model_.get(), delegate_.get());
 | 
| +
 | 
| +    tabstrip_.reset(new MockSidebarBaseTabStrip(controller_));
 | 
| +
 | 
| +    controller_->set_tab_strip(tabstrip_.get());
 | 
| +  }
 | 
| +
 | 
| +  virtual void TearDown() {
 | 
| +    tabstrip_.reset();
 | 
| +    delegate_.reset();
 | 
| +    model_.reset();
 | 
| +
 | 
| +    STLDeleteContainerPointers(tabs_.begin(), tabs_.end());
 | 
| +    profile_.reset();
 | 
| +  }
 | 
| +
 | 
| + protected:
 | 
| +  // Accessors for private members.
 | 
| +  size_t GetControllerModelCount() const {
 | 
| +    return controller_->model_index_.size();
 | 
| +  }
 | 
| +
 | 
| +  // Mocks accessible from tests.
 | 
| +  scoped_ptr<MockSidebarModel> model_;
 | 
| +  scoped_ptr<MockSidebarBaseTabStrip> tabstrip_;
 | 
| +  // Owned by |tabstrip_|.
 | 
| +  BrowserSidebarTabStripController* controller_;
 | 
| +  // Almost real tabs accessible from tests.
 | 
| +  std::vector<TabContentsWrapper*> tabs_;
 | 
| +
 | 
| + private:
 | 
| +  scoped_ptr<Profile> profile_;
 | 
| +  scoped_ptr<MockSidebarTabStripControllerDelegate> delegate_;
 | 
| +
 | 
| +  MessageLoopForUI message_loop_;
 | 
| +  BrowserThread ui_thread_;
 | 
| +};
 | 
| +
 | 
| +TEST_F(BrowserSidebarTabStripControllerTest, EmptyModel) {
 | 
| +  // Check that nothing extra happens when model is empty, these are the only
 | 
| +  // calls we expect to receive.
 | 
| +  EXPECT_CALL(*model_, GetActiveSidebarContainerFor(_))
 | 
| +      .Times(AnyNumber())
 | 
| +      .WillRepeatedly(Return(static_cast<SidebarContainer*>(NULL)));
 | 
| +  EXPECT_CALL(*tabstrip_, SetToIdealBounds())
 | 
| +      .Times(AnyNumber());
 | 
| +
 | 
| +  // Check preconditions.
 | 
| +  EXPECT_EQ(0, tabstrip_->tab_count());
 | 
| +  EXPECT_EQ(0, GetControllerModelCount());
 | 
| +
 | 
| +  // Emulate tab switches.
 | 
| +  TabContentsWrapper* tab_switch_sequence[] = {
 | 
| +      tabs_[0], tabs_[1], NULL
 | 
| +  };
 | 
| +  for (int i = 0; i < arraysize(tab_switch_sequence); ++i) {
 | 
| +    controller_->UpdateTabs(tab_switch_sequence[i]);
 | 
| +    // Nothing should change.
 | 
| +    EXPECT_EQ(0, GetControllerModelCount());
 | 
| +  }
 | 
| +
 | 
| +  // Check postconditions.
 | 
| +  EXPECT_EQ(0, tabstrip_->tab_count());
 | 
| +  EXPECT_EQ(0, GetControllerModelCount());
 | 
| +}
 | 
| +
 | 
| +TEST_F(BrowserSidebarTabStripControllerTest, UpdateTabsOnTabChange) {
 | 
| +  // Set up sidebars for tabs.
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[0], kContentId1, NULL));
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[1], kContentId1, NULL));
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[1], kContentId2, NULL));
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[1], kContentId3, NULL));
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[2], kContentId2, NULL));
 | 
| +
 | 
| +  // Set up expectations.
 | 
| +  EXPECT_CALL(*model_, GetActiveSidebarContainerFor(_))
 | 
| +      .Times(AnyNumber())
 | 
| +      .WillRepeatedly(Return(static_cast<SidebarContainer*>(NULL)));
 | 
| +  EXPECT_CALL(*tabstrip_, SetToIdealBounds())
 | 
| +      .Times(AnyNumber());
 | 
| +
 | 
| +  // The following calls should happen in this order to make sure
 | 
| +  // tab views are created and removed only when necessary (as opposed
 | 
| +  // to remove all views and recreate them on every UpdateTabs call).
 | 
| +  {
 | 
| +    InSequence sequence;
 | 
| +
 | 
| +    // No animation is supposed to be requested on tab switch, hence
 | 
| +    // false as a second parameter for all calls.
 | 
| +    // The only tab for tabs_[0] gets added.
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(0, false, _));
 | 
| +    // Two tabs for tabs_[1] are added, the first one is reused.
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(1, false, _));
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(2, false, _));
 | 
| +    // The first and third tabs are removed.
 | 
| +    EXPECT_CALL(*tabstrip_, RemoveTabAt(0, false));
 | 
| +    EXPECT_CALL(*tabstrip_, RemoveTabAt(1, false));
 | 
| +    // The first tab is inserted, second one is removed
 | 
| +    // on tabs_[2] -> tabs_[0] switch.
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(0, false, _));
 | 
| +    EXPECT_CALL(*tabstrip_, RemoveTabAt(1, false));
 | 
| +    // The last tab is removed on closing all tabs (switching to NULL).
 | 
| +    EXPECT_CALL(*tabstrip_, RemoveTabAt(0, false));
 | 
| +  }
 | 
| +
 | 
| +  // Emulate tab switches, check that a number of sidebars defined
 | 
| +  // for the tab match a number of sidebar mini tabs in the controller's model.
 | 
| +  TabContentsWrapper* tab_switch_sequence[] = {
 | 
| +      tabs_[0],  // kContentId1
 | 
| +      tabs_[1],  // kContentId1 | kContentId2 | kContentId3
 | 
| +      tabs_[2],  // kContentId2
 | 
| +      tabs_[0],  // kContentId1
 | 
| +      NULL
 | 
| +  };
 | 
| +  for (int i = 0; i < arraysize(tab_switch_sequence); ++i) {
 | 
| +    controller_->UpdateTabs(tab_switch_sequence[i]);
 | 
| +
 | 
| +    EXPECT_EQ(model_->GetAllSidebarsFor(tab_switch_sequence[i]).size(),
 | 
| +              GetControllerModelCount());
 | 
| +  }
 | 
| +
 | 
| +  // Check postconditions.
 | 
| +  EXPECT_EQ(0, tabstrip_->tab_count());
 | 
| +  EXPECT_EQ(0, GetControllerModelCount());
 | 
| +}
 | 
| +
 | 
| +TEST_F(BrowserSidebarTabStripControllerTest, UpdateState) {
 | 
| +  // Set up sidebars for tabs.
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[0], kContentId1, NULL));
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[0], kContentId2, NULL));
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[0], kContentId3, NULL));
 | 
| +
 | 
| +  // Set up expectations.
 | 
| +  EXPECT_CALL(*model_, GetActiveSidebarContainerFor(_))
 | 
| +      .Times(AnyNumber())
 | 
| +      .WillRepeatedly(Return(static_cast<SidebarContainer*>(NULL)));
 | 
| +  EXPECT_CALL(*tabstrip_, SetToIdealBounds())
 | 
| +      .Times(AnyNumber());
 | 
| +  {
 | 
| +    InSequence sequence;
 | 
| +
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(0, false, _));
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(1, false, _));
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(2, false, _));
 | 
| +
 | 
| +    // Updating tab with model_index 1.
 | 
| +    EXPECT_CALL(*tabstrip_, SetTabData(1, _));
 | 
| +  }
 | 
| +
 | 
| +  // Create tabs.
 | 
| +  controller_->UpdateTabs(tabs_[0]);
 | 
| +
 | 
| +  // Update second tab state.
 | 
| +  controller_->UpdateState(
 | 
| +      model_->GetSidebarContainerFor(tabs_[0], kContentId2));
 | 
| +}
 | 
| +
 | 
| +TEST_F(BrowserSidebarTabStripControllerTest, IsTabSelected) {
 | 
| +  // Set up sidebars for tabs.
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[0], kContentId1, NULL));
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[0], kContentId2, NULL));
 | 
| +
 | 
| +  // Set up expectations.
 | 
| +  EXPECT_CALL(*tabstrip_, SetToIdealBounds())
 | 
| +      .Times(AnyNumber());
 | 
| +  {
 | 
| +    InSequence sequence;
 | 
| +
 | 
| +    EXPECT_CALL(*model_, GetActiveSidebarContainerFor(_))
 | 
| +        .WillOnce(Return(static_cast<SidebarContainer*>(NULL)));
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(0, false, _));
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(1, false, _));
 | 
| +
 | 
| +    // No active sidebar during first two checks.
 | 
| +    EXPECT_CALL(*model_, GetActiveSidebarContainerFor(_))
 | 
| +        .Times(2)
 | 
| +        .WillRepeatedly(Return(static_cast<SidebarContainer*>(NULL)));
 | 
| +    // Second sidebar is active now.
 | 
| +    EXPECT_CALL(*model_, GetActiveSidebarContainerFor(_))
 | 
| +        .Times(2)
 | 
| +        .WillRepeatedly(Return(
 | 
| +            model_->GetSidebarContainerFor(tabs_[0], kContentId2)));
 | 
| +  }
 | 
| +
 | 
| +  // Create tabs.
 | 
| +  controller_->UpdateTabs(tabs_[0]);
 | 
| +
 | 
| +  // Verify that no tab is selected.
 | 
| +  EXPECT_FALSE(controller_->IsTabSelected(0));
 | 
| +  EXPECT_FALSE(controller_->IsTabSelected(1));
 | 
| +
 | 
| +  // Now, according to the expectations set earlier (see above),
 | 
| +  // the second tab is selected, check again.
 | 
| +  EXPECT_FALSE(controller_->IsTabSelected(0));
 | 
| +  EXPECT_TRUE(controller_->IsTabSelected(1));
 | 
| +}
 | 
| +
 | 
| +TEST_F(BrowserSidebarTabStripControllerTest, SelectTab) {
 | 
| +  // Set up sidebars for tabs.
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[0], kContentId1, NULL));
 | 
| +  model_->AddSidebarContainer(
 | 
| +      new SidebarContainer(tabs_[0], kContentId2, NULL));
 | 
| +
 | 
| +  // Set up expectations.
 | 
| +  EXPECT_CALL(*model_, GetActiveSidebarContainerFor(_))
 | 
| +      .Times(AnyNumber())
 | 
| +      .WillRepeatedly(Return(static_cast<SidebarContainer*>(NULL)));
 | 
| +  EXPECT_CALL(*tabstrip_, SetToIdealBounds())
 | 
| +      .Times(AnyNumber());
 | 
| +  {
 | 
| +    InSequence sequence;
 | 
| +
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(0, false, _));
 | 
| +    EXPECT_CALL(*tabstrip_, AddTabAt(1, false, _));
 | 
| +
 | 
| +    EXPECT_CALL(*model_, ToggleSidebar(tabs_[0], kContentId2));
 | 
| +    EXPECT_CALL(*model_, ToggleSidebar(tabs_[0], kContentId1));
 | 
| +  }
 | 
| +
 | 
| +  // Create tabs and emulate tab clicks.
 | 
| +  controller_->UpdateTabs(tabs_[0]);
 | 
| +
 | 
| +  controller_->SelectTab(1);
 | 
| +  controller_->SelectTab(0);
 | 
| +}
 | 
| +
 | 
| 
 | 
| Property changes on: chrome\browser\ui\views\sidebar\browser_sidebar_tab_strip_controller_unittest.cc
 | 
| ___________________________________________________________________
 | 
| Added: svn:eol-style
 | 
|    + LF
 | 
| 
 | 
| 
 |