browser_view_layout_unittest.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/views/frame/browser_view_layout.h"
6
7#include "chrome/browser/ui/views/frame/browser_view.h"
8#include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h"
9#include "chrome/browser/ui/views/frame/contents_container.h"
10#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
11#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
12#include "chrome/browser/ui/views/tabs/tab_strip.h"
13#include "chrome/test/base/browser_with_test_window_test.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16class MockBrowserViewLayoutDelegate : public BrowserViewLayoutDelegate {
17 public:
18  MockBrowserViewLayoutDelegate()
19      : tab_strip_visible_(true),
20        toolbar_visible_(true),
21        bookmark_bar_visible_(true),
22        download_shelf_needs_layout_(false) {
23  }
24  virtual ~MockBrowserViewLayoutDelegate() {}
25
26  void set_download_shelf_needs_layout(bool layout) {
27    download_shelf_needs_layout_ = layout;
28  }
29  void set_tab_strip_visible(bool visible) {
30    tab_strip_visible_ = visible;
31  }
32  void set_toolbar_visible(bool visible) {
33    toolbar_visible_ = visible;
34  }
35  void set_bookmark_bar_visible(bool visible) {
36    bookmark_bar_visible_ = visible;
37  }
38
39  // BrowserViewLayout::Delegate overrides:
40  virtual views::View* GetWindowSwitcherButton() const OVERRIDE {
41    // TODO(jamescook): Add a test for Windows that exercises the layout for
42    // this button.
43    return NULL;
44  }
45  virtual bool IsTabStripVisible() const OVERRIDE {
46    return tab_strip_visible_;
47  }
48  virtual gfx::Rect GetBoundsForTabStrip(views::View* tab_strip) const
49      OVERRIDE {
50    return gfx::Rect();
51  }
52  virtual bool IsToolbarVisible() const OVERRIDE {
53    return toolbar_visible_;
54  }
55  virtual bool IsBookmarkBarVisible() const OVERRIDE {
56    return bookmark_bar_visible_;
57  }
58  virtual bool DownloadShelfNeedsLayout() const OVERRIDE {
59    return download_shelf_needs_layout_;
60  }
61
62  virtual FullscreenExitBubbleViews* GetFullscreenExitBubble() const OVERRIDE {
63    return NULL;
64  }
65
66 private:
67  bool tab_strip_visible_;
68  bool toolbar_visible_;
69  bool bookmark_bar_visible_;
70  bool download_shelf_needs_layout_;
71
72  DISALLOW_COPY_AND_ASSIGN(MockBrowserViewLayoutDelegate);
73};
74
75///////////////////////////////////////////////////////////////////////////////
76
77// A simple view that prefers an initial size.
78class MockView : public views::View {
79 public:
80  explicit MockView(gfx::Size initial_size)
81      : size_(initial_size) {
82    SetBoundsRect(gfx::Rect(gfx::Point(), size_));
83  }
84  virtual ~MockView() {}
85
86  // views::View overrides:
87  virtual gfx::Size GetPreferredSize() OVERRIDE {
88    return size_;
89  }
90
91 private:
92  gfx::Size size_;
93
94  DISALLOW_COPY_AND_ASSIGN(MockView);
95};
96
97///////////////////////////////////////////////////////////////////////////////
98
99class MockImmersiveModeController : public ImmersiveModeController {
100 public:
101  MockImmersiveModeController() {}
102  virtual ~MockImmersiveModeController() {}
103
104  // ImmersiveModeController overrides:
105  virtual void Init(Delegate* delegate,
106                    views::Widget* widget,
107                    views::View* top_container) OVERRIDE {}
108  virtual void SetEnabled(bool enabled) OVERRIDE {}
109  virtual bool IsEnabled() const OVERRIDE { return false; }
110  virtual bool ShouldHideTabIndicators() const OVERRIDE { return false; }
111  virtual bool ShouldHideTopViews() const OVERRIDE { return false; }
112  virtual bool IsRevealed() const OVERRIDE { return false; }
113  virtual int GetTopContainerVerticalOffset(
114      const gfx::Size& top_container_size) const OVERRIDE { return 0; }
115  virtual ImmersiveRevealedLock* GetRevealedLock(
116      AnimateReveal animate_reveal) OVERRIDE WARN_UNUSED_RESULT { return NULL; }
117  virtual void OnFindBarVisibleBoundsChanged(
118      const gfx::Rect& new_visible_bounds) OVERRIDE {}
119  virtual void SetupForTest() OVERRIDE {}
120
121 private:
122  DISALLOW_COPY_AND_ASSIGN(MockImmersiveModeController);
123};
124
125///////////////////////////////////////////////////////////////////////////////
126// Tests of BrowserViewLayout. Runs tests without constructing a BrowserView.
127class BrowserViewLayoutTest : public BrowserWithTestWindowTest {
128 public:
129  BrowserViewLayoutTest()
130      : delegate_(NULL),
131        top_container_(NULL),
132        tab_strip_(NULL),
133        toolbar_(NULL),
134        infobar_container_(NULL),
135        contents_split_(NULL),
136        contents_container_(NULL),
137        active_web_view_(NULL) {}
138  virtual ~BrowserViewLayoutTest() {}
139
140  BrowserViewLayout* layout() { return layout_.get(); }
141  MockBrowserViewLayoutDelegate* delegate() { return delegate_; }
142  MockView* root_view() { return root_view_.get(); }
143  MockView* top_container() { return top_container_; }
144  TabStrip* tab_strip() { return tab_strip_; }
145  MockView* toolbar() { return toolbar_; }
146  InfoBarContainerView* infobar_container() { return infobar_container_; }
147  MockView* contents_split() { return contents_split_; }
148  ContentsContainer* contents_container() { return contents_container_; }
149
150  // BrowserWithTestWindowTest overrides:
151  virtual void SetUp() OVERRIDE {
152    BrowserWithTestWindowTest::SetUp();
153
154    root_view_.reset(new MockView(gfx::Size(800, 600)));
155
156    immersive_mode_controller_.reset(new MockImmersiveModeController);
157
158    top_container_ = new MockView(gfx::Size(800, 60));
159    tab_strip_ = new TabStrip(NULL);
160    top_container_->AddChildView(tab_strip_);
161    toolbar_ = new MockView(gfx::Size(800, 30));
162    top_container_->AddChildView(toolbar_);
163    root_view_->AddChildView(top_container_);
164
165    infobar_container_ = new InfoBarContainerView(NULL);
166    root_view_->AddChildView(infobar_container_);
167
168    contents_split_ = new MockView(gfx::Size(800, 600));
169    active_web_view_ = new MockView(gfx::Size(800, 600));
170    contents_container_ = new ContentsContainer(active_web_view_);
171    contents_split_->AddChildView(contents_container_);
172    root_view_->AddChildView(contents_split_);
173
174    // TODO(jamescook): Attach |layout_| to |root_view_|?
175    layout_.reset(new BrowserViewLayout);
176    delegate_ = new MockBrowserViewLayoutDelegate;
177    layout_->Init(delegate_,
178                  browser(),
179                  NULL,  // BrowserView.
180                  top_container_,
181                  tab_strip_,
182                  toolbar_,
183                  infobar_container_,
184                  contents_split_,
185                  contents_container_,
186                  immersive_mode_controller_.get());
187  }
188
189 private:
190  scoped_ptr<BrowserViewLayout> layout_;
191  MockBrowserViewLayoutDelegate* delegate_;  // Owned by |layout_|.
192  scoped_ptr<MockView> root_view_;
193
194  // Views owned by |root_view_|.
195  MockView* top_container_;
196  TabStrip* tab_strip_;
197  MockView* toolbar_;
198  InfoBarContainerView* infobar_container_;
199  MockView* contents_split_;
200  ContentsContainer* contents_container_;
201  MockView* active_web_view_;
202
203  scoped_ptr<MockImmersiveModeController> immersive_mode_controller_;
204
205  DISALLOW_COPY_AND_ASSIGN(BrowserViewLayoutTest);
206};
207
208// Test basic construction and initialization.
209TEST_F(BrowserViewLayoutTest, BrowserViewLayout) {
210  EXPECT_TRUE(layout()->browser());
211  EXPECT_TRUE(layout()->GetWebContentsModalDialogHost());
212  EXPECT_FALSE(layout()->InfobarVisible());
213}
214
215// Test the core layout functions.
216TEST_F(BrowserViewLayoutTest, Layout) {
217  // Simulate a window with no interesting UI.
218  delegate()->set_tab_strip_visible(false);
219  delegate()->set_toolbar_visible(false);
220  delegate()->set_bookmark_bar_visible(false);
221  layout()->Layout(root_view());
222
223  // Top views are zero-height.
224  EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
225  EXPECT_EQ("0,0 800x0", toolbar()->bounds().ToString());
226  EXPECT_EQ("0,0 800x0", infobar_container()->bounds().ToString());
227  // Contents split fills the window.
228  EXPECT_EQ("0,0 800x600", contents_split()->bounds().ToString());
229
230  // Turn on the toolbar, like in a pop-up window.
231  delegate()->set_toolbar_visible(true);
232  layout()->Layout(root_view());
233
234  // Now the toolbar has bounds and other views shift down.
235  EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
236  EXPECT_EQ("0,0 800x30", toolbar()->bounds().ToString());
237  EXPECT_EQ("0,30 800x0", infobar_container()->bounds().ToString());
238  EXPECT_EQ("0,30 800x570", contents_split()->bounds().ToString());
239
240  // TODO(jamescook): Tab strip and bookmark bar.
241}
242
243TEST_F(BrowserViewLayoutTest, LayoutDownloadShelf) {
244  scoped_ptr<MockView> download_shelf(new MockView(gfx::Size(800, 50)));
245  layout()->set_download_shelf(download_shelf.get());
246
247  // If download shelf doesn't need layout, it doesn't move the bottom edge.
248  delegate()->set_download_shelf_needs_layout(false);
249  const int kBottom = 500;
250  EXPECT_EQ(kBottom, layout()->LayoutDownloadShelf(kBottom));
251
252  // Download shelf layout moves up the bottom edge and sets visibility.
253  delegate()->set_download_shelf_needs_layout(true);
254  download_shelf->SetVisible(false);
255  EXPECT_EQ(450, layout()->LayoutDownloadShelf(kBottom));
256  EXPECT_TRUE(download_shelf->visible());
257  EXPECT_EQ("0,450 0x50", download_shelf->bounds().ToString());
258}
259