Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/tabs/tab.h" | 5 #include "chrome/browser/ui/views/tabs/tab.h" |
| 6 | 6 |
| 7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "chrome/browser/ui/views/tabs/tab_controller.h" | 8 #include "chrome/browser/ui/views/tabs/tab_controller.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "ui/base/models/list_selection_model.h" | 10 #include "ui/base/models/list_selection_model.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 | 26 |
| 27 virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE { | 27 virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE { |
| 28 return selection_model_; | 28 return selection_model_; |
| 29 } | 29 } |
| 30 virtual bool SupportsMultipleSelection() OVERRIDE { return false; } | 30 virtual bool SupportsMultipleSelection() OVERRIDE { return false; } |
| 31 virtual void SelectTab(Tab* tab) OVERRIDE {} | 31 virtual void SelectTab(Tab* tab) OVERRIDE {} |
| 32 virtual void ExtendSelectionTo(Tab* tab) OVERRIDE {} | 32 virtual void ExtendSelectionTo(Tab* tab) OVERRIDE {} |
| 33 virtual void ToggleSelected(Tab* tab) OVERRIDE {} | 33 virtual void ToggleSelected(Tab* tab) OVERRIDE {} |
| 34 virtual void AddSelectionFromAnchorTo(Tab* tab) OVERRIDE {} | 34 virtual void AddSelectionFromAnchorTo(Tab* tab) OVERRIDE {} |
| 35 virtual void CloseTab(Tab* tab, CloseTabSource source) OVERRIDE {} | 35 virtual void CloseTab(Tab* tab, CloseTabSource source) OVERRIDE {} |
| 36 virtual void ToggleTabAudioMute(Tab* tab) OVERRIDE {} | |
| 36 virtual void ShowContextMenuForTab(Tab* tab, | 37 virtual void ShowContextMenuForTab(Tab* tab, |
| 37 const gfx::Point& p, | 38 const gfx::Point& p, |
| 38 ui::MenuSourceType source_type) OVERRIDE {} | 39 ui::MenuSourceType source_type) OVERRIDE {} |
| 39 virtual bool IsActiveTab(const Tab* tab) const OVERRIDE { | 40 virtual bool IsActiveTab(const Tab* tab) const OVERRIDE { |
| 40 return active_tab_; | 41 return active_tab_; |
| 41 } | 42 } |
| 42 virtual bool IsTabSelected(const Tab* tab) const OVERRIDE { | 43 virtual bool IsTabSelected(const Tab* tab) const OVERRIDE { |
| 43 return false; | 44 return false; |
| 44 } | 45 } |
| 45 virtual bool IsTabPinned(const Tab* tab) const OVERRIDE { return false; } | 46 virtual bool IsTabPinned(const Tab* tab) const OVERRIDE { return false; } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 69 bool active_tab_; | 70 bool active_tab_; |
| 70 | 71 |
| 71 DISALLOW_COPY_AND_ASSIGN(FakeTabController); | 72 DISALLOW_COPY_AND_ASSIGN(FakeTabController); |
| 72 }; | 73 }; |
| 73 | 74 |
| 74 class TabTest : public views::ViewsTestBase { | 75 class TabTest : public views::ViewsTestBase { |
| 75 public: | 76 public: |
| 76 TabTest() {} | 77 TabTest() {} |
| 77 virtual ~TabTest() {} | 78 virtual ~TabTest() {} |
| 78 | 79 |
| 79 static void DisableMediaIndicatorAnimation(Tab* tab) { | |
| 80 tab->media_indicator_animation_.reset(); | |
| 81 tab->animating_media_state_ = tab->data_.media_state; | |
| 82 } | |
| 83 | |
| 84 static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) { | 80 static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) { |
| 85 // Check whether elements are visible when they are supposed to be, given | 81 // Check whether elements are visible when they are supposed to be, given |
| 86 // Tab size and TabRendererData state. | 82 // Tab size and TabRendererData state. |
| 87 if (tab.data_.mini) { | 83 if (tab.data_.mini) { |
| 88 EXPECT_EQ(1, tab.IconCapacity()); | 84 EXPECT_EQ(1, tab.IconCapacity()); |
| 89 if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { | 85 if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |
| 90 EXPECT_FALSE(tab.ShouldShowIcon()); | 86 EXPECT_FALSE(tab.ShouldShowIcon()); |
| 91 EXPECT_TRUE(tab.ShouldShowMediaIndicator()); | 87 EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
| 92 } else { | 88 } else { |
| 93 EXPECT_TRUE(tab.ShouldShowIcon()); | 89 EXPECT_TRUE(tab.ShouldShowIcon()); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 // are fully within the contents bounds. | 148 // are fully within the contents bounds. |
| 153 const gfx::Rect contents_bounds = tab.GetContentsBounds(); | 149 const gfx::Rect contents_bounds = tab.GetContentsBounds(); |
| 154 if (tab.ShouldShowIcon()) { | 150 if (tab.ShouldShowIcon()) { |
| 155 EXPECT_LE(contents_bounds.x(), tab.favicon_bounds_.x()); | 151 EXPECT_LE(contents_bounds.x(), tab.favicon_bounds_.x()); |
| 156 if (tab.title_->width() > 0) | 152 if (tab.title_->width() > 0) |
| 157 EXPECT_LE(tab.favicon_bounds_.right(), tab.title_->x()); | 153 EXPECT_LE(tab.favicon_bounds_.right(), tab.title_->x()); |
| 158 EXPECT_LE(contents_bounds.y(), tab.favicon_bounds_.y()); | 154 EXPECT_LE(contents_bounds.y(), tab.favicon_bounds_.y()); |
| 159 EXPECT_LE(tab.favicon_bounds_.bottom(), contents_bounds.bottom()); | 155 EXPECT_LE(tab.favicon_bounds_.bottom(), contents_bounds.bottom()); |
| 160 } | 156 } |
| 161 if (tab.ShouldShowIcon() && tab.ShouldShowMediaIndicator()) | 157 if (tab.ShouldShowIcon() && tab.ShouldShowMediaIndicator()) |
| 162 EXPECT_LE(tab.favicon_bounds_.right(), tab.media_indicator_bounds_.x()); | 158 EXPECT_LE(tab.favicon_bounds_.right(), GetMediaIndicatorBounds(tab).x()); |
| 163 if (tab.ShouldShowMediaIndicator()) { | 159 if (tab.ShouldShowMediaIndicator()) { |
| 164 if (tab.title_->width() > 0) { | 160 if (tab.title_->width() > 0) { |
| 165 EXPECT_LE(tab.title_->bounds().right(), | 161 EXPECT_LE(tab.title_->bounds().right(), |
| 166 tab.media_indicator_bounds_.x()); | 162 GetMediaIndicatorBounds(tab).x()); |
| 167 } | 163 } |
| 168 EXPECT_LE(tab.media_indicator_bounds_.right(), contents_bounds.right()); | 164 EXPECT_LE(GetMediaIndicatorBounds(tab).right(), contents_bounds.right()); |
| 169 EXPECT_LE(contents_bounds.y(), tab.media_indicator_bounds_.y()); | 165 EXPECT_LE(contents_bounds.y(), GetMediaIndicatorBounds(tab).y()); |
| 170 EXPECT_LE(tab.media_indicator_bounds_.bottom(), contents_bounds.bottom()); | 166 EXPECT_LE(GetMediaIndicatorBounds(tab).bottom(), |
| 167 contents_bounds.bottom()); | |
| 171 } | 168 } |
| 172 if (tab.ShouldShowMediaIndicator() && tab.ShouldShowCloseBox()) { | 169 if (tab.ShouldShowMediaIndicator() && tab.ShouldShowCloseBox()) { |
| 173 // Note: The media indicator can overlap the left-insets of the close box, | 170 // Note: The media indicator can overlap the left-insets of the close box, |
| 174 // but should otherwise be to the left of the close button. | 171 // but should otherwise be to the left of the close button. |
| 175 EXPECT_LE(tab.media_indicator_bounds_.right(), | 172 EXPECT_LE(GetMediaIndicatorBounds(tab).right(), |
| 176 tab.close_button_->bounds().x() + | 173 tab.close_button_->bounds().x() + |
| 177 tab.close_button_->GetInsets().left()); | 174 tab.close_button_->GetInsets().left()); |
| 178 } | 175 } |
| 179 if (tab.ShouldShowCloseBox()) { | 176 if (tab.ShouldShowCloseBox()) { |
| 180 // Note: The title bounds can overlap the left-insets of the close box, | 177 // Note: The title bounds can overlap the left-insets of the close box, |
| 181 // but should otherwise be to the left of the close button. | 178 // but should otherwise be to the left of the close button. |
| 182 if (tab.title_->width() > 0) { | 179 if (tab.title_->width() > 0) { |
| 183 EXPECT_LE(tab.title_->bounds().right(), | 180 EXPECT_LE(tab.title_->bounds().right(), |
| 184 tab.close_button_->bounds().x() + | 181 tab.close_button_->bounds().x() + |
| 185 tab.close_button_->GetInsets().left()); | 182 tab.close_button_->GetInsets().left()); |
| 186 } | 183 } |
| 187 EXPECT_LE(tab.close_button_->bounds().right(), contents_bounds.right()); | 184 EXPECT_LE(tab.close_button_->bounds().right(), contents_bounds.right()); |
| 188 EXPECT_LE(contents_bounds.y(), tab.close_button_->bounds().y()); | 185 EXPECT_LE(contents_bounds.y(), tab.close_button_->bounds().y()); |
| 189 EXPECT_LE(tab.close_button_->bounds().bottom(), contents_bounds.bottom()); | 186 EXPECT_LE(tab.close_button_->bounds().bottom(), contents_bounds.bottom()); |
| 190 } | 187 } |
| 191 } | 188 } |
| 189 | |
| 190 private: | |
| 191 static const gfx::Rect& GetMediaIndicatorBounds(const Tab& tab) { | |
| 192 CHECK(tab.media_indicator_button_); | |
|
sky
2014/09/23 22:58:18
You should ADD_FAILURE here and early return.
miu
2014/09/24 22:34:16
Done.
| |
| 193 return reinterpret_cast<const views::View*>(tab.media_indicator_button_)-> | |
| 194 bounds(); | |
| 195 } | |
| 192 }; | 196 }; |
| 193 | 197 |
| 194 TEST_F(TabTest, HitTestTopPixel) { | 198 TEST_F(TabTest, HitTestTopPixel) { |
| 195 Widget widget; | 199 Widget widget; |
| 196 Widget::InitParams params(CreateParams(Widget::InitParams::TYPE_WINDOW)); | 200 Widget::InitParams params(CreateParams(Widget::InitParams::TYPE_WINDOW)); |
| 197 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 201 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 198 params.bounds.SetRect(10, 20, 300, 400); | 202 params.bounds.SetRect(10, 20, 300, 400); |
| 199 widget.Init(params); | 203 widget.Init(params); |
| 200 | 204 |
| 201 FakeTabController tab_controller; | 205 FakeTabController tab_controller; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 217 EXPECT_TRUE(tab.HitTestPoint(gfx::Point(middle_x, 0))); | 221 EXPECT_TRUE(tab.HitTestPoint(gfx::Point(middle_x, 0))); |
| 218 | 222 |
| 219 // But clicks in the area above the slanted sides should still miss. | 223 // But clicks in the area above the slanted sides should still miss. |
| 220 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, 0))); | 224 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, 0))); |
| 221 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(tab.width() - 1, 0))); | 225 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(tab.width() - 1, 0))); |
| 222 } | 226 } |
| 223 | 227 |
| 224 TEST_F(TabTest, LayoutAndVisibilityOfElements) { | 228 TEST_F(TabTest, LayoutAndVisibilityOfElements) { |
| 225 static const TabMediaState kMediaStatesToTest[] = { | 229 static const TabMediaState kMediaStatesToTest[] = { |
| 226 TAB_MEDIA_STATE_NONE, TAB_MEDIA_STATE_CAPTURING, | 230 TAB_MEDIA_STATE_NONE, TAB_MEDIA_STATE_CAPTURING, |
| 227 TAB_MEDIA_STATE_AUDIO_PLAYING | 231 TAB_MEDIA_STATE_AUDIO_PLAYING, TAB_MEDIA_STATE_AUDIO_MUTING |
| 228 }; | 232 }; |
| 229 | 233 |
| 230 FakeTabController controller; | 234 FakeTabController controller; |
| 231 Tab tab(&controller); | 235 Tab tab(&controller); |
| 232 | 236 |
| 233 SkBitmap bitmap; | 237 SkBitmap bitmap; |
| 234 bitmap.allocN32Pixels(16, 16); | 238 bitmap.allocN32Pixels(16, 16); |
| 235 TabRendererData data; | 239 TabRendererData data; |
| 236 data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); | 240 data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); |
| 237 | 241 |
| 238 // Perform layout over all possible combinations, checking for correct | 242 // Perform layout over all possible combinations, checking for correct |
| 239 // results. | 243 // results. |
| 240 for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) { | 244 for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) { |
| 241 for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) { | 245 for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) { |
| 242 for (size_t media_state_index = 0; | 246 for (size_t media_state_index = 0; |
| 243 media_state_index < arraysize(kMediaStatesToTest); | 247 media_state_index < arraysize(kMediaStatesToTest); |
| 244 ++media_state_index) { | 248 ++media_state_index) { |
| 245 const TabMediaState media_state = kMediaStatesToTest[media_state_index]; | 249 const TabMediaState media_state = kMediaStatesToTest[media_state_index]; |
| 246 SCOPED_TRACE(::testing::Message() | 250 SCOPED_TRACE(::testing::Message() |
| 247 << (is_active_tab ? "Active" : "Inactive") << ' ' | 251 << (is_active_tab ? "Active" : "Inactive") << ' ' |
| 248 << (is_mini_tab ? "Mini " : "") | 252 << (is_mini_tab ? "Mini " : "") |
| 249 << "Tab with media indicator state " << media_state); | 253 << "Tab with media indicator state " << media_state); |
| 250 | 254 |
| 251 data.mini = !!is_mini_tab; | 255 data.mini = !!is_mini_tab; |
| 252 controller.set_active_tab(!!is_active_tab); | 256 controller.set_active_tab(!!is_active_tab); |
| 253 data.media_state = media_state; | 257 data.media_state = media_state; |
| 254 tab.SetData(data); | 258 tab.SetData(data); |
| 255 | 259 |
| 256 // Disable the media indicator animation so that the layout/visibility | |
| 257 // logic can be tested effectively. If the animation was left enabled, | |
| 258 // the ShouldShowMediaIndicator() method would return true during | |
| 259 // fade-out transitions. | |
| 260 DisableMediaIndicatorAnimation(&tab); | |
| 261 | |
| 262 // Test layout for every width from standard to minimum. | 260 // Test layout for every width from standard to minimum. |
| 263 gfx::Rect bounds(gfx::Point(0, 0), Tab::GetStandardSize()); | 261 gfx::Rect bounds(gfx::Point(0, 0), Tab::GetStandardSize()); |
| 264 int min_width; | 262 int min_width; |
| 265 if (is_mini_tab) { | 263 if (is_mini_tab) { |
| 266 bounds.set_width(Tab::GetMiniWidth()); | 264 bounds.set_width(Tab::GetMiniWidth()); |
| 267 min_width = Tab::GetMiniWidth(); | 265 min_width = Tab::GetMiniWidth(); |
| 268 } else { | 266 } else { |
| 269 min_width = is_active_tab ? Tab::GetMinimumSelectedSize().width() : | 267 min_width = is_active_tab ? Tab::GetMinimumSelectedSize().width() : |
| 270 Tab::GetMinimumUnselectedSize().width(); | 268 Tab::GetMinimumUnselectedSize().width(); |
| 271 } | 269 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 291 tab.Layout(); | 289 tab.Layout(); |
| 292 gfx::Insets close_button_insets_2 = tab.close_button_->GetInsets(); | 290 gfx::Insets close_button_insets_2 = tab.close_button_->GetInsets(); |
| 293 EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top()); | 291 EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top()); |
| 294 EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left()); | 292 EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left()); |
| 295 EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom()); | 293 EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom()); |
| 296 EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right()); | 294 EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right()); |
| 297 | 295 |
| 298 // Also make sure the close button is sized as large as the tab. | 296 // Also make sure the close button is sized as large as the tab. |
| 299 EXPECT_EQ(50, tab.close_button_->bounds().height()); | 297 EXPECT_EQ(50, tab.close_button_->bounds().height()); |
| 300 } | 298 } |
| OLD | NEW |