Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / views / layout / box_layout_unittest.cc
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
3 // found in the LICENSE file.
4
5 #include "ui/views/layout/box_layout.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/views/test/test_views.h"
9 #include "ui/views/view.h"
10
11 namespace views {
12
13 namespace {
14
15 class BoxLayoutTest : public testing::Test {
16  public:
17   virtual void SetUp() OVERRIDE {
18     host_.reset(new View);
19   }
20
21   scoped_ptr<View> host_;
22 };
23
24 }  // namespace
25
26 TEST_F(BoxLayoutTest, Empty) {
27   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 10, 10, 20);
28   host_->SetLayoutManager(layout);
29   EXPECT_EQ(gfx::Size(20, 20), layout->GetPreferredSize(host_.get()));
30 }
31
32 TEST_F(BoxLayoutTest, AlignmentHorizontal) {
33   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 0, 0, 0);
34   host_->SetLayoutManager(layout);
35   View* v1 = new StaticSizedView(gfx::Size(10, 20));
36   host_->AddChildView(v1);
37   View* v2 = new StaticSizedView(gfx::Size(10, 10));
38   host_->AddChildView(v2);
39   EXPECT_EQ(gfx::Size(20, 20), layout->GetPreferredSize(host_.get()));
40   host_->SetBounds(0, 0, 20, 20);
41   host_->Layout();
42   EXPECT_EQ(gfx::Rect(0, 0, 10, 20), v1->bounds());
43   EXPECT_EQ(gfx::Rect(10, 0, 10, 20), v2->bounds());
44 }
45
46 TEST_F(BoxLayoutTest, AlignmentVertical) {
47   BoxLayout* layout = new BoxLayout(BoxLayout::kVertical, 0, 0, 0);
48   host_->SetLayoutManager(layout);
49   View* v1 = new StaticSizedView(gfx::Size(20, 10));
50   host_->AddChildView(v1);
51   View* v2 = new StaticSizedView(gfx::Size(10, 10));
52   host_->AddChildView(v2);
53   EXPECT_EQ(gfx::Size(20, 20), layout->GetPreferredSize(host_.get()));
54   host_->SetBounds(0, 0, 20, 20);
55   host_->Layout();
56   EXPECT_EQ(gfx::Rect(0, 0, 20, 10), v1->bounds());
57   EXPECT_EQ(gfx::Rect(0, 10, 20, 10), v2->bounds());
58 }
59
60 TEST_F(BoxLayoutTest, SetInsideBorderInsets) {
61   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 10, 20, 0);
62   host_->SetLayoutManager(layout);
63   View* v1 = new StaticSizedView(gfx::Size(10, 20));
64   host_->AddChildView(v1);
65   View* v2 = new StaticSizedView(gfx::Size(10, 10));
66   host_->AddChildView(v2);
67   EXPECT_EQ(gfx::Size(40, 60), layout->GetPreferredSize(host_.get()));
68   host_->SetBounds(0, 0, 40, 60);
69   host_->Layout();
70   EXPECT_EQ(gfx::Rect(10, 20, 10, 20), v1->bounds());
71   EXPECT_EQ(gfx::Rect(20, 20, 10, 20), v2->bounds());
72
73   layout->set_inside_border_insets(
74       gfx::Insets(5, 10, 15, 20));
75   EXPECT_EQ(gfx::Size(50, 40), layout->GetPreferredSize(host_.get()));
76   host_->SetBounds(0, 0, 50, 40);
77   host_->Layout();
78   EXPECT_EQ(gfx::Rect(10, 5, 10, 20), v1->bounds());
79   EXPECT_EQ(gfx::Rect(20, 5, 10, 20), v2->bounds());
80 }
81
82 TEST_F(BoxLayoutTest, Spacing) {
83   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 7, 7, 8);
84   host_->SetLayoutManager(layout);
85   View* v1 = new StaticSizedView(gfx::Size(10, 20));
86   host_->AddChildView(v1);
87   View* v2 = new StaticSizedView(gfx::Size(10, 20));
88   host_->AddChildView(v2);
89   EXPECT_EQ(gfx::Size(42, 34), layout->GetPreferredSize(host_.get()));
90   host_->SetBounds(0, 0, 100, 100);
91   host_->Layout();
92   EXPECT_EQ(gfx::Rect(7, 7, 10, 86), v1->bounds());
93   EXPECT_EQ(gfx::Rect(25, 7, 10, 86), v2->bounds());
94 }
95
96 TEST_F(BoxLayoutTest, Overflow) {
97   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 0, 0, 0);
98   host_->SetLayoutManager(layout);
99   View* v1 = new StaticSizedView(gfx::Size(20, 20));
100   host_->AddChildView(v1);
101   View* v2 = new StaticSizedView(gfx::Size(10, 20));
102   host_->AddChildView(v2);
103   host_->SetBounds(0, 0, 10, 10);
104
105   // Overflows by positioning views at the start and truncating anything that
106   // doesn't fit.
107   host_->Layout();
108   EXPECT_EQ(gfx::Rect(0, 0, 10, 10), v1->bounds());
109   EXPECT_EQ(gfx::Rect(0, 0, 0, 0), v2->bounds());
110
111   // All values of main axis alignment should overflow in the same manner.
112   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_START);
113   host_->Layout();
114   EXPECT_EQ(gfx::Rect(0, 0, 10, 10), v1->bounds());
115   EXPECT_EQ(gfx::Rect(0, 0, 0, 0), v2->bounds());
116
117   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
118   host_->Layout();
119   EXPECT_EQ(gfx::Rect(0, 0, 10, 10), v1->bounds());
120   EXPECT_EQ(gfx::Rect(0, 0, 0, 0), v2->bounds());
121
122   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_END);
123   host_->Layout();
124   EXPECT_EQ(gfx::Rect(0, 0, 10, 10), v1->bounds());
125   EXPECT_EQ(gfx::Rect(0, 0, 0, 0), v2->bounds());
126 }
127
128 TEST_F(BoxLayoutTest, NoSpace) {
129   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 10, 10, 10);
130   host_->SetLayoutManager(layout);
131   View* childView = new StaticSizedView(gfx::Size(20, 20));
132   host_->AddChildView(childView);
133   host_->SetBounds(0, 0, 10, 10);
134   host_->Layout();
135   EXPECT_EQ(gfx::Rect(0, 0, 0, 0), childView->bounds());
136 }
137
138 TEST_F(BoxLayoutTest, InvisibleChild) {
139   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 10, 10, 10);
140   host_->SetLayoutManager(layout);
141   View* v1 = new StaticSizedView(gfx::Size(20, 20));
142   v1->SetVisible(false);
143   host_->AddChildView(v1);
144   View* v2 = new StaticSizedView(gfx::Size(10, 10));
145   host_->AddChildView(v2);
146   EXPECT_EQ(gfx::Size(30, 30), layout->GetPreferredSize(host_.get()));
147   host_->SetBounds(0, 0, 30, 30);
148   host_->Layout();
149   EXPECT_EQ(gfx::Rect(10, 10, 10, 10), v2->bounds());
150 }
151
152 TEST_F(BoxLayoutTest, UseHeightForWidth) {
153   BoxLayout* layout = new BoxLayout(BoxLayout::kVertical, 0, 0, 0);
154   host_->SetLayoutManager(layout);
155   View* v1 = new StaticSizedView(gfx::Size(20, 10));
156   host_->AddChildView(v1);
157   ProportionallySizedView* v2 = new ProportionallySizedView(2);
158   v2->set_preferred_width(10);
159   host_->AddChildView(v2);
160   EXPECT_EQ(gfx::Size(20, 50), layout->GetPreferredSize(host_.get()));
161
162   host_->SetBounds(0, 0, 20, 50);
163   host_->Layout();
164   EXPECT_EQ(gfx::Rect(0, 0, 20, 10), v1->bounds());
165   EXPECT_EQ(gfx::Rect(0, 10, 20, 40), v2->bounds());
166
167   EXPECT_EQ(110, layout->GetPreferredHeightForWidth(host_.get(), 50));
168
169   // Test without horizontal stretching of the views.
170   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_END);
171   EXPECT_EQ(gfx::Size(20, 30).ToString(),
172             layout->GetPreferredSize(host_.get()).ToString());
173
174   host_->SetBounds(0, 0, 20, 30);
175   host_->Layout();
176   EXPECT_EQ(gfx::Rect(0, 0, 20, 10), v1->bounds());
177   EXPECT_EQ(gfx::Rect(10, 10, 10, 20), v2->bounds());
178
179   EXPECT_EQ(30, layout->GetPreferredHeightForWidth(host_.get(), 50));
180 }
181
182 TEST_F(BoxLayoutTest, EmptyPreferredSize) {
183   for (size_t i = 0; i < 2; i++) {
184     BoxLayout::Orientation orientation = i == 0 ? BoxLayout::kHorizontal :
185                                                   BoxLayout::kVertical;
186     host_->RemoveAllChildViews(true);
187     host_->SetLayoutManager(new BoxLayout(orientation, 0, 0, 5));
188     View* v1 = new StaticSizedView(gfx::Size());
189     host_->AddChildView(v1);
190     View* v2 = new StaticSizedView(gfx::Size(10, 10));
191     host_->AddChildView(v2);
192     host_->SizeToPreferredSize();
193     host_->Layout();
194
195     EXPECT_EQ(v2->GetPreferredSize().width(), host_->bounds().width()) << i;
196     EXPECT_EQ(v2->GetPreferredSize().height(), host_->bounds().height()) << i;
197     EXPECT_EQ(v1->GetPreferredSize().width(), v1->bounds().width()) << i;
198     EXPECT_EQ(v1->GetPreferredSize().height(), v1->bounds().height()) << i;
199     EXPECT_EQ(v2->GetPreferredSize().width(), v2->bounds().width()) << i;
200     EXPECT_EQ(v2->GetPreferredSize().height(), v2->bounds().height()) << i;
201   }
202 }
203
204 TEST_F(BoxLayoutTest, MainAxisAlignmentHorizontal) {
205   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 10, 10, 10);
206   host_->SetLayoutManager(layout);
207
208   View* v1 = new StaticSizedView(gfx::Size(20, 20));
209   host_->AddChildView(v1);
210   View* v2 = new StaticSizedView(gfx::Size(10, 10));
211   host_->AddChildView(v2);
212
213   host_->SetBounds(0, 0, 100, 40);
214
215   // Align children to the horizontal start by default.
216   host_->Layout();
217   EXPECT_EQ(gfx::Rect(10, 10, 20, 20).ToString(), v1->bounds().ToString());
218   EXPECT_EQ(gfx::Rect(40, 10, 10, 20).ToString(), v2->bounds().ToString());
219
220   // Ensure same results for MAIN_AXIS_ALIGNMENT_START.
221   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_START);
222   host_->Layout();
223   EXPECT_EQ(gfx::Rect(10, 10, 20, 20).ToString(), v1->bounds().ToString());
224   EXPECT_EQ(gfx::Rect(40, 10, 10, 20).ToString(), v2->bounds().ToString());
225
226   // Aligns children to the center horizontally.
227   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
228   host_->Layout();
229   EXPECT_EQ(gfx::Rect(30, 10, 20, 20).ToString(), v1->bounds().ToString());
230   EXPECT_EQ(gfx::Rect(60, 10, 10, 20).ToString(), v2->bounds().ToString());
231
232   // Aligns children to the end of the host horizontally, accounting for the
233   // inside border spacing.
234   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_END);
235   host_->Layout();
236   EXPECT_EQ(gfx::Rect(50, 10, 20, 20).ToString(), v1->bounds().ToString());
237   EXPECT_EQ(gfx::Rect(80, 10, 10, 20).ToString(), v2->bounds().ToString());
238 }
239
240 TEST_F(BoxLayoutTest, MainAxisAlignmentVertical) {
241   BoxLayout* layout = new BoxLayout(BoxLayout::kVertical, 10, 10, 10);
242   host_->SetLayoutManager(layout);
243
244   View* v1 = new StaticSizedView(gfx::Size(20, 20));
245   host_->AddChildView(v1);
246   View* v2 = new StaticSizedView(gfx::Size(10, 10));
247   host_->AddChildView(v2);
248
249   host_->SetBounds(0, 0, 40, 100);
250
251   // Align children to the vertical start by default.
252   host_->Layout();
253   EXPECT_EQ(gfx::Rect(10, 10, 20, 20).ToString(), v1->bounds().ToString());
254   EXPECT_EQ(gfx::Rect(10, 40, 20, 10).ToString(), v2->bounds().ToString());
255
256   // Ensure same results for MAIN_AXIS_ALIGNMENT_START.
257   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_START);
258   host_->Layout();
259   EXPECT_EQ(gfx::Rect(10, 10, 20, 20).ToString(), v1->bounds().ToString());
260   EXPECT_EQ(gfx::Rect(10, 40, 20, 10).ToString(), v2->bounds().ToString());
261
262   // Aligns children to the center vertically.
263   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
264   host_->Layout();
265   EXPECT_EQ(gfx::Rect(10, 30, 20, 20).ToString(), v1->bounds().ToString());
266   EXPECT_EQ(gfx::Rect(10, 60, 20, 10).ToString(), v2->bounds().ToString());
267
268   // Aligns children to the end of the host vertically, accounting for the
269   // inside border spacing.
270   layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_END);
271   host_->Layout();
272   EXPECT_EQ(gfx::Rect(10, 50, 20, 20).ToString(), v1->bounds().ToString());
273   EXPECT_EQ(gfx::Rect(10, 80, 20, 10).ToString(), v2->bounds().ToString());
274 }
275
276 TEST_F(BoxLayoutTest, CrossAxisAlignmentHorizontal) {
277   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 10, 10, 10);
278   host_->SetLayoutManager(layout);
279
280   View* v1 = new StaticSizedView(gfx::Size(20, 20));
281   host_->AddChildView(v1);
282   View* v2 = new StaticSizedView(gfx::Size(10, 10));
283   host_->AddChildView(v2);
284
285   host_->SetBounds(0, 0, 100, 60);
286
287   // Stretch children to fill the available height by default.
288   host_->Layout();
289   EXPECT_EQ(gfx::Rect(10, 10, 20, 40).ToString(), v1->bounds().ToString());
290   EXPECT_EQ(gfx::Rect(40, 10, 10, 40).ToString(), v2->bounds().ToString());
291
292   // Ensure same results for CROSS_AXIS_ALIGNMENT_STRETCH.
293   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
294   host_->Layout();
295   EXPECT_EQ(gfx::Rect(10, 10, 20, 40).ToString(), v1->bounds().ToString());
296   EXPECT_EQ(gfx::Rect(40, 10, 10, 40).ToString(), v2->bounds().ToString());
297
298   // Aligns children to the start vertically.
299   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_START);
300   host_->Layout();
301   EXPECT_EQ(gfx::Rect(10, 10, 20, 20).ToString(), v1->bounds().ToString());
302   EXPECT_EQ(gfx::Rect(40, 10, 10, 10).ToString(), v2->bounds().ToString());
303
304   // Aligns children to the center vertically.
305   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
306   host_->Layout();
307   EXPECT_EQ(gfx::Rect(10, 20, 20, 20).ToString(), v1->bounds().ToString());
308   EXPECT_EQ(gfx::Rect(40, 25, 10, 10).ToString(), v2->bounds().ToString());
309
310   // Aligns children to the end of the host vertically, accounting for the
311   // inside border spacing.
312   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_END);
313   host_->Layout();
314   EXPECT_EQ(gfx::Rect(10, 30, 20, 20).ToString(), v1->bounds().ToString());
315   EXPECT_EQ(gfx::Rect(40, 40, 10, 10).ToString(), v2->bounds().ToString());
316 }
317
318 TEST_F(BoxLayoutTest, CrossAxisAlignmentVertical) {
319   BoxLayout* layout = new BoxLayout(BoxLayout::kVertical, 10, 10, 10);
320   host_->SetLayoutManager(layout);
321
322   View* v1 = new StaticSizedView(gfx::Size(20, 20));
323   host_->AddChildView(v1);
324   View* v2 = new StaticSizedView(gfx::Size(10, 10));
325   host_->AddChildView(v2);
326
327   host_->SetBounds(0, 0, 60, 100);
328
329   // Stretch children to fill the available width by default.
330   host_->Layout();
331   EXPECT_EQ(gfx::Rect(10, 10, 40, 20).ToString(), v1->bounds().ToString());
332   EXPECT_EQ(gfx::Rect(10, 40, 40, 10).ToString(), v2->bounds().ToString());
333
334   // Ensure same results for CROSS_AXIS_ALIGNMENT_STRETCH.
335   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
336   host_->Layout();
337   EXPECT_EQ(gfx::Rect(10, 10, 40, 20).ToString(), v1->bounds().ToString());
338   EXPECT_EQ(gfx::Rect(10, 40, 40, 10).ToString(), v2->bounds().ToString());
339
340   // Aligns children to the start horizontally.
341   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_START);
342   host_->Layout();
343   EXPECT_EQ(gfx::Rect(10, 10, 20, 20).ToString(), v1->bounds().ToString());
344   EXPECT_EQ(gfx::Rect(10, 40, 10, 10).ToString(), v2->bounds().ToString());
345
346   // Aligns children to the center horizontally.
347   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
348   host_->Layout();
349   EXPECT_EQ(gfx::Rect(20, 10, 20, 20).ToString(), v1->bounds().ToString());
350   EXPECT_EQ(gfx::Rect(25, 40, 10, 10).ToString(), v2->bounds().ToString());
351
352   // Aligns children to the end of the host horizontally, accounting for the
353   // inside border spacing.
354   layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_END);
355   host_->Layout();
356   EXPECT_EQ(gfx::Rect(30, 10, 20, 20).ToString(), v1->bounds().ToString());
357   EXPECT_EQ(gfx::Rect(40, 40, 10, 10).ToString(), v2->bounds().ToString());
358 }
359
360 TEST_F(BoxLayoutTest, FlexAll) {
361   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 10, 10, 10);
362   host_->SetLayoutManager(layout);
363   layout->SetDefaultFlex(1);
364
365   View* v1 = new StaticSizedView(gfx::Size(20, 20));
366   host_->AddChildView(v1);
367   View* v2 = new StaticSizedView(gfx::Size(10, 10));
368   host_->AddChildView(v2);
369   View* v3 = new StaticSizedView(gfx::Size(30, 30));
370   host_->AddChildView(v3);
371   EXPECT_EQ(gfx::Size(100, 50), layout->GetPreferredSize(host_.get()));
372
373   host_->SetBounds(0, 0, 120, 50);
374   host_->Layout();
375   EXPECT_EQ(gfx::Rect(10, 10, 27, 30).ToString(), v1->bounds().ToString());
376   EXPECT_EQ(gfx::Rect(47, 10, 16, 30).ToString(), v2->bounds().ToString());
377   EXPECT_EQ(gfx::Rect(73, 10, 37, 30).ToString(), v3->bounds().ToString());
378 }
379
380 TEST_F(BoxLayoutTest, FlexGrowVertical) {
381   BoxLayout* layout = new BoxLayout(BoxLayout::kVertical, 10, 10, 10);
382   host_->SetLayoutManager(layout);
383
384   View* v1 = new StaticSizedView(gfx::Size(20, 20));
385   host_->AddChildView(v1);
386   View* v2 = new StaticSizedView(gfx::Size(10, 10));
387   host_->AddChildView(v2);
388   View* v3 = new StaticSizedView(gfx::Size(30, 30));
389   host_->AddChildView(v3);
390
391   host_->SetBounds(0, 0, 50, 130);
392
393   // Views don't fill the available space by default.
394   host_->Layout();
395   EXPECT_EQ(gfx::Rect(10, 10, 30, 20).ToString(), v1->bounds().ToString());
396   EXPECT_EQ(gfx::Rect(10, 40, 30, 10).ToString(), v2->bounds().ToString());
397   EXPECT_EQ(gfx::Rect(10, 60, 30, 30).ToString(), v3->bounds().ToString());
398
399   std::vector<BoxLayout::MainAxisAlignment> main_alignments;
400   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_START);
401   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
402   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_END);
403
404   for (size_t i = 0; i < main_alignments.size(); ++i) {
405     layout->set_main_axis_alignment(main_alignments[i]);
406
407     // Set the first view to consume all free space.
408     layout->SetFlexForView(v1, 1);
409     layout->ClearFlexForView(v2);
410     layout->ClearFlexForView(v3);
411     host_->Layout();
412     EXPECT_EQ(gfx::Rect(10, 10, 30, 50).ToString(), v1->bounds().ToString());
413     EXPECT_EQ(gfx::Rect(10, 70, 30, 10).ToString(), v2->bounds().ToString());
414     EXPECT_EQ(gfx::Rect(10, 90, 30, 30).ToString(), v3->bounds().ToString());
415
416     // Set the third view to take 2/3s of the free space and leave the first
417     // view
418     // with 1/3.
419     layout->SetFlexForView(v3, 2);
420     host_->Layout();
421     EXPECT_EQ(gfx::Rect(10, 10, 30, 30).ToString(), v1->bounds().ToString());
422     EXPECT_EQ(gfx::Rect(10, 50, 30, 10).ToString(), v2->bounds().ToString());
423     EXPECT_EQ(gfx::Rect(10, 70, 30, 50).ToString(), v3->bounds().ToString());
424
425     // Clear the previously set flex values and set the second view to take all
426     // the free space.
427     layout->ClearFlexForView(v1);
428     layout->SetFlexForView(v2, 1);
429     layout->ClearFlexForView(v3);
430     host_->Layout();
431     EXPECT_EQ(gfx::Rect(10, 10, 30, 20).ToString(), v1->bounds().ToString());
432     EXPECT_EQ(gfx::Rect(10, 40, 30, 40).ToString(), v2->bounds().ToString());
433     EXPECT_EQ(gfx::Rect(10, 90, 30, 30).ToString(), v3->bounds().ToString());
434   }
435 }
436
437 TEST_F(BoxLayoutTest, FlexGrowHorizontalWithRemainder) {
438   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 0, 0, 0);
439   host_->SetLayoutManager(layout);
440   layout->SetDefaultFlex(1);
441   std::vector<View*> views;
442   for (int i = 0; i < 5; ++i) {
443     View* view = new StaticSizedView(gfx::Size(10, 10));
444     views.push_back(view);
445     host_->AddChildView(view);
446   }
447
448   EXPECT_EQ(gfx::Size(50, 10), layout->GetPreferredSize(host_.get()));
449
450   host_->SetBounds(0, 0, 52, 10);
451   host_->Layout();
452   // The 2nd and 4th views should have an extra pixel as they correspond to 20.8
453   // and 41.6 which round up.
454   EXPECT_EQ(gfx::Rect(0, 0, 10, 10).ToString(), views[0]->bounds().ToString());
455   EXPECT_EQ(gfx::Rect(10, 0, 11, 10).ToString(), views[1]->bounds().ToString());
456   EXPECT_EQ(gfx::Rect(21, 0, 10, 10).ToString(), views[2]->bounds().ToString());
457   EXPECT_EQ(gfx::Rect(31, 0, 11, 10).ToString(), views[3]->bounds().ToString());
458   EXPECT_EQ(gfx::Rect(42, 0, 10, 10).ToString(), views[4]->bounds().ToString());
459 }
460
461 TEST_F(BoxLayoutTest, FlexGrowHorizontalWithRemainder2) {
462   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 0, 0, 0);
463   host_->SetLayoutManager(layout);
464   layout->SetDefaultFlex(1);
465   std::vector<View*> views;
466   for (int i = 0; i < 4; ++i) {
467     View* view = new StaticSizedView(gfx::Size(1, 10));
468     views.push_back(view);
469     host_->AddChildView(view);
470   }
471
472   EXPECT_EQ(gfx::Size(4, 10), layout->GetPreferredSize(host_.get()));
473
474   host_->SetBounds(0, 0, 10, 10);
475   host_->Layout();
476   // The 1st and 3rd views should have an extra pixel as they correspond to 2.5
477   // and 7.5 which round up.
478   EXPECT_EQ(gfx::Rect(0, 0, 3, 10).ToString(), views[0]->bounds().ToString());
479   EXPECT_EQ(gfx::Rect(3, 0, 2, 10).ToString(), views[1]->bounds().ToString());
480   EXPECT_EQ(gfx::Rect(5, 0, 3, 10).ToString(), views[2]->bounds().ToString());
481   EXPECT_EQ(gfx::Rect(8, 0, 2, 10).ToString(), views[3]->bounds().ToString());
482 }
483
484 TEST_F(BoxLayoutTest, FlexShrinkHorizontal) {
485   BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 10, 10, 10);
486   host_->SetLayoutManager(layout);
487
488   View* v1 = new StaticSizedView(gfx::Size(20, 20));
489   host_->AddChildView(v1);
490   View* v2 = new StaticSizedView(gfx::Size(10, 10));
491   host_->AddChildView(v2);
492   View* v3 = new StaticSizedView(gfx::Size(30, 30));
493   host_->AddChildView(v3);
494
495   host_->SetBounds(0, 0, 85, 50);
496
497   // Truncate width by default.
498   host_->Layout();
499   EXPECT_EQ(gfx::Rect(10, 10, 20, 30).ToString(), v1->bounds().ToString());
500   EXPECT_EQ(gfx::Rect(40, 10, 10, 30).ToString(), v2->bounds().ToString());
501   EXPECT_EQ(gfx::Rect(60, 10, 15, 30).ToString(), v3->bounds().ToString());
502
503   std::vector<BoxLayout::MainAxisAlignment> main_alignments;
504   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_START);
505   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
506   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_END);
507
508   for (size_t i = 0; i < main_alignments.size(); ++i) {
509     layout->set_main_axis_alignment(main_alignments[i]);
510
511     // Set the first view to shrink as much as necessary.
512     layout->SetFlexForView(v1, 1);
513     layout->ClearFlexForView(v2);
514     layout->ClearFlexForView(v3);
515     host_->Layout();
516     EXPECT_EQ(gfx::Rect(10, 10, 5, 30).ToString(), v1->bounds().ToString());
517     EXPECT_EQ(gfx::Rect(25, 10, 10, 30).ToString(), v2->bounds().ToString());
518     EXPECT_EQ(gfx::Rect(45, 10, 30, 30).ToString(), v3->bounds().ToString());
519
520     // Set the third view to shrink 2/3s of the free space and leave the first
521     // view with 1/3.
522     layout->SetFlexForView(v3, 2);
523     host_->Layout();
524     EXPECT_EQ(gfx::Rect(10, 10, 15, 30).ToString(), v1->bounds().ToString());
525     EXPECT_EQ(gfx::Rect(35, 10, 10, 30).ToString(), v2->bounds().ToString());
526     EXPECT_EQ(gfx::Rect(55, 10, 20, 30).ToString(), v3->bounds().ToString());
527
528     // Clear the previously set flex values and set the second view to take all
529     // the free space with MAIN_AXIS_ALIGNMENT_END set. This causes the second
530     // view to shrink to zero and the third view still doesn't fit so it
531     // overflows.
532     layout->ClearFlexForView(v1);
533     layout->SetFlexForView(v2, 2);
534     layout->ClearFlexForView(v3);
535     host_->Layout();
536     EXPECT_EQ(gfx::Rect(10, 10, 20, 30).ToString(), v1->bounds().ToString());
537     // Conceptually this view is at 10, 40, 0, 0.
538     EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(), v2->bounds().ToString());
539     EXPECT_EQ(gfx::Rect(50, 10, 25, 30).ToString(), v3->bounds().ToString());
540   }
541 }
542
543 TEST_F(BoxLayoutTest, FlexShrinkVerticalWithRemainder) {
544   BoxLayout* layout = new BoxLayout(BoxLayout::kVertical, 0, 0, 0);
545   host_->SetLayoutManager(layout);
546   View* v1 = new StaticSizedView(gfx::Size(20, 10));
547   host_->AddChildView(v1);
548   View* v2 = new StaticSizedView(gfx::Size(20, 20));
549   host_->AddChildView(v2);
550   View* v3 = new StaticSizedView(gfx::Size(20, 10));
551   host_->AddChildView(v3);
552   host_->SetBounds(0, 0, 20, 20);
553
554   std::vector<BoxLayout::MainAxisAlignment> main_alignments;
555   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_START);
556   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
557   main_alignments.push_back(BoxLayout::MAIN_AXIS_ALIGNMENT_END);
558
559   for (size_t i = 0; i < main_alignments.size(); ++i) {
560     layout->set_main_axis_alignment(main_alignments[i]);
561
562     // The first view shrinks by 1/3 of the excess, the second view shrinks by
563     // 2/3 of the excess and the third view should maintain its preferred size.
564     layout->SetFlexForView(v1, 1);
565     layout->SetFlexForView(v2, 2);
566     layout->ClearFlexForView(v3);
567     host_->Layout();
568     EXPECT_EQ(gfx::Rect(0, 0, 20, 3).ToString(), v1->bounds().ToString());
569     EXPECT_EQ(gfx::Rect(0, 3, 20, 7).ToString(), v2->bounds().ToString());
570     EXPECT_EQ(gfx::Rect(0, 10, 20, 10).ToString(), v3->bounds().ToString());
571
572     // The second view shrinks to 2/3 of the excess, the third view shrinks to
573     // 1/3 of the excess and the first view should maintain its preferred size.
574     layout->ClearFlexForView(v1);
575     layout->SetFlexForView(v2, 2);
576     layout->SetFlexForView(v3, 1);
577     host_->Layout();
578     EXPECT_EQ(gfx::Rect(0, 0, 20, 10).ToString(), v1->bounds().ToString());
579     EXPECT_EQ(gfx::Rect(0, 10, 20, 7).ToString(), v2->bounds().ToString());
580     EXPECT_EQ(gfx::Rect(0, 17, 20, 3).ToString(), v3->bounds().ToString());
581
582     // Each view shrinks equally to fit within the available space.
583     layout->SetFlexForView(v1, 1);
584     layout->SetFlexForView(v2, 1);
585     layout->SetFlexForView(v3, 1);
586     host_->Layout();
587     EXPECT_EQ(gfx::Rect(0, 0, 20, 3).ToString(), v1->bounds().ToString());
588     EXPECT_EQ(gfx::Rect(0, 3, 20, 14).ToString(), v2->bounds().ToString());
589     EXPECT_EQ(gfx::Rect(0, 17, 20, 3).ToString(), v3->bounds().ToString());
590   }
591 }
592
593 }  // namespace views