[M108 Migration] Support standard build for armv7hl architecture
[platform/framework/web/chromium-efl.git] / ash / controls / scroll_view_gradient_helper_unittest.cc
1 // Copyright 2021 The Chromium Authors
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 <memory>
6
7 #include "ash/controls/gradient_layer_delegate.h"
8 #include "ash/controls/scroll_view_gradient_helper.h"
9 #include "ui/compositor/layer.h"
10 #include "ui/compositor/layer_type.h"
11 #include "ui/gfx/geometry/rect.h"
12 #include "ui/views/controls/scroll_view.h"
13 #include "ui/views/test/views_test_base.h"
14 #include "ui/views/test/views_test_utils.h"
15 #include "ui/views/widget/unique_widget_ptr.h"
16 #include "ui/views/widget/widget.h"
17 #include "ui/views/widget/widget_utils.h"
18
19 namespace ash {
20 namespace {
21
22 constexpr int kWidgetHeight = 100;
23 constexpr int kWidgetWidth = 100;
24 constexpr int kGradientSize = 16;
25
26 // Uses ViewsTestBase because we may want to move this helper into //ui/views
27 // in the future.
28 class ScrollViewGradientHelperTest : public views::ViewsTestBase {
29  public:
30   ScrollViewGradientHelperTest() = default;
31   ~ScrollViewGradientHelperTest() override = default;
32
33   // testing::Test:
34   void SetUp() override {
35     ViewsTestBase::SetUp();
36
37     // Create a small widget.
38     widget_ = std::make_unique<views::Widget>();
39     views::Widget::InitParams params =
40         CreateParams(views::Widget::InitParams::TYPE_POPUP);
41     params.bounds = gfx::Rect(10, 10, kWidgetWidth, kWidgetHeight);
42     widget_->Init(std::move(params));
43     widget_->Show();
44
45     // Add a scroll view and gradient helper.
46     auto* contents = widget_->SetContentsView(std::make_unique<views::View>());
47     scroll_view_ =
48         contents->AddChildView(std::make_unique<views::ScrollView>());
49     scroll_view_->SetBounds(0, 0, kWidgetWidth, kWidgetHeight);
50     scroll_view_->SetPaintToLayer(ui::LAYER_NOT_DRAWN);
51     gradient_helper_ =
52         std::make_unique<ScrollViewGradientHelper>(scroll_view_, kGradientSize);
53   }
54
55   void TearDown() override {
56     gradient_helper_.reset();
57     widget_.reset();
58     ViewsTestBase::TearDown();
59   }
60
61   void AddScrollViewContentsWithHeight(int height) {
62     auto contents = std::make_unique<views::View>();
63     contents->SetSize({kWidgetWidth, height});
64     scroll_view_->SetContents(std::move(contents));
65     views::test::RunScheduledLayout(scroll_view_);
66   }
67
68   bool HasGradientAtTop() {
69     const auto& gradient_mask = gradient_helper_->gradient_mask_for_test();
70     EXPECT_FALSE(gradient_mask.IsEmpty());
71     return cc::MathUtil::IsWithinEpsilon(gradient_mask.steps()[0].fraction,
72                                          0.f);
73   }
74
75   bool HasGradientAtBottom() {
76     const auto& gradient_mask = gradient_helper_->gradient_mask_for_test();
77     EXPECT_FALSE(gradient_mask.IsEmpty());
78     return cc::MathUtil::IsWithinEpsilon(
79         gradient_mask.steps()[gradient_mask.step_count() - 1].fraction, 1.f);
80   }
81
82   bool HasGradientMask(const ui::Layer* layer) {
83     return !layer->gradient_mask().IsEmpty();
84   }
85
86   views::UniqueWidgetPtr widget_;
87   views::ScrollView* scroll_view_ = nullptr;
88   std::unique_ptr<ScrollViewGradientHelper> gradient_helper_;
89 };
90
91 TEST_F(ScrollViewGradientHelperTest, NoGradientForViewThatDoesNotScroll) {
92   // Create a short contents view, so the scroll view won't scroll.
93   AddScrollViewContentsWithHeight(10);
94   gradient_helper_->UpdateGradientMask();
95
96   EXPECT_FALSE(HasGradientMask(scroll_view_->layer()));
97   EXPECT_TRUE(gradient_helper_->gradient_mask_for_test().IsEmpty());
98 }
99
100 TEST_F(ScrollViewGradientHelperTest, HasGradientForViewThatScrolls) {
101   // Create a tall contents view.
102   AddScrollViewContentsWithHeight(500);
103   gradient_helper_->UpdateGradientMask();
104
105   // Gradient is shown.
106   EXPECT_TRUE(HasGradientMask(scroll_view_->layer()));
107   EXPECT_FALSE(gradient_helper_->gradient_mask_for_test().IsEmpty());
108
109   // Shrink the contents view.
110   scroll_view_->contents()->SetSize({kWidgetWidth, 10});
111   views::test::RunScheduledLayout(scroll_view_);
112   gradient_helper_->UpdateGradientMask();
113
114   // Gradient is removed.
115   EXPECT_FALSE(HasGradientMask(scroll_view_->layer()));
116   EXPECT_TRUE(gradient_helper_->gradient_mask_for_test().IsEmpty());
117 }
118
119 TEST_F(ScrollViewGradientHelperTest, ShowsGradientsBasedOnScrollPosition) {
120   // Create a tall contents view.
121   AddScrollViewContentsWithHeight(500);
122   ASSERT_TRUE(scroll_view_->vertical_scroll_bar());
123   gradient_helper_->UpdateGradientMask();
124
125   // Because the scroll position is at the top, only the bottom gradient shows.
126   EXPECT_FALSE(HasGradientAtTop());
127   EXPECT_TRUE(HasGradientAtBottom());
128
129   // Scroll down. Now both top and bottom should have gradients.
130   scroll_view_->vertical_scroll_bar()->ScrollByAmount(
131       views::ScrollBar::ScrollAmount::kNextLine);
132   EXPECT_TRUE(HasGradientAtTop());
133   EXPECT_TRUE(HasGradientAtBottom());
134
135   // Scroll to end. Now only the top should have a gradient.
136   scroll_view_->vertical_scroll_bar()->ScrollByAmount(
137       views::ScrollBar::ScrollAmount::kEnd);
138   EXPECT_TRUE(HasGradientAtTop());
139   EXPECT_FALSE(HasGradientAtBottom());
140 }
141
142 TEST_F(ScrollViewGradientHelperTest, DeletingHelperRemovesMaskLayer) {
143   // Create a tall contents view.
144   AddScrollViewContentsWithHeight(500);
145   gradient_helper_->UpdateGradientMask();
146
147   // Precondition: Mask exists.
148   ASSERT_TRUE(HasGradientMask(scroll_view_->layer()));
149
150   gradient_helper_.reset();
151   ASSERT_FALSE(HasGradientMask(scroll_view_->layer()));
152 }
153
154 }  // namespace
155 }  // namespace ash