1 /*
2 * Copyright (c) 2023 iSoftStone Information Technology (Group) 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 <memory>
17 #include <optional>
18
19 #include "gtest/gtest.h"
20
21 #define protected public
22 #define private public
23 #include "test/mock/core/pipeline/mock_pipeline_context.h"
24
25 #include "base/geometry/dimension.h"
26 #include "base/geometry/ng/offset_t.h"
27 #include "base/geometry/ng/size_t.h"
28 #include "base/memory/ace_type.h"
29 #include "base/utils/utils.h"
30 #include "core/components/common/layout/grid_layout_info.h"
31 #include "core/components/common/properties/alignment.h"
32 #include "core/components_ng/layout/layout_algorithm.h"
33 #include "core/components_ng/layout/layout_wrapper_node.h"
34 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
35 #include "core/components_ng/property/grid_property.h"
36 #include "core/components_ng/property/property.h"
37 #include "core/components_ng/syntax/lazy_for_each_model.h"
38 #include "core/components_ng/syntax/lazy_layout_wrapper_builder.h"
39 #undef private
40 #undef protected
41
42 using namespace testing;
43 using namespace testing::ext;
44
45 namespace OHOS::Ace::NG {
46 namespace {
47 constexpr int32_t NODE_ID_0 = 0;
48 constexpr int32_t NODE_ID_1 = 1;
49 constexpr int32_t NODE_ID_2 = 2;
50 constexpr int32_t NODE_ID_3 = 3;
51 const std::string ROW_FRAME_NODE = "rowFrameNode";
52 // const std::string FIRST_FRAME_NODE = "TabContent";
53 const std::string FIRST_CHILD_FRAME_NODE = "firstChildFrameNode";
54 const std::string SECOND_CHILD_FRAME_NODE = "secondChildFrameNode";
55 const std::string THIRD_CHILD_FRAME_NODE = "thirdChildFrameNode";
56 const int32_t INDEX = 1;
57
CreateNodeAndWrapper(const std::string & tag,int32_t nodeId)58 std::pair<RefPtr<FrameNode>, RefPtr<LayoutWrapperNode>> CreateNodeAndWrapper(const std::string& tag, int32_t nodeId)
59 {
60 auto node = FrameNode::CreateFrameNode(tag, nodeId, AceType::MakeRefPtr<Pattern>());
61 RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
62 RefPtr<LayoutWrapperNode> layoutWrapper =
63 AceType::MakeRefPtr<LayoutWrapperNode>(node, geometryNode, node->GetLayoutProperty());
64
65 return std::make_pair(node, layoutWrapper);
66 }
67
CreateWrapperBuilder()68 RefPtr<LazyLayoutWrapperBuilder> CreateWrapperBuilder()
69 {
70 RefPtr<LazyForEachActuator> actuator = AceType::MakeRefPtr<LazyForEachActuator>();
71 auto builder = AceType::DynamicCast<LazyForEachBuilder>(actuator);
72 RefPtr<LazyForEachNode> host = AceType::MakeRefPtr<LazyForEachNode>(INDEX, builder);
73 RefPtr<LazyLayoutWrapperBuilder> wrapperBuilder = AceType::MakeRefPtr<LazyLayoutWrapperBuilder>(builder, host);
74 return wrapperBuilder;
75 }
76 } // namespace
77
78 class LayoutWrapperNodeTestNg : public testing::Test {
79 public:
80 static void SetUpTestSuite();
81 static void TearDownTestSuite();
82 };
83
SetUpTestSuite()84 void LayoutWrapperNodeTestNg::SetUpTestSuite()
85 {
86 MockPipelineContext::SetUp();
87 }
88
TearDownTestSuite()89 void LayoutWrapperNodeTestNg::TearDownTestSuite()
90 {
91 MockPipelineContext::TearDown();
92 }
93
94 /**
95 * @tc.name: LayoutWrapperNodeTestNg001
96 * @tc.desc: Test Update.
97 * @tc.type: FUNC
98 */
99 HWTEST_F(LayoutWrapperNodeTestNg, LayoutWrapperNodeTestNg001, TestSize.Level1)
100 {
101 auto [node, wrapper] = CreateNodeAndWrapper(ROW_FRAME_NODE, NODE_ID_0);
102 auto [newNode, newWrapper] = CreateNodeAndWrapper(FIRST_CHILD_FRAME_NODE, NODE_ID_1);
103 wrapper->Update(newNode, newWrapper->GetGeometryNode(), newNode->GetLayoutProperty());
104 EXPECT_EQ(wrapper->GetHostNode()->GetTag(), FIRST_CHILD_FRAME_NODE);
105 }
106
107 /**
108 * @tc.name: LayoutWrapperNodeTestNg002
109 * @tc.desc: Test AppendChild.
110 * @tc.type: FUNC
111 */
112 HWTEST_F(LayoutWrapperNodeTestNg, LayoutWrapperNodeTestNg002, TestSize.Level1)
113 {
114 auto [node, wrapper] = CreateNodeAndWrapper(ROW_FRAME_NODE, NODE_ID_0);
115 auto [child, childWrapper] = CreateNodeAndWrapper(FIRST_CHILD_FRAME_NODE, NODE_ID_1);
116
117 wrapper->AppendChild(childWrapper, true);
118 EXPECT_EQ(wrapper->overlayChild_->GetHostNode()->GetTag(), FIRST_CHILD_FRAME_NODE);
119 }
120
121 /**
122 * @tc.name: LayoutWrapperNodeTestNg003
123 * @tc.desc: Test GetAllChildrenWithBuild.
124 * @tc.type: FUNC
125 */
126 HWTEST_F(LayoutWrapperNodeTestNg, LayoutWrapperNodeTestNg003, TestSize.Level1)
127 {
128 auto [node, wrapper] = CreateNodeAndWrapper(ROW_FRAME_NODE, NODE_ID_0);
129 auto [child, childWrapper] = CreateNodeAndWrapper(FIRST_CHILD_FRAME_NODE, NODE_ID_1);
130 auto [child2, childWrapper2] = CreateNodeAndWrapper(SECOND_CHILD_FRAME_NODE, NODE_ID_2);
131 auto [child3, childWrapper3] = CreateNodeAndWrapper(THIRD_CHILD_FRAME_NODE, NODE_ID_3);
132
133 wrapper->AppendChild(childWrapper, false);
134 wrapper->AppendChild(childWrapper2, false);
135 wrapper->AppendChild(childWrapper3, true);
136 wrapper->GetAllChildrenWithBuild(true);
137
138 EXPECT_TRUE(wrapper->overlayChild_->IsActive());
139 }
140
141 /**
142 * @tc.name: LayoutWrapperNodeTestNg004
143 * @tc.desc: Test Layout.
144 * @tc.type: FUNC
145 */
146 HWTEST_F(LayoutWrapperNodeTestNg, LayoutWrapperNodeTestNg004, TestSize.Level1)
147 {
148 auto [node, wrapper] = CreateNodeAndWrapper(ROW_FRAME_NODE, NODE_ID_0);
149
150 auto layoutAlgorithmT = AceType::MakeRefPtr<LayoutAlgorithm>();
151 auto layoutAlgorithm = AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithmT, false, false);
152 wrapper->SetLayoutAlgorithm(layoutAlgorithm);
153
154 wrapper->Layout();
155 EXPECT_TRUE(wrapper->layoutProperty_->GetLayoutConstraint());
156
157 LayoutConstraintF layoutConstraint;
158 layoutConstraint.parentIdealSize = OptionalSizeF(768, 1024);
159 wrapper->layoutProperty_->UpdateLayoutConstraint(layoutConstraint);
160 EXPECT_EQ(wrapper->layoutProperty_->layoutConstraint_->parentIdealSize, OptionalSizeF(768, 1024));
161 }
162
163 /**
164 * @tc.name: LayoutWrapperNodeTestNg005
165 * @tc.desc: Test SetLongPredictTask.
166 * @tc.type: FUNC
167 */
168 HWTEST_F(LayoutWrapperNodeTestNg, LayoutWrapperNodeTestNg005, TestSize.Level1)
169 {
170 auto [node, wrapper] = CreateNodeAndWrapper(ROW_FRAME_NODE, NODE_ID_0);
171 wrapper->layoutWrapperBuilder_ = CreateWrapperBuilder();
172 EXPECT_TRUE(wrapper->layoutWrapperBuilder_);
173
174 wrapper->SetLongPredictTask();
175 EXPECT_TRUE(wrapper->layoutWrapperBuilder_->useLongPredictTask_);
176 }
177
178 /**
179 * @tc.name: LayoutWrapperNodeTestNg007
180 * @tc.desc: Test LayoutOverlay.
181 * @tc.type: FUNC
182 */
183 HWTEST_F(LayoutWrapperNodeTestNg, LayoutWrapperNodeTestNg007, TestSize.Level1)
184 {
185 auto [node, wrapper] = CreateNodeAndWrapper(ROW_FRAME_NODE, NODE_ID_0);
186 auto frameSize = SizeF(100, 200);
187 wrapper->geometryNode_->SetFrameSize(frameSize);
188
189 auto [child, childWrapper] = CreateNodeAndWrapper(FIRST_CHILD_FRAME_NODE, NODE_ID_1);
190 auto frameSizeChild = SizeF(50, 100);
191 childWrapper->geometryNode_->SetFrameSize(frameSizeChild);
192 childWrapper->layoutProperty_->overlayOffsetX_ = Dimension::FromString("1px");
193 childWrapper->layoutProperty_->overlayOffsetY_ = Dimension::FromString("1px");
194
195 wrapper->AppendChild(childWrapper, true);
196 wrapper->LayoutOverlay();
197 EXPECT_EQ(childWrapper->GetGeometryNode()->GetFrameRect().GetOffset(), OffsetF(1, 1));
198 }
199
200 /**
201 * @tc.name: LayoutWrapperNodeTestNg08
202 * @tc.desc: Test GetAllChildrenWithBuild .
203 * @tc.type: FUNC
204 */
205 HWTEST_F(LayoutWrapperNodeTestNg, LayoutWrapperNodeTestNg08, TestSize.Level1)
206 {
207 /**
208 * @tc.steps: step1. Create frameNode.
209 */
210 RefPtr<FrameNode> frameNode = FrameNode::CreateFrameNode(ROW_FRAME_NODE, NODE_ID_0, AceType::MakeRefPtr<Pattern>());
211
212 /**
213 * @tc.steps: step2. Create geometryNode.
214 */
215 RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
216
217 /**
218 * @tc.steps: step3. Create layoutWrapper.
219 */
220 RefPtr<LayoutWrapperNode> layoutWrapper =
221 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
222
223 /**
224 * @tc.steps: step4. Add Children.
225 * @tc.expected: Children add successful.
226 */
227 RefPtr<LayoutWrapperNode> layoutWrapper1 =
228 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
229 layoutWrapper->AppendChild(layoutWrapper1, false);
230 EXPECT_EQ(layoutWrapper->children_.size(), 1);
231
232 RefPtr<LayoutWrapperNode> layoutWrapper2 =
233 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
234 layoutWrapper->AppendChild(layoutWrapper2, false);
235 EXPECT_EQ(layoutWrapper->children_.size(), 2);
236
237 /**
238 * @tc.steps: step5. set overlayChild_.
239 * @tc.expected: overlayChild_ is not null.
240 */
241 RefPtr<LayoutWrapperNode> layoutWrapper3 =
242 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
243 layoutWrapper->AppendChild(layoutWrapper3, true);
244 EXPECT_EQ(layoutWrapper->children_.size(), 2);
245 EXPECT_TRUE(layoutWrapper->overlayChild_);
246
247 /**
248 * @tc.steps: step6. GetAllChildrenWithBuild.
249 * @tc.expected: cachedList_ is same with children.
250 */
251 layoutWrapper->overlayChild_->isActive_ = true;
252 layoutWrapper->GetAllChildrenWithBuild();
253 EXPECT_EQ(layoutWrapper->cachedList_.size(), layoutWrapper->children_.size());
254 }
255
256 /**
257 * @tc.name: LayoutWrapperNodeTestNg09
258 * @tc.desc: Test Measure .
259 * @tc.type: FUNC
260 */
261 HWTEST_F(LayoutWrapperNodeTestNg, LayoutWrapperNodeTestNg09, TestSize.Level1)
262 {
263 /**
264 * @tc.steps: step1. Create frameNode.
265 */
266 RefPtr<FrameNode> frameNode = FrameNode::CreateFrameNode(ROW_FRAME_NODE, NODE_ID_0, AceType::MakeRefPtr<Pattern>());
267 frameNode->layoutPriority_ = 1;
268
269 /**
270 * @tc.steps: step2. Create geometryNode.
271 */
272 RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
273
274 /**
275 * @tc.steps: step3. Create layoutWrapper.
276 */
277 RefPtr<LayoutWrapperNode> layoutWrapper =
278 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
279
280 /**
281 * @tc.steps: step4. Create LayoutAlgorithmWrapper.
282 * @tc.expected: layoutAlgorithm is not null.
283 */
284 auto layoutAlgorithmT = AceType::MakeRefPtr<LayoutAlgorithm>();
285 auto layoutAlgorithm = AceType::MakeRefPtr<LayoutAlgorithmWrapper>(layoutAlgorithmT, false, false);
286 layoutWrapper->layoutAlgorithm_ = layoutAlgorithm;
287 layoutAlgorithm->skipMeasure_ = false;
288
289 /**
290 * @tc.steps: step5. Create GeometryTransition.
291 */
292 RefPtr<FrameNode> frameNode1 =
293 FrameNode::CreateFrameNode(ROW_FRAME_NODE, NODE_ID_1, AceType::MakeRefPtr<Pattern>());
294 RefPtr<GeometryTransition> geometryTransition = AceType::MakeRefPtr<GeometryTransition>("test", true, true);
295 geometryTransition->state_ = GeometryTransition::State::ACTIVE;
296 geometryTransition->inNode_ = frameNode;
297 geometryTransition->outNode_ = frameNode1;
298 geometryTransition->hasInAnim_ = true;
299 layoutWrapper->layoutProperty_->geometryTransition_ = geometryTransition;
300
301 /**
302 * @tc.steps: step6. Create LayoutConstraintF and Call Measure.
303 * @tc.expected: IsRunning and IsNodeInAndActive is true.
304 */
305 layoutWrapper->SetRootMeasureNode();
306 EXPECT_TRUE(layoutWrapper->IsRootMeasureNode());
307 LayoutConstraintF parentLayoutConstraint;
308 layoutWrapper->Measure(parentLayoutConstraint);
309 EXPECT_TRUE(geometryTransition->IsRunning(layoutWrapper->GetHostNode()));
310 EXPECT_TRUE(geometryTransition->IsNodeInAndActive(layoutWrapper->GetHostNode()));
311
312 /**
313 * @tc.steps: step7. set overlayChild_.
314 * @tc.expected: IsRunning and IsNodeInAndActive is true.
315 */
316 RefPtr<LayoutWrapperNode> layoutWrapper1 =
317 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
318 layoutWrapper->overlayChild_ = layoutWrapper1;
319 layoutWrapper->Measure(parentLayoutConstraint);
320 EXPECT_TRUE(geometryTransition->IsRunning(layoutWrapper->GetHostNode()));
321 EXPECT_TRUE(geometryTransition->IsNodeInAndActive(layoutWrapper->GetHostNode()));
322 }
323 } // namespace OHOS::Ace::NG
324