| 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 } |
| 78 |
| 79 bool IsShrinking() const override { return state() == SHRINKING; } |
| 80 |
| 81 private: |
| 82 int value_; |
| 83 DISALLOW_COPY_AND_ASSIGN(TestIconLabelBubbleView); |
| 84 }; |
| 85 |
| 86 } // namespace |
| 87 |
| 88 class IconLabelBubbleViewTest : public views::ViewsTestBase { |
| 89 public: |
| 90 IconLabelBubbleViewTest() |
| 91 : views::ViewsTestBase(), |
| 92 steady_reached_(false), |
| 93 shrinking_reached_(false), |
| 94 minimum_size_reached_(false), |
| 95 previous_width_(0), |
| 96 initial_image_x_(0) {} |
| 97 ~IconLabelBubbleViewTest() override {} |
| 98 |
| 99 protected: |
| 100 // views::ViewsTestBase: |
| 101 void SetUp() override { |
| 102 views::ViewsTestBase::SetUp(); |
| 103 gfx::FontList font_list; |
| 104 view_.reset(new TestIconLabelBubbleView(font_list, kTestColor)); |
| 105 } |
| 106 |
| 107 void VerifyWithAnimationStep(int step) { |
| 108 Reset(); |
| 109 for (int value = 0; value < kNumberOfSteps; value += step) { |
| 110 SetValue(value); |
| 111 VerifyAnimationStep(); |
| 112 } |
| 113 view_->SetLabelVisible(false); |
| 114 } |
| 115 |
| 116 private: |
| 117 void Reset() { |
| 118 view_->SetLabelVisible(true); |
| 119 SetValue(0); |
| 120 steady_reached_ = false; |
| 121 shrinking_reached_ = false; |
| 122 minimum_size_reached_ = false; |
| 123 previous_width_ = 0; |
| 124 initial_image_x_ = GetImageBounds().x(); |
| 125 EXPECT_NE(0, initial_image_x_); |
| 126 } |
| 127 |
| 128 void VerifyAnimationStep() { |
| 129 switch (state()) { |
| 130 case TestIconLabelBubbleView::State::GROWING: { |
| 131 EXPECT_GE(width(), previous_width_); |
| 132 EXPECT_EQ(initial_image_x_, GetImageBounds().x()); |
| 133 EXPECT_GE(GetImageBounds().x(), 0); |
| 134 if (GetImageBounds().width() > 0) |
| 135 EXPECT_LE(GetImageBounds().right(), width()); |
| 136 EXPECT_TRUE(IsLabelVisible()); |
| 137 if (GetLabelBounds().width() > 0) { |
| 138 EXPECT_GT(GetLabelBounds().x(), GetImageBounds().right()); |
| 139 EXPECT_LT(GetLabelBounds().right(), width()); |
| 140 } |
| 141 break; |
| 142 } |
| 143 case TestIconLabelBubbleView::State::STEADY: { |
| 144 if (steady_reached_) |
| 145 EXPECT_EQ(previous_width_, width()); |
| 146 EXPECT_EQ(initial_image_x_, GetImageBounds().x()); |
| 147 EXPECT_GT(GetImageBounds().x(), 0); |
| 148 EXPECT_LT(GetImageBounds().right(), width()); |
| 149 EXPECT_TRUE(IsLabelVisible()); |
| 150 EXPECT_GT(GetLabelBounds().x(), GetImageBounds().right()); |
| 151 EXPECT_LT(GetLabelBounds().right(), width()); |
| 152 steady_reached_ = true; |
| 153 break; |
| 154 } |
| 155 case TestIconLabelBubbleView::State::SHRINKING: { |
| 156 if (shrinking_reached_) |
| 157 EXPECT_LE(width(), previous_width_); |
| 158 if (minimum_size_reached_) |
| 159 EXPECT_EQ(previous_width_, width()); |
| 160 |
| 161 EXPECT_GE(GetImageBounds().x(), 0); |
| 162 if (width() <= initial_image_x_ + kImageSize) { |
| 163 EXPECT_EQ(width(), GetImageBounds().right()); |
| 164 EXPECT_EQ(0, GetLabelBounds().width()); |
| 165 } else { |
| 166 EXPECT_EQ(initial_image_x_, GetImageBounds().x()); |
| 167 EXPECT_LE(GetImageBounds().right(), width()); |
| 168 } |
| 169 if (GetLabelBounds().width() > 0) { |
| 170 EXPECT_GT(GetLabelBounds().x(), GetImageBounds().right()); |
| 171 EXPECT_LT(GetLabelBounds().right(), width()); |
| 172 } |
| 173 shrinking_reached_ = true; |
| 174 if (width() == kImageSize) |
| 175 minimum_size_reached_ = true; |
| 176 break; |
| 177 } |
| 178 } |
| 179 previous_width_ = width(); |
| 180 } |
| 181 |
| 182 void SetValue(int value) { view_->SetCurrentAnimationValue(value); } |
| 183 |
| 184 TestIconLabelBubbleView::State state() const { return view_->state(); } |
| 185 |
| 186 int width() { return view_->width(); } |
| 187 |
| 188 bool IsLabelVisible() { return view_->IsLabelVisible(); } |
| 189 |
| 190 const gfx::Rect& GetLabelBounds() const { return view_->GetLabelBounds(); } |
| 191 |
| 192 const gfx::Rect& GetImageBounds() const { |
| 193 return view_->GetImageView()->bounds(); |
| 194 } |
| 195 |
| 196 scoped_ptr<TestIconLabelBubbleView> view_; |
| 197 |
| 198 bool steady_reached_; |
| 199 bool shrinking_reached_; |
| 200 bool minimum_size_reached_; |
| 201 int previous_width_; |
| 202 int initial_image_x_; |
| 203 }; |
| 204 |
| 205 // Tests layout rules for IconLabelBubbleView while simulating animation. |
| 206 // The animation is first growing the bubble from zero, then keeping its size |
| 207 // constant and finally shrinking it down to its minimum size which is the image |
| 208 // size. |
| 209 // Various step sizes during animation simulate different possible timing. |
| 210 TEST_F(IconLabelBubbleViewTest, AnimateLayout) { |
| 211 VerifyWithAnimationStep(1); |
| 212 VerifyWithAnimationStep(5); |
| 213 VerifyWithAnimationStep(10); |
| 214 VerifyWithAnimationStep(25); |
| 215 } |
| OLD | NEW |