| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 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/location_bar/icon_label_bubble_view.h" |
| 6 |
| 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "testing/gtest/include/gtest/gtest.h" |
| 9 #include "ui/views/controls/image_view.h" |
| 10 #include "ui/views/test/views_test_base.h" |
| 11 |
| 12 namespace { |
| 13 |
| 14 const int kStayOpenTimeMS = 100; |
| 15 const int kOpenTimeMS = 100; |
| 16 const int kAnimationDurationMS = (kOpenTimeMS * 2) + kStayOpenTimeMS; |
| 17 const int kImageSize = 15; |
| 18 const SkColor kTestColor = SkColorSetRGB(64, 64, 64); |
| 19 const int kNumberOfSteps = 300; |
| 20 |
| 21 class TestIconLabelBubbleView : public IconLabelBubbleView { |
| 22 public: |
| 23 enum State { |
| 24 GROWING, |
| 25 STEADY, |
| 26 SHRINKING, |
| 27 }; |
| 28 |
| 29 TestIconLabelBubbleView(const gfx::FontList& font_list, SkColor color) |
| 30 : IconLabelBubbleView(0, font_list, color, false), value_(0) { |
| 31 GetImageView()->SetImageSize(gfx::Size(kImageSize, kImageSize)); |
| 32 SetLabel(base::ASCIIToUTF16("Label")); |
| 33 } |
| 34 |
| 35 void SetCurrentAnimationValue(int value) { |
| 36 value_ = value; |
| 37 SizeToPreferredSize(); |
| 38 } |
| 39 |
| 40 int width() { return bounds().width(); } |
| 41 bool IsLabelVisible() const { return label()->visible(); } |
| 42 void SetLabelVisible(bool visible) { label()->SetVisible(visible); } |
| 43 const gfx::Rect& GetLabelBounds() const { return label()->bounds(); } |
| 44 |
| 45 State state() const { |
| 46 const double kOpenFraction = |
| 47 static_cast<double>(kOpenTimeMS) / kAnimationDurationMS; |
| 48 double state = value_ / (double)kNumberOfSteps; |
| 49 if (state < kOpenFraction) |
| 50 return GROWING; |
| 51 if (state > (1.0 - kOpenFraction)) |
| 52 return SHRINKING; |
| 53 return STEADY; |
| 54 } |
| 55 |
| 56 protected: |
| 57 // IconLabelBubbleView: |
| 58 SkColor GetTextColor() const override { return kTestColor; } |
| 59 SkColor GetBorderColor() const override { return kTestColor; } |
| 60 |
| 61 bool ShouldShowBackground() const override { |
| 62 return !IsShrinking() || label()->width() > 0; |
| 63 } |
| 64 |
| 65 double WidthMultiplier() const override { |
| 66 const double kOpenFraction = |
| 67 static_cast<double>(kOpenTimeMS) / kAnimationDurationMS; |
| 68 double fraction = value_ / (double)kNumberOfSteps; |
| 69 switch (state()) { |
| 70 case GROWING: |
| 71 return fraction / kOpenFraction; |
| 72 case STEADY: |
| 73 return 1.0; |
| 74 case SHRINKING: |
| 75 return (1.0 - fraction) / kOpenFraction; |
| 76 } |
| 77 NOTREACHED(); |
| 78 return 1.0; |
| 79 } |
| 80 |
| 81 bool IsShrinking() const override { return state() == SHRINKING; } |
| 82 |
| 83 private: |
| 84 int value_; |
| 85 DISALLOW_COPY_AND_ASSIGN(TestIconLabelBubbleView); |
| 86 }; |
| 87 |
| 88 } // namespace |
| 89 |
| 90 class IconLabelBubbleViewTest : public views::ViewsTestBase { |
| 91 public: |
| 92 IconLabelBubbleViewTest() |
| 93 : views::ViewsTestBase(), |
| 94 steady_reached_(false), |
| 95 shrinking_reached_(false), |
| 96 minimum_size_reached_(false), |
| 97 previous_width_(0), |
| 98 initial_image_x_(0) {} |
| 99 ~IconLabelBubbleViewTest() override {} |
| 100 |
| 101 protected: |
| 102 // views::ViewsTestBase: |
| 103 void SetUp() override { |
| 104 views::ViewsTestBase::SetUp(); |
| 105 gfx::FontList font_list; |
| 106 view_.reset(new TestIconLabelBubbleView(font_list, kTestColor)); |
| 107 } |
| 108 |
| 109 void VerifyWithAnimationStep(int step) { |
| 110 Reset(); |
| 111 for (int value = 0; value < kNumberOfSteps; value += step) { |
| 112 SetValue(value); |
| 113 VerifyAnimationStep(); |
| 114 } |
| 115 view_->SetLabelVisible(false); |
| 116 } |
| 117 |
| 118 private: |
| 119 void Reset() { |
| 120 view_->SetLabelVisible(true); |
| 121 SetValue(0); |
| 122 steady_reached_ = false; |
| 123 shrinking_reached_ = false; |
| 124 minimum_size_reached_ = false; |
| 125 previous_width_ = 0; |
| 126 initial_image_x_ = GetImageBounds().x(); |
| 127 EXPECT_NE(0, initial_image_x_); |
| 128 } |
| 129 |
| 130 void VerifyAnimationStep() { |
| 131 switch (state()) { |
| 132 case TestIconLabelBubbleView::State::GROWING: { |
| 133 EXPECT_GE(width(), previous_width_); |
| 134 EXPECT_EQ(initial_image_x_, GetImageBounds().x()); |
| 135 EXPECT_GE(GetImageBounds().x(), 0); |
| 136 if (GetImageBounds().width() > 0) |
| 137 EXPECT_LE(GetImageBounds().right(), width()); |
| 138 EXPECT_TRUE(IsLabelVisible()); |
| 139 if (GetLabelBounds().width() > 0) { |
| 140 EXPECT_GT(GetLabelBounds().x(), GetImageBounds().right()); |
| 141 EXPECT_LT(GetLabelBounds().right(), width()); |
| 142 } |
| 143 break; |
| 144 } |
| 145 case TestIconLabelBubbleView::State::STEADY: { |
| 146 if (steady_reached_) |
| 147 EXPECT_EQ(previous_width_, width()); |
| 148 EXPECT_EQ(initial_image_x_, GetImageBounds().x()); |
| 149 EXPECT_GT(GetImageBounds().x(), 0); |
| 150 EXPECT_LT(GetImageBounds().right(), width()); |
| 151 EXPECT_TRUE(IsLabelVisible()); |
| 152 EXPECT_GT(GetLabelBounds().x(), GetImageBounds().right()); |
| 153 EXPECT_LT(GetLabelBounds().right(), width()); |
| 154 steady_reached_ = true; |
| 155 break; |
| 156 } |
| 157 case TestIconLabelBubbleView::State::SHRINKING: { |
| 158 if (shrinking_reached_) |
| 159 EXPECT_LE(width(), previous_width_); |
| 160 if (minimum_size_reached_) |
| 161 EXPECT_EQ(previous_width_, width()); |
| 162 |
| 163 EXPECT_GE(GetImageBounds().x(), 0); |
| 164 if (width() <= initial_image_x_ + kImageSize) { |
| 165 EXPECT_EQ(width(), GetImageBounds().right()); |
| 166 EXPECT_EQ(0, GetLabelBounds().width()); |
| 167 } else { |
| 168 EXPECT_EQ(initial_image_x_, GetImageBounds().x()); |
| 169 EXPECT_LE(GetImageBounds().right(), width()); |
| 170 } |
| 171 if (GetLabelBounds().width() > 0) { |
| 172 EXPECT_GT(GetLabelBounds().x(), GetImageBounds().right()); |
| 173 EXPECT_LT(GetLabelBounds().right(), width()); |
| 174 } |
| 175 shrinking_reached_ = true; |
| 176 if (width() == kImageSize) |
| 177 minimum_size_reached_ = true; |
| 178 break; |
| 179 } |
| 180 } |
| 181 previous_width_ = width(); |
| 182 } |
| 183 |
| 184 void SetValue(int value) { view_->SetCurrentAnimationValue(value); } |
| 185 |
| 186 TestIconLabelBubbleView::State state() const { return view_->state(); } |
| 187 |
| 188 int width() { return view_->width(); } |
| 189 |
| 190 bool IsLabelVisible() { return view_->IsLabelVisible(); } |
| 191 |
| 192 const gfx::Rect& GetLabelBounds() const { return view_->GetLabelBounds(); } |
| 193 |
| 194 const gfx::Rect& GetImageBounds() const { |
| 195 return view_->GetImageView()->bounds(); |
| 196 } |
| 197 |
| 198 scoped_ptr<TestIconLabelBubbleView> view_; |
| 199 |
| 200 bool steady_reached_; |
| 201 bool shrinking_reached_; |
| 202 bool minimum_size_reached_; |
| 203 int previous_width_; |
| 204 int initial_image_x_; |
| 205 }; |
| 206 |
| 207 // Tests layout rules for IconLabelBubbleView while simulating animation. |
| 208 // The animation is first growing the bubble from zero, then keeping its size |
| 209 // constant and finally shrinking it down to its minimum size which is the image |
| 210 // size. |
| 211 // Various step sizes during animation simulate different possible timing. |
| 212 TEST_F(IconLabelBubbleViewTest, AnimateLayout) { |
| 213 VerifyWithAnimationStep(1); |
| 214 VerifyWithAnimationStep(5); |
| 215 VerifyWithAnimationStep(10); |
| 216 VerifyWithAnimationStep(25); |
| 217 } |
| OLD | NEW |