1 /*
2  * Copyright (c) 2023 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 <vector>
17 
18 #include "gtest/gtest.h"
19 
20 #define private public
21 #define protected public
22 
23 #include "base_shape_pattern_test_ng.h"
24 
25 #include "base/geometry/dimension.h"
26 #include "core/components/common/properties/color.h"
27 #include "core/components_ng/base/ui_node.h"
28 #include "core/components_ng/base/view_stack_processor.h"
29 #include "core/components_ng/pattern/flex/flex_layout_algorithm.h"
30 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
31 #include "core/components_ng/pattern/pattern.h"
32 #include "core/components_ng/pattern/shape/circle_model_ng.h"
33 #include "core/components_ng/pattern/shape/circle_pattern.h"
34 #include "core/components_ng/pattern/shape/ellipse_model_ng.h"
35 #include "core/components_ng/pattern/shape/shape_abstract_model_ng.h"
36 #include "core/components_ng/pattern/shape/shape_container_layout_algorithm.h"
37 #include "core/components_ng/pattern/shape/shape_container_paint_property.h"
38 #include "core/components_ng/pattern/shape/shape_container_pattern.h"
39 #include "core/components_ng/pattern/shape/shape_model_ng.h"
40 #include "core/components_ng/pattern/shape/shape_pattern.h"
41 
42 using namespace testing;
43 using namespace testing::ext;
44 
45 namespace OHOS::Ace::NG {
46 namespace {
47 const float LEFT = -20.0f;
48 const float TOP = -30.0f;
49 const float ZERO = 0.0;
50 const int32_t COLUMN = 2;
51 const int32_t ROW = 3;
52 static constexpr double STROKE_MITERLIMIT_FIRST = -0.1f;
53 static constexpr double STROKE_MITERLIMIT_SECONG = 0.0f;
54 static constexpr double STROKE_MITERLIMIT_THIRD = 4.0f;
55 SizeF sizeF(80.0f, 20.0f);
56 std::vector<double> MESH = { 1, 2, 4, 6, 4, 2, 1, 3, 5, 1, 3, 5, 6, 3, 2, 2, 4, 5, 5, 3, 2, 2, 2, 4 };
57 } // namespace
58 
59 class ShapeContainerPatternTestNg : public BaseShapePatternTestNg {
60 public:
CreadFrameNode()61     RefPtr<FrameNode> CreadFrameNode() override
62     {
63         return nullptr;
64     }
65 
Draw(RefPtr<FrameNode> frameNode)66     void Draw(RefPtr<FrameNode> frameNode) override {}
67 };
68 
69 /**
70  * @tc.name: OnDirtyLayoutWrapperSwap
71  * @tc.desc: check ShapeContainerPattern OnDirtyLayoutWrapperSwap
72  * @tc.type: FUNC
73  */
74 
75 HWTEST_F(ShapeContainerPatternTestNg, OnDirtyLayoutWrapperSwap001, TestSize.Level1)
76 {
77     auto shapeModel = ShapeModelNG();
78     shapeModel.Create();
79     shapeModel.SetBitmapMesh(MESH, COLUMN, ROW);
80     RefPtr<UINode> uiNode = ViewStackProcessor::GetInstance()->Finish();
81     RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(uiNode);
82     EXPECT_TRUE(frameNode);
83     RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
84     EXPECT_TRUE(geometryNode);
85     RefPtr<LayoutWrapperNode> layoutWrapper =
86         AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
87     auto pattern = frameNode->GetPattern<ShapeContainerPattern>();
88     auto layoutAlgorithm = AceType::DynamicCast<ShapeLayoutAlgorithm>(pattern->CreateLayoutAlgorithm());
89     layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithm));
90     /**
91      * @tc.desc: Call OnDirtyLayoutWrapperSwap(skipMeasure = true; dirty->SkipMeasureContent() = false;
92      *           isShapeContainerInit_ = false)
93      */
94     auto flag01 = pattern->OnDirtyLayoutWrapperSwap(layoutWrapper, true, true);
95     EXPECT_FALSE(flag01);
96     /**
97      * @tc.desc: Call OnDirtyLayoutWrapperSwap(skipMeasure = false; dirty->SkipMeasureContent() = false;
98      *           isShapeContainerInit_ = false)
99      */
100     auto flag02 = pattern->OnDirtyLayoutWrapperSwap(layoutWrapper, false, true);
101     EXPECT_TRUE(flag02);
102     /**
103      * @tc.desc: Call OnDirtyLayoutWrapperSwap(skipMeasure = false; dirty->SkipMeasureContent() = true;
104      *           isShapeContainerInit_ = true)
105      */
106     layoutWrapper->skipMeasureContent_ = std::make_optional<bool>(true);
107     EXPECT_TRUE(layoutWrapper);
108     auto flag03 = pattern->OnDirtyLayoutWrapperSwap(layoutWrapper, false, true);
109     EXPECT_FALSE(flag03);
110     /**
111      * @tc.desc: Call ViewPortTransform(false)
112      */
113     auto paintProperty = frameNode->GetPaintProperty<ShapeContainerPaintProperty>();
114     EXPECT_TRUE(paintProperty);
115     pattern->ViewPortTransform();
116     paintProperty->propShapeViewBox_ = std::nullopt;
117     pattern->ViewPortTransform();
118     EXPECT_EQ(pattern->isShapeContainerInit_, true);
119     /**
120      * @tc.desc: Call OnModifyDone(false)
121      */
122     pattern->OnModifyDone();
123 }
124 
125 /**
126  * @tc.name: ViewPortTransform
127  * @tc.desc: check ShapeContainerPattern ViewPortTransform
128  * @tc.type: FUNC
129  */
130 
131 HWTEST_F(ShapeContainerPatternTestNg, ViewPortTransform001, TestSize.Level1)
132 {
133     /**
134      * @tc.desc: Call ViewPortTransform(HasShapeViewBox = true; IsValid = false; first_if = false)
135      */
136     auto shapeModel01 = ShapeModelNG();
137     shapeModel01.Create();
138     shapeModel01.SetViewPort(Dimension(ZERO), Dimension(ZERO), Dimension(ZERO), Dimension(ZERO));
139     shapeModel01.SetBitmapMesh(MESH, COLUMN, ROW);
140     RefPtr<UINode> uiNode = ViewStackProcessor::GetInstance()->Finish();
141     RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(uiNode);
142     auto pattern = frameNode->GetPattern<ShapeContainerPattern>();
143     auto paintProperty01 = frameNode->GetPaintProperty<ShapeContainerPaintProperty>();
144     pattern->ViewPortTransform();
145     EXPECT_TRUE(paintProperty01->HasShapeViewBox());
146     ViewStackProcessor::GetInstance()->Pop();
147     /**
148      * @tc.desc: Call ViewPortTransform(HasShapeViewBox = true; IsValid = true; first_if = true;
149      *           IsPositive = false; portWidth = true; portHeight = true; second_if = false)
150      */
151     auto shapeModel02 = ShapeModelNG();
152     shapeModel02.Create();
153     shapeModel02.SetViewPort(Dimension(LEFT), Dimension(TOP), Dimension(WIDTH), Dimension(HEIGHT));
154     shapeModel02.SetBitmapMesh(MESH, COLUMN, ROW);
155     RefPtr<UINode> uiNode01 = ViewStackProcessor::GetInstance()->Finish();
156     RefPtr<FrameNode> frameNode01 = AceType::DynamicCast<FrameNode>(uiNode01);
157     auto pattern01 = frameNode01->GetPattern<ShapeContainerPattern>();
158     auto paintProperty02 = frameNode01->GetPaintProperty<ShapeContainerPaintProperty>();
159     pattern01->ViewPortTransform();
160     EXPECT_TRUE(paintProperty02->GetShapeViewBoxValue().IsValid());
161     ViewStackProcessor::GetInstance()->Pop();
162     /**
163      * @tc.desc: Call ViewPortTransform(HasShapeViewBox = true; IsValid = true; first_if = true;
164      *           IsPositive = true; portWidth = true; portHeight = true; second_if = true;
165      *           HasOffset = false; third_if = false)
166      */
167     auto shapeModel03 = ShapeModelNG();
168     shapeModel03.Create();
169     shapeModel03.SetViewPort(Dimension(LEFT), Dimension(TOP), Dimension(WIDTH), Dimension(HEIGHT));
170     shapeModel03.SetBitmapMesh(MESH, COLUMN, ROW);
171     RefPtr<UINode> uiNode03 = ViewStackProcessor::GetInstance()->Finish();
172     RefPtr<FrameNode> frameNode03 = AceType::DynamicCast<FrameNode>(uiNode03);
173     auto pattern03 = frameNode03->GetPattern<ShapeContainerPattern>();
174     auto paintProperty03 = frameNode03->GetPaintProperty<ShapeContainerPaintProperty>();
175     auto geometryNode = frameNode03->GetGeometryNode();
176     geometryNode->SetContentSize(sizeF);
177     // add frameNode child
178     auto rowNodeId = ElementRegister::GetInstance()->MakeUniqueId();
179     auto rowNode = FrameNode::GetOrCreateFrameNode(
__anon2ed5af160202() 180         V2::ROW_ETS_TAG, rowNodeId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
181     rowNode->MountToParent(frameNode03);
182     pattern03->ViewPortTransform();
183     auto node = AceType::DynamicCast<FrameNode>(rowNode);
184     auto context = node->GetRenderContext();
185     EXPECT_EQ(context->HasOffset(), false);
186     ViewStackProcessor::GetInstance()->Pop();
187 }
188 
189 /**
190  * @tc.name: ViewPortTransform
191  * @tc.desc: check ShapeContainerPattern OnModifyDone
192  * @tc.type: FUNC
193  */
194 
195 HWTEST_F(ShapeContainerPatternTestNg, OnModifyDone001, TestSize.Level1)
196 {
197     auto shapeModel01 = ShapeModelNG();
198     shapeModel01.Create();
199     RefPtr<UINode> uiNode01 = ViewStackProcessor::GetInstance()->Finish();
200     RefPtr<FrameNode> frameNode01 = AceType::DynamicCast<FrameNode>(uiNode01);
201     auto pattern01 = frameNode01->GetPattern<ShapeContainerPattern>();
202     auto paintProperty01 = frameNode01->GetPaintProperty<ShapeContainerPaintProperty>();
203     /**
204      * @tc.desc: Call OnModifyDone(HasStrokeMiterLimit = false; first_if = false;
205      *           !child = false; third = false)
206      */
207     WeakPtr<FrameNode> childNode = frameNode01;
208     pattern01->AddChildShapeNode(childNode);
209     pattern01->OnModifyDone();
210     EXPECT_EQ(paintProperty01->HasStrokeMiterLimit(), false);
211     /**
212      * @tc.desc: Call OnModifyDone(HasStrokeMiterLimit = true; first_if = true;
213      *           Negative = true; NonNegative = false; second_if = true;
214      */
215     paintProperty01->UpdateStrokeMiterLimit(STROKE_MITERLIMIT_FIRST);
216     pattern01->OnModifyDone();
217     EXPECT_EQ(paintProperty01->HasStrokeMiterLimit(), true);
218     EXPECT_EQ(paintProperty01->GetStrokeMiterLimitValue(), ShapePaintProperty::STROKE_MITERLIMIT_DEFAULT);
219     EXPECT_NE(paintProperty01->GetStrokeMiterLimitValue(), ShapePaintProperty::STROKE_MITERLIMIT_MIN);
220     /**
221      * @tc.desc: Call OnModifyDone(HasStrokeMiterLimit = true; first_if = true;
222      *           Negative = false; NonNegative = true; second_if = true;
223      */
224     paintProperty01->UpdateStrokeMiterLimit(STROKE_MITERLIMIT_SECONG);
225     pattern01->OnModifyDone();
226     EXPECT_NE(paintProperty01->GetStrokeMiterLimitValue(), ShapePaintProperty::STROKE_MITERLIMIT_DEFAULT);
227     EXPECT_EQ(paintProperty01->GetStrokeMiterLimitValue(), ShapePaintProperty::STROKE_MITERLIMIT_MIN);
228     /**
229      * @tc.desc: Call OnModifyDone(HasStrokeMiterLimit = true; first_if = true;
230      *           Negative = false; NonNegative = false; second_if = false;
231      */
232     paintProperty01->UpdateStrokeMiterLimit(STROKE_MITERLIMIT_THIRD);
233     pattern01->OnModifyDone();
234     EXPECT_EQ(paintProperty01->GetStrokeMiterLimitValue(), ShapePaintProperty::STROKE_MITERLIMIT_DEFAULT);
235     EXPECT_NE(paintProperty01->GetStrokeMiterLimitValue(), ShapePaintProperty::STROKE_MITERLIMIT_MIN);
236 }
237 } // namespace OHOS::Ace::NG