Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(924)

Side by Side Diff: ui/views/layout/grid_layout_unittest.cc

Issue 2743743003: GridLayout: Guard against layout queries while adding a view. (Closed)
Patch Set: Rebase for BUILD.gn conflict Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/layout/grid_layout.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "ui/views/layout/grid_layout.h" 5 #include "ui/views/layout/grid_layout.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/test/gtest_util.h"
8 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/views/view.h" 10 #include "ui/views/view.h"
10 11
11 namespace views { 12 namespace views {
12 13
13 void ExpectViewBoundsEquals(int x, int y, int w, int h, 14 void ExpectViewBoundsEquals(int x, int y, int w, int h,
14 const View* view) { 15 const View* view) {
15 EXPECT_EQ(x, view->x()); 16 EXPECT_EQ(x, view->x());
16 EXPECT_EQ(y, view->y()); 17 EXPECT_EQ(y, view->y());
17 EXPECT_EQ(w, view->width()); 18 EXPECT_EQ(w, view->width());
18 EXPECT_EQ(h, view->height()); 19 EXPECT_EQ(h, view->height());
19 } 20 }
20 21
21 class SettableSizeView : public View { 22 class SettableSizeView : public View {
22 public: 23 public:
23 explicit SettableSizeView(const gfx::Size& pref) { 24 explicit SettableSizeView(const gfx::Size& pref) {
24 pref_ = pref; 25 pref_ = pref;
25 } 26 }
26 27
27 gfx::Size GetPreferredSize() const override { return pref_; } 28 gfx::Size GetPreferredSize() const override { return pref_; }
28 29
29 void set_pref(const gfx::Size& pref) { pref_ = pref; } 30 void set_pref(const gfx::Size& pref) { pref_ = pref; }
30 31
31 private: 32 private:
32 gfx::Size pref_; 33 gfx::Size pref_;
33 34
34 DISALLOW_COPY_AND_ASSIGN(SettableSizeView); 35 DISALLOW_COPY_AND_ASSIGN(SettableSizeView);
35 }; 36 };
36 37
38 // A test view that wants to alter its preferred size and re-layout when it gets
39 // added to the View hierarchy.
40 class LayoutOnAddView : public SettableSizeView {
41 public:
42 LayoutOnAddView() : SettableSizeView(gfx::Size(10, 10)) {}
43
44 void set_target_size(const gfx::Size& target_size) {
45 target_size_ = target_size;
46 }
47
48 // View:
49 void ViewHierarchyChanged(
50 const ViewHierarchyChangedDetails& details) override {
51 if (GetPreferredSize() == target_size_)
52 return;
53
54 // Contrive a realistic thing that a View might what to do, but which would
55 // break the layout machinery. Note an override of OnNativeThemeChanged()
56 // would be more compelling, but there is no Widget in this test harness.
57 set_pref(target_size_);
58 PreferredSizeChanged();
59 parent()->Layout();
60 }
61
62 private:
63 gfx::Size target_size_;
64
65 DISALLOW_COPY_AND_ASSIGN(LayoutOnAddView);
66 };
67
37 // A view with fixed circumference that trades height for width. 68 // A view with fixed circumference that trades height for width.
38 class FlexibleView : public View { 69 class FlexibleView : public View {
39 public: 70 public:
40 explicit FlexibleView(int circumference) { 71 explicit FlexibleView(int circumference) {
41 circumference_ = circumference; 72 circumference_ = circumference;
42 } 73 }
43 74
44 gfx::Size GetPreferredSize() const override { 75 gfx::Size GetPreferredSize() const override {
45 return gfx::Size(0, circumference_ / 2); 76 return gfx::Size(0, circumference_ / 2);
46 } 77 }
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 GetPreferredSize(); 761 GetPreferredSize();
731 EXPECT_EQ(gfx::Size(10, 20), pref); 762 EXPECT_EQ(gfx::Size(10, 20), pref);
732 763
733 layout.set_minimum_size(gfx::Size(40, 40)); 764 layout.set_minimum_size(gfx::Size(40, 40));
734 GetPreferredSize(); 765 GetPreferredSize();
735 EXPECT_EQ(gfx::Size(40, 40), pref); 766 EXPECT_EQ(gfx::Size(40, 40), pref);
736 767
737 RemoveAll(); 768 RemoveAll();
738 } 769 }
739 770
771 // Test that attempting a Layout() while nested in AddView() causes a DCHECK.
772 // GridLayout must guard against this as it hasn't yet updated the internal
773 // structures it uses to calculate Layout, so will give bogus results.
774 TEST_F(GridLayoutTest, LayoutOnAddDeath) {
775 // Don't use the |layout| data member from the test harness, otherwise
776 // SetLayoutManager() can take not take ownership.
777 GridLayout* grid_layout = new GridLayout(&host);
778 host.SetLayoutManager(grid_layout);
779 ColumnSet* set = grid_layout->AddColumnSet(0);
780 set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, GridLayout::USE_PREF, 0,
781 0);
782 grid_layout->StartRow(0, 0);
783 LayoutOnAddView view;
784 EXPECT_DCHECK_DEATH(grid_layout->AddView(&view));
785 // Death tests use fork(), so nothing should be added here.
786 EXPECT_FALSE(view.parent());
787
788 // If the View has nothing to change, adding should succeed.
789 view.set_target_size(view.GetPreferredSize());
790 grid_layout->AddView(&view);
791 EXPECT_TRUE(view.parent());
792
793 RemoveAll();
794 }
795
740 } // namespace views 796 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/layout/grid_layout.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698