1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <array>
17 
18 #define private public
19 #define protected public
20 
21 #include "base_shape_pattern_test_ng.h"
22 #include "test/mock/core/rosen/mock_canvas.h"
23 
24 #include "base/geometry/dimension.h"
25 #include "base/geometry/ng/radius.h"
26 #include "base/memory/referenced.h"
27 #include "core/components_ng/base/view_stack_processor.h"
28 #include "core/components_ng/pattern/shape/rect_model_ng.h"
29 #include "core/components_ng/pattern/shape/rect_paint_property.h"
30 #include "core/components_ng/pattern/shape/rect_pattern.h"
31 
32 using namespace testing;
33 using namespace testing::ext;
34 
35 namespace OHOS::Ace::NG {
36 namespace {
37 constexpr std::array<std::array<float, 2>, 4> RADIUS = { { { 21, 4 }, { 3, 33 }, { 22, 44 }, { 0, 44 } } };
38 constexpr Dimension RADIUS_WIDTH = Dimension(20);
39 constexpr Dimension RADIUS_HEIGHT = Dimension(2);
40 constexpr int32_t INDEX_ZERO = 0;
41 constexpr int32_t INDEX_ONE = 1;
42 constexpr int32_t INDEX_TWO = 2;
43 constexpr int32_t INDEX_THREE = 3;
44 } // namespace
45 class RectPatternTestNg : public BaseShapePatternTestNg {
46 public:
CreadFrameNode()47     RefPtr<FrameNode> CreadFrameNode() override
48     {
49         RectModelNG().Create();
50         return AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
51     }
52 
Draw(RefPtr<FrameNode> frameNode)53     void Draw(RefPtr<FrameNode> frameNode) override
54     {
55         EXPECT_EQ(frameNode == nullptr, false);
56         auto pattern = frameNode->GetPattern<RectPattern>();
57         EXPECT_EQ(pattern == nullptr, false);
58         auto layoutProperty = frameNode->GetLayoutProperty();
59         EXPECT_EQ(layoutProperty == nullptr, false);
60         auto layoutAlgorithm = AceType::DynamicCast<ShapeLayoutAlgorithm>(pattern->CreateLayoutAlgorithm());
61         EXPECT_EQ(layoutAlgorithm == nullptr, false);
62         LayoutConstraintF layoutConstraint;
63         layoutConstraint.percentReference.SetWidth(WIDTH);
64         layoutConstraint.percentReference.SetHeight(HEIGHT);
65         layoutConstraint.selfIdealSize.SetWidth(WIDTH);
66         layoutConstraint.selfIdealSize.SetHeight(HEIGHT);
67         layoutProperty->UpdateLayoutConstraint(layoutConstraint);
68         layoutProperty->UpdateContentConstraint();
69         RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
70         ASSERT_NE(geometryNode, nullptr);
71         LayoutWrapperNode layoutWrapper = LayoutWrapperNode(frameNode, geometryNode, frameNode->GetLayoutProperty());
72         auto size = layoutAlgorithm->MeasureContent(layoutProperty->CreateContentConstraint(), &layoutWrapper);
73         EXPECT_EQ(size.has_value(), true);
74         auto paintMethod = pattern->CreateNodePaintMethod();
75         EXPECT_EQ(paintMethod == nullptr, false);
76         frameNode->GetGeometryNode()->SetContentSize(size.value());
77         auto paintWrapper = AceType::MakeRefPtr<PaintWrapper>(frameNode->GetRenderContext(),
78             frameNode->GetGeometryNode()->Clone(), frameNode->GetPaintProperty<ShapePaintProperty>());
79         EXPECT_EQ(paintWrapper == nullptr, false);
80         auto contentDraw = paintMethod->GetContentDrawFunction(AceType::RawPtr(paintWrapper));
81         EXPECT_EQ(contentDraw == nullptr, false);
82         std::shared_ptr<SkCanvas> canvas = std::make_shared<SkCanvas>();
83         Testing::MockCanvas rsCavas(&canvas);
84         auto shapePaintProperty = AceType::DynamicCast<ShapePaintProperty>(paintWrapper->GetPaintProperty()->Clone());
85         if (!shapePaintProperty->HasStrokeWidth() || !NearZero(shapePaintProperty->GetStrokeWidth()->Value())) {
86             EXPECT_CALL(rsCavas, AttachPen(_)).WillOnce(ReturnRef(rsCavas));
87         }
88         EXPECT_CALL(rsCavas, AttachBrush(_)).WillOnce(ReturnRef(rsCavas));
89         EXPECT_CALL(rsCavas, DrawRoundRect(_)).WillOnce(Return());
90         EXPECT_CALL(rsCavas, DetachPen()).WillOnce(ReturnRef(rsCavas));
91         EXPECT_CALL(rsCavas, DetachBrush()).WillOnce(ReturnRef(rsCavas));
92         contentDraw(rsCavas);
93     }
94 
CheckRadius(const RefPtr<FrameNode> & frameNode,bool hasValue)95     void CheckRadius(const RefPtr<FrameNode>& frameNode, bool hasValue)
96     {
97         EXPECT_EQ(frameNode == nullptr, false);
98         auto paintProperty = frameNode->GetPaintProperty<RectPaintProperty>();
99         EXPECT_EQ(paintProperty == nullptr, false);
100         if (hasValue) {
101             EXPECT_EQ(paintProperty->HasTopLeftRadius(), true);
102             EXPECT_EQ(paintProperty->HasTopRightRadius(), true);
103             EXPECT_EQ(paintProperty->HasBottomRightRadius(), true);
104             EXPECT_EQ(paintProperty->HasBottomLeftRadius(), true);
105             EXPECT_FLOAT_EQ(
106                 paintProperty->GetTopLeftRadiusValue().GetX().ConvertToPx(), RADIUS.at(INDEX_ZERO).at(INDEX_ZERO));
107             EXPECT_FLOAT_EQ(
108                 paintProperty->GetTopLeftRadiusValue().GetY().ConvertToPx(), RADIUS.at(INDEX_ZERO).at(INDEX_ONE));
109             EXPECT_FLOAT_EQ(
110                 paintProperty->GetTopRightRadiusValue().GetX().ConvertToPx(), RADIUS.at(INDEX_ONE).at(INDEX_ZERO));
111             EXPECT_FLOAT_EQ(
112                 paintProperty->GetTopRightRadiusValue().GetY().ConvertToPx(), RADIUS.at(INDEX_ONE).at(INDEX_ONE));
113             EXPECT_FLOAT_EQ(
114                 paintProperty->GetBottomRightRadiusValue().GetX().ConvertToPx(), RADIUS.at(INDEX_TWO).at(INDEX_ZERO));
115             EXPECT_FLOAT_EQ(
116                 paintProperty->GetBottomRightRadiusValue().GetY().ConvertToPx(), RADIUS.at(INDEX_TWO).at(INDEX_ONE));
117             EXPECT_FLOAT_EQ(
118                 paintProperty->GetBottomLeftRadiusValue().GetX().ConvertToPx(), RADIUS.at(INDEX_THREE).at(INDEX_ZERO));
119             EXPECT_FLOAT_EQ(
120                 paintProperty->GetBottomLeftRadiusValue().GetY().ConvertToPx(), RADIUS.at(INDEX_THREE).at(INDEX_ONE));
121         } else {
122             EXPECT_EQ(paintProperty->HasTopLeftRadius(), false);
123             EXPECT_EQ(paintProperty->HasTopRightRadius(), false);
124             EXPECT_EQ(paintProperty->HasBottomRightRadius(), false);
125             EXPECT_EQ(paintProperty->HasBottomLeftRadius(), false);
126         }
127         Draw(frameNode);
128     }
129 };
130 
131 /**
132  * @tc.name: RectPaintProperty001
133  * @tc.desc: create rect with radius
134  * @tc.type: FUNC
135  */
136 
137 HWTEST_F(RectPatternTestNg, RectPaintProperty001, TestSize.Level1)
138 {
139     auto rectModelNG = RectModelNG();
140     rectModelNG.Create();
141     for (int i = 0; i < RADIUS.size(); i++) {
142         rectModelNG.SetRadiusValue(Dimension(RADIUS.at(i).at(0)), Dimension(RADIUS.at(i).at(1)), i);
143     }
144     auto shapeAbstactModel = ShapeAbstractModelNG();
145     SetSize(shapeAbstactModel);
146     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
147     ViewStackProcessor::GetInstance()->Pop();
148     CheckRadius(frameNode, true);
149 }
150 
151 /**
152  * @tc.name: RectPaintProperty002
153  * @tc.desc: create rect with invalid radius
154  * @tc.type: FUNC
155  */
156 
157 HWTEST_F(RectPatternTestNg, RectPaintProperty002, TestSize.Level1)
158 {
159     auto rectModelNG = RectModelNG();
160     rectModelNG.Create();
161     rectModelNG.SetRadiusValue(Dimension(), Dimension(), RADIUS.size());
162     auto shapeAbstactModel = ShapeAbstractModelNG();
163     SetSize(shapeAbstactModel);
164     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
165     ViewStackProcessor::GetInstance()->Pop();
166     CheckRadius(frameNode, false);
167 }
168 
169 /**
170  * @tc.name: RectPaintProperty003
171  * @tc.desc: create rect with radius width and radius height
172  * @tc.type: FUNC
173  */
174 
175 HWTEST_F(RectPatternTestNg, RectPaintProperty003, TestSize.Level1)
176 {
177     RectModelNG().Create();
178     RectModelNG().SetRadiusWidth(RADIUS_WIDTH);
179     RectModelNG().SetRadiusHeight(RADIUS_HEIGHT);
180     auto shapeAbstactModel = ShapeAbstractModelNG();
181     SetSize(shapeAbstactModel);
182     auto frameNode = AceType::DynamicCast<FrameNode>(ViewStackProcessor::GetInstance()->GetMainElementNode());
183     ViewStackProcessor::GetInstance()->Pop();
184     EXPECT_EQ(frameNode == nullptr, false);
185     auto paintProperty = frameNode->GetPaintProperty<RectPaintProperty>();
186     EXPECT_EQ(paintProperty == nullptr, false);
187     EXPECT_EQ(paintProperty->HasTopLeftRadius(), true);
188     EXPECT_EQ(paintProperty->HasTopRightRadius(), true);
189     EXPECT_EQ(paintProperty->HasBottomRightRadius(), true);
190     EXPECT_EQ(paintProperty->HasBottomLeftRadius(), true);
191     EXPECT_FLOAT_EQ(paintProperty->GetTopLeftRadiusValue().GetX().ConvertToPx(), RADIUS_WIDTH.ConvertToPx());
192     EXPECT_FLOAT_EQ(paintProperty->GetTopLeftRadiusValue().GetY().ConvertToPx(), RADIUS_HEIGHT.ConvertToPx());
193     EXPECT_FLOAT_EQ(paintProperty->GetTopRightRadiusValue().GetX().ConvertToPx(), RADIUS_WIDTH.ConvertToPx());
194     EXPECT_FLOAT_EQ(paintProperty->GetTopRightRadiusValue().GetY().ConvertToPx(), RADIUS_HEIGHT.ConvertToPx());
195     EXPECT_FLOAT_EQ(paintProperty->GetBottomRightRadiusValue().GetX().ConvertToPx(), RADIUS_WIDTH.ConvertToPx());
196     EXPECT_FLOAT_EQ(paintProperty->GetBottomRightRadiusValue().GetY().ConvertToPx(), RADIUS_HEIGHT.ConvertToPx());
197     EXPECT_FLOAT_EQ(paintProperty->GetBottomLeftRadiusValue().GetX().ConvertToPx(), RADIUS_WIDTH.ConvertToPx());
198     EXPECT_FLOAT_EQ(paintProperty->GetBottomLeftRadiusValue().GetY().ConvertToPx(), RADIUS_HEIGHT.ConvertToPx());
199     Draw(frameNode);
200 }
201 
202 /**
203  * @tc.name: RectPaintProperty004
204  * @tc.desc: create RefPtr<SHapeRect>()
205  * @tc.type: FUNC
206  */
207 
208 HWTEST_F(RectPatternTestNg, RectPaintProperty004, TestSize.Level1)
209 {
210     auto rect = AceType::MakeRefPtr<ShapeRect>();
211     auto rectModelNG01 = RectModelNG();
212     rectModelNG01.Create();
213     /**
214      * @tc.desc: Call SetShapeRectRadius(index = TOP_LEFT_RADIUS = 0)
215      */
216     rectModelNG01.SetShapeRectRadius(rect, Dimension(RADIUS.at(0).at(0)), Dimension(RADIUS.at(0).at(1)), 0);
217     auto newRadius01 = Ace::Radius(Dimension(RADIUS.at(0).at(0)), Dimension(RADIUS.at(0).at(1)));
218     EXPECT_EQ(rect->topLeftRadius_, newRadius01);
219     /**
220      * @tc.desc: Call SetShapeRectRadius(index = TOP_RIGHT_RADIUS = 1)
221      */
222     rectModelNG01.SetShapeRectRadius(rect, Dimension(RADIUS.at(1).at(0)), Dimension(RADIUS.at(1).at(1)), 1);
223     auto newRadius02 = Ace::Radius(Dimension(RADIUS.at(1).at(0)), Dimension(RADIUS.at(1).at(1)));
224     EXPECT_EQ(rect->topRightRadius_, newRadius02);
225     /**
226      * @tc.desc: Call SetShapeRectRadius(index = BOTTOM_RIGHT_RADIUS = 2)
227      */
228     rectModelNG01.SetShapeRectRadius(rect, Dimension(RADIUS.at(2).at(0)), Dimension(RADIUS.at(2).at(1)), 2);
229     auto newRadius03 = Ace::Radius(Dimension(RADIUS.at(2).at(0)), Dimension(RADIUS.at(2).at(1)));
230     EXPECT_EQ(rect->bottomRightRadius_, newRadius03);
231     /**
232      * @tc.desc: Call SetShapeRectRadius(index = BOTTOM_LEFT_RADIUS = 3)
233      */
234     rectModelNG01.SetShapeRectRadius(rect, Dimension(RADIUS.at(3).at(0)), Dimension(RADIUS.at(3).at(1)), 3);
235     auto newRadius04 = Ace::Radius(Dimension(RADIUS.at(3).at(0)), Dimension(RADIUS.at(3).at(1)));
236     EXPECT_EQ(rect->bottomLeftRadius_, newRadius04);
237     /**
238      * @tc.desc: Call SetShapeRectRadius(index, Values other than 0,1,2,3)
239      */
240     auto rect01 = rect->topLeftRadius_;
241     auto rect02 = rect->topRightRadius_;
242     auto rect03 = rect->bottomRightRadius_;
243     auto rect04 = rect->bottomLeftRadius_;
244     rectModelNG01.SetShapeRectRadius(rect, Dimension(RADIUS.at(3).at(0)), Dimension(RADIUS.at(3).at(1)), 4);
245     EXPECT_EQ(rect->topLeftRadius_, rect01);
246     EXPECT_EQ(rect->topRightRadius_, rect02);
247     EXPECT_EQ(rect->bottomRightRadius_, rect03);
248     EXPECT_EQ(rect->bottomLeftRadius_, rect04);
249 }
250 
251 } // namespace OHOS::Ace::NG