| Index: chrome/browser/ui/views/tabs/tab_unittest.cc
|
| diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc
|
| index 6a175fa09506154477ab7ab90e4d6d60ae2e4b70..da4a1a7b08ca7483cdc1c94d4edc8d3c4e48e2e6 100644
|
| --- a/chrome/browser/ui/views/tabs/tab_unittest.cc
|
| +++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
|
| @@ -16,11 +16,12 @@ using views::Widget;
|
|
|
| class FakeTabController : public TabController {
|
| public:
|
| - FakeTabController() : immersive_style_(false) {
|
| + FakeTabController() : immersive_style_(false), active_tab_(false) {
|
| }
|
| virtual ~FakeTabController() {}
|
|
|
| void set_immersive_style(bool value) { immersive_style_ = value; }
|
| + void set_active_tab(bool value) { active_tab_ = value; }
|
|
|
| virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE {
|
| return selection_model_;
|
| @@ -34,7 +35,9 @@ class FakeTabController : public TabController {
|
| virtual void ShowContextMenuForTab(Tab* tab,
|
| const gfx::Point& p,
|
| ui::MenuSourceType source_type) OVERRIDE {}
|
| - virtual bool IsActiveTab(const Tab* tab) const OVERRIDE { return false; }
|
| + virtual bool IsActiveTab(const Tab* tab) const OVERRIDE {
|
| + return active_tab_;
|
| + }
|
| virtual bool IsTabSelected(const Tab* tab) const OVERRIDE {
|
| return false;
|
| }
|
| @@ -60,6 +63,7 @@ class FakeTabController : public TabController {
|
| private:
|
| ui::ListSelectionModel selection_model_;
|
| bool immersive_style_;
|
| + bool active_tab_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(FakeTabController);
|
| };
|
| @@ -70,11 +74,108 @@ class TabTest : public views::ViewsTestBase {
|
| virtual ~TabTest() {}
|
|
|
| static bool IconAnimationInvariant(const Tab& tab) {
|
| - bool capture_invariant =
|
| - tab.data().CaptureActive() == (tab.icon_animation_.get() != NULL);
|
| - bool audio_invariant =
|
| - !tab.data().AudioActive() || tab.tab_audio_indicator_->IsAnimating();
|
| - return capture_invariant && audio_invariant;
|
| + return tab.data().CaptureActive() == (tab.icon_animation_.get() != NULL);
|
| + }
|
| +
|
| + static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) {
|
| + // Check whether elements are visible when they are supposed to be, given
|
| + // Tab size and TabRendererData state.
|
| + if (tab.data_.mini) {
|
| + if (tab.data_.CaptureActive())
|
| + EXPECT_TRUE(tab.ShouldShowIcon());
|
| + else
|
| + EXPECT_TRUE(tab.ShouldShowIcon() != tab.ShouldShowAudioIndicator());
|
| + EXPECT_FALSE(tab.ShouldShowCloseBox());
|
| + } else if (tab.IsActive()) {
|
| + EXPECT_TRUE(tab.ShouldShowCloseBox());
|
| + switch (tab.IconCapacity()) {
|
| + case 0:
|
| + case 1:
|
| + EXPECT_FALSE(tab.ShouldShowIcon());
|
| + EXPECT_FALSE(tab.ShouldShowAudioIndicator());
|
| + break;
|
| + case 2:
|
| + if (tab.data_.CaptureActive())
|
| + EXPECT_TRUE(tab.ShouldShowIcon());
|
| + else
|
| + EXPECT_TRUE(tab.ShouldShowIcon() != tab.ShouldShowAudioIndicator());
|
| + break;
|
| + default:
|
| + EXPECT_LE(3, tab.IconCapacity());
|
| + EXPECT_TRUE(tab.ShouldShowIcon());
|
| + if (tab.data_.CaptureActive()) {
|
| + EXPECT_FALSE(tab.ShouldShowAudioIndicator());
|
| + } else {
|
| + EXPECT_TRUE(tab.data_.AudioActive() ==
|
| + tab.ShouldShowAudioIndicator());
|
| + }
|
| + break;
|
| + }
|
| + } else { // Tab not active and not mini tab.
|
| + switch (tab.IconCapacity()) {
|
| + case 0:
|
| + EXPECT_FALSE(tab.ShouldShowCloseBox());
|
| + EXPECT_FALSE(tab.ShouldShowIcon());
|
| + EXPECT_FALSE(tab.ShouldShowAudioIndicator());
|
| + break;
|
| + case 1:
|
| + EXPECT_FALSE(tab.ShouldShowCloseBox());
|
| + if (tab.data_.CaptureActive())
|
| + EXPECT_TRUE(tab.ShouldShowIcon());
|
| + else
|
| + EXPECT_TRUE(tab.ShouldShowIcon() != tab.ShouldShowAudioIndicator());
|
| + break;
|
| + default:
|
| + EXPECT_LE(2, tab.IconCapacity());
|
| + EXPECT_TRUE(tab.ShouldShowIcon());
|
| + if (tab.data_.CaptureActive()) {
|
| + EXPECT_FALSE(tab.ShouldShowAudioIndicator());
|
| + } else {
|
| + EXPECT_TRUE(tab.data_.AudioActive() ==
|
| + tab.ShouldShowAudioIndicator());
|
| + }
|
| + break;
|
| + }
|
| + }
|
| +
|
| + // Check positioning of elements with respect to each other, and that they
|
| + // are fully within the contents bounds.
|
| + const gfx::Rect contents_bounds = tab.GetContentsBounds();
|
| + if (tab.ShouldShowIcon()) {
|
| + EXPECT_LE(contents_bounds.x(), tab.favicon_bounds_.x());
|
| + if (tab.title_bounds_.width() > 0)
|
| + EXPECT_LE(tab.favicon_bounds_.right(), tab.title_bounds_.x());
|
| + EXPECT_LE(contents_bounds.y(), tab.favicon_bounds_.y());
|
| + EXPECT_LE(tab.favicon_bounds_.bottom(), contents_bounds.bottom());
|
| + }
|
| + if (tab.ShouldShowIcon() && tab.ShouldShowAudioIndicator())
|
| + EXPECT_LE(tab.favicon_bounds_.right(), tab.audio_indicator_bounds_.x());
|
| + if (tab.ShouldShowAudioIndicator()) {
|
| + if (tab.title_bounds_.width() > 0)
|
| + EXPECT_LE(tab.title_bounds_.right(), tab.audio_indicator_bounds_.x());
|
| + EXPECT_LE(tab.audio_indicator_bounds_.right(), contents_bounds.right());
|
| + EXPECT_LE(contents_bounds.y(), tab.audio_indicator_bounds_.y());
|
| + EXPECT_LE(tab.audio_indicator_bounds_.bottom(), contents_bounds.bottom());
|
| + }
|
| + if (tab.ShouldShowAudioIndicator() && tab.ShouldShowCloseBox()) {
|
| + // Note: The audio indicator can overlap the left-insets of the close box,
|
| + // but should otherwise be to the left of the close button.
|
| + EXPECT_LE(tab.audio_indicator_bounds_.right(),
|
| + tab.close_button_->bounds().x() +
|
| + tab.close_button_->GetInsets().left());
|
| + }
|
| + if (tab.ShouldShowCloseBox()) {
|
| + // Note: The title bounds can overlap the left-insets of the close box,
|
| + // but should otherwise be to the left of the close button.
|
| + if (tab.title_bounds_.width() > 0) {
|
| + EXPECT_LE(tab.title_bounds_.right(),
|
| + tab.close_button_->bounds().x() +
|
| + tab.close_button_->GetInsets().left());
|
| + }
|
| + EXPECT_LE(tab.close_button_->bounds().right(), contents_bounds.right());
|
| + EXPECT_LE(contents_bounds.y(), tab.close_button_->bounds().y());
|
| + EXPECT_LE(tab.close_button_->bounds().bottom(), contents_bounds.bottom());
|
| + }
|
| }
|
| };
|
|
|
| @@ -108,6 +209,61 @@ TEST_F(TabTest, HitTestTopPixel) {
|
| EXPECT_FALSE(tab.HitTestPoint(gfx::Point(tab.width() - 1, 0)));
|
| }
|
|
|
| +TEST_F(TabTest, LayoutAndVisibilityOfElements) {
|
| + FakeTabController controller;
|
| + Tab tab(&controller);
|
| +
|
| + SkBitmap bitmap;
|
| + bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16);
|
| + bitmap.allocPixels();
|
| + TabRendererData data;
|
| + data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
|
| +
|
| + // Perform layout over all possible combinations, checking for correct
|
| + // results.
|
| + for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) {
|
| + for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) {
|
| + for (int audio_state = TabRendererData::AUDIO_STATE_NONE;
|
| + audio_state <= TabRendererData::AUDIO_STATE_PLAYING; ++audio_state) {
|
| + for (int capture_state = TabRendererData::CAPTURE_STATE_NONE;
|
| + capture_state <= TabRendererData::CAPTURE_STATE_PROJECTING;
|
| + ++capture_state) {
|
| + SCOPED_TRACE(::testing::Message()
|
| + << (is_active_tab ? "Active" : "Inactive") << ' '
|
| + << (is_mini_tab ? "Mini " : "")
|
| + << "Tab with audio_state=" << audio_state
|
| + << " and capture_state=" << capture_state);
|
| + data.mini = !!is_mini_tab;
|
| + controller.set_active_tab(!!is_active_tab);
|
| + data.audio_state =
|
| + static_cast<TabRendererData::AudioState>(audio_state);
|
| + data.capture_state =
|
| + static_cast<TabRendererData::CaptureState>(capture_state);
|
| + tab.SetData(data);
|
| +
|
| + // Test layout for every width from standard to minimum.
|
| + gfx::Rect bounds(gfx::Point(0, 0), Tab::GetStandardSize());
|
| + int min_width;
|
| + if (is_mini_tab) {
|
| + bounds.set_width(Tab::GetMiniWidth());
|
| + min_width = Tab::GetMiniWidth();
|
| + } else {
|
| + min_width = is_active_tab ? Tab::GetMinimumSelectedSize().width() :
|
| + Tab::GetMinimumUnselectedSize().width();
|
| + }
|
| + while (bounds.width() >= min_width) {
|
| + SCOPED_TRACE(::testing::Message()
|
| + << "bounds=" << bounds.ToString());
|
| + tab.SetBoundsRect(bounds); // Invokes Tab::Layout().
|
| + CheckForExpectedLayoutAndVisibilityOfElements(tab);
|
| + bounds.set_width(bounds.width() - 1);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| // Regression test for http://crbug.com/226253. Calling Layout() more than once
|
| // shouldn't change the insets of the close button.
|
| TEST_F(TabTest, CloseButtonLayout) {
|
| @@ -127,9 +283,10 @@ TEST_F(TabTest, CloseButtonLayout) {
|
| EXPECT_EQ(50, tab.close_button_->bounds().height());
|
| }
|
|
|
| -TEST_F(TabTest, ActivityIndicators) {
|
| +TEST_F(TabTest, RecordingAndProjectingActivityIndicators) {
|
| FakeTabController controller;
|
| Tab tab(&controller);
|
| + tab.SetBoundsRect(gfx::Rect(gfx::Point(0, 0), Tab::GetStandardSize()));
|
|
|
| SkBitmap bitmap;
|
| bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16);
|
| @@ -139,77 +296,45 @@ TEST_F(TabTest, ActivityIndicators) {
|
| data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
|
| tab.SetData(data);
|
|
|
| - // Audio starts and stops.
|
| - data.audio_state = TabRendererData::AUDIO_STATE_PLAYING;
|
| - tab.SetData(data);
|
| - EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::AUDIO_STATE_PLAYING, tab.data().audio_state);
|
| - EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
|
| - data.audio_state = TabRendererData::AUDIO_STATE_NONE;
|
| - tab.SetData(data);
|
| - EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
|
| - EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
|
| - EXPECT_TRUE(IconAnimationInvariant(tab));
|
| -
|
| - // Capture starts and stops.
|
| + // Recording starts and stops.
|
| data.capture_state = TabRendererData::CAPTURE_STATE_RECORDING;
|
| tab.SetData(data);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
|
| EXPECT_EQ(TabRendererData::CAPTURE_STATE_RECORDING, tab.data().capture_state);
|
| data.capture_state = TabRendererData::CAPTURE_STATE_NONE;
|
| tab.SetData(data);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
|
| EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
|
|
| - // Audio starts then capture starts, then audio stops then capture stops.
|
| - data.audio_state = TabRendererData::AUDIO_STATE_PLAYING;
|
| - tab.SetData(data);
|
| + // Recording starts then tab capture starts, then back to just recording, then
|
| + // recording stops.
|
| data.capture_state = TabRendererData::CAPTURE_STATE_RECORDING;
|
| tab.SetData(data);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::AUDIO_STATE_PLAYING, tab.data().audio_state);
|
| EXPECT_EQ(TabRendererData::CAPTURE_STATE_RECORDING, tab.data().capture_state);
|
|
|
| data.title = ASCIIToUTF16("test X");
|
| tab.SetData(data);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
|
|
| - data.audio_state = TabRendererData::AUDIO_STATE_NONE;
|
| + data.capture_state = TabRendererData::CAPTURE_STATE_PROJECTING;
|
| tab.SetData(data);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::CAPTURE_STATE_RECORDING, tab.data().capture_state);
|
| - data.capture_state = TabRendererData::CAPTURE_STATE_NONE;
|
| + EXPECT_EQ(TabRendererData::CAPTURE_STATE_PROJECTING,
|
| + tab.data().capture_state);
|
| +
|
| + data.title = ASCIIToUTF16("test Y");
|
| tab.SetData(data);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
|
| - EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
|
|
|
| - // Audio starts then capture starts, then capture stops then audio stops.
|
| - data.audio_state = TabRendererData::AUDIO_STATE_PLAYING;
|
| - tab.SetData(data);
|
| data.capture_state = TabRendererData::CAPTURE_STATE_RECORDING;
|
| tab.SetData(data);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::AUDIO_STATE_PLAYING, tab.data().audio_state);
|
| EXPECT_EQ(TabRendererData::CAPTURE_STATE_RECORDING, tab.data().capture_state);
|
|
|
| - data.title = ASCIIToUTF16("test Y");
|
| - tab.SetData(data);
|
| - EXPECT_TRUE(IconAnimationInvariant(tab));
|
| -
|
| data.capture_state = TabRendererData::CAPTURE_STATE_NONE;
|
| tab.SetData(data);
|
| EXPECT_TRUE(IconAnimationInvariant(tab));
|
| EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
|
| -
|
| - data.audio_state = TabRendererData::AUDIO_STATE_NONE;
|
| - tab.SetData(data);
|
| - EXPECT_TRUE(IconAnimationInvariant(tab));
|
| - EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
|
| - EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
|
| - EXPECT_TRUE(IconAnimationInvariant(tab));
|
| }
|
|
|