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 <memory>
17
18 #include "gtest/gtest.h"
19
20 #include "base/json/json_util.h"
21
22 #define protected public
23 #define private public
24
25 #include "base/json/node_object.h"
26 #include "core/components_ng/base/distributed_ui.h"
27 #include "core/components_ng/pattern/text_field/text_component_decorator.h"
28 #include "core/pipeline_ng/pipeline_context.h"
29 #include "test/mock/core/pipeline/mock_pipeline_context.h"
30
31 using namespace testing;
32 using namespace testing::ext;
33
34 namespace OHOS::Ace::NG {
35 namespace {
36 const char DISTRIBUTE_UI_ID[] = "$ID";
37 const char DISTRIBUTE_UI_DEPTH[] = "$depth";
38 const char DISTRIBUTE_UI_ATTRS[] = "$attrs";
39 } // namespace
40 class DistributedUiTestNg : public testing::Test {
41 public:
SetUpTestSuite()42 static void SetUpTestSuite()
43 {
44 MockPipelineContext::SetUp();
45 }
TearDownTestSuite()46 static void TearDownTestSuite()
47 {
48 MockPipelineContext::TearDown();
49 }
50
51 void Init();
52 };
53
Init()54 void DistributedUiTestNg::Init()
55 {
56 auto parentNode = FrameNode::CreateFrameNode(
57 V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
58 auto childNode = FrameNode::CreateFrameNode(
59 "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
60 parentNode->AddChild(childNode);
61 auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
62 MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
63 }
64
65 /**
66 * @tc.name: DistributedUiTestNg001
67 * @tc.desc: DistributedUi of tests
68 * @tc.type: FUNC
69 */
70 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg001, TestSize.Level1)
71 {
72 auto parentNode = FrameNode::CreateFrameNode(
73 V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
74 auto childNode = FrameNode::CreateFrameNode(
75 "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
76 parentNode->AddChild(childNode);
77 auto thirdGenerationNode = FrameNode::CreateFrameNode(
78 "thirdGenerationNode", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
79 auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
80 MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
81
82 /**
83 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
84 * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
85 */
86 DistributedUI distributedUI;
87 auto array = distributedUI.DumpUITree();
88 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
89
90 /**
91 * @tc.steps: step2. childNode add thirdGenerationNode
92 * @tc.expected: step2. call DumpUITree() return SerializeableObjectArray
93 */
94 childNode->AddChild(thirdGenerationNode);
95 array = distributedUI.DumpUITree();
96 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
97 EXPECT_FALSE(array.empty());
98
99 /**
100 * @tc.steps: step3. creat fun.
101 * @tc.expected: step3. distributedUI.onUpdateCb_ is not null
102 */
103
__anon70da084d0202(int32_t num, SerializeableObjectArray& array) 104 std::function<void(int32_t, SerializeableObjectArray&)> fun = [](int32_t num, SerializeableObjectArray& array) {};
105
106 distributedUI.SubscribeUpdate(fun);
107 EXPECT_TRUE(distributedUI.onUpdateCb_);
108 /**
109 * @tc.steps: step4. call UnSubscribeUpdate
110 * @tc.expected: step4. distributedUI.onUpdateCb_ is destroy.
111 */
112
113 distributedUI.UnSubscribeUpdate();
114 EXPECT_FALSE(distributedUI.onUpdateCb_);
115 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::STOP);
116 }
117
118 /**
119 * @tc.name: DistributedUiTestNg002
120 * @tc.desc: DistributedUi of tests
121 * @tc.type: FUNC
122 */
123 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg002, TestSize.Level1)
124 {
125 Init();
126 /**
127 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
128 * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
129 */
130 DistributedUI distributedUI;
131 auto array = distributedUI.DumpUITree();
132 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
133
134 /**
135 * @tc.steps: step2. call AddNode
136 * @tc.expected: step2. DistributedUI::StateMachine state determines whether to add nodes
137 */
138 distributedUI.AddDeletedNode(0);
139 distributedUI.AddNewNode(0);
140 distributedUI.AddDirtyCustomNode(0);
141 distributedUI.AddDirtyRenderNode(0);
142 distributedUI.AddDirtyLayoutNode(0);
143 EXPECT_TRUE(distributedUI.deletedNodes_.empty());
144
__anon70da084d0302(int32_t num, SerializeableObjectArray& array) 145 std::function<void(int32_t, SerializeableObjectArray&)> fun = [](int32_t num, SerializeableObjectArray& array) {};
146 distributedUI.SubscribeUpdate(fun);
147 EXPECT_TRUE(distributedUI.onUpdateCb_);
148 distributedUI.AddDeletedNode(0);
149 distributedUI.AddNewNode(0);
150 distributedUI.AddDirtyCustomNode(0);
151 distributedUI.AddDirtyRenderNode(0);
152 distributedUI.AddDirtyLayoutNode(0);
153 EXPECT_EQ(distributedUI.deletedNodes_.size(), 1);
154 }
155
156 /**
157 * @tc.name: DistributedUiTestNg003
158 * @tc.desc: DistributedUi of tests
159 * @tc.type: FUNC
160 */
161 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg003, TestSize.Level1)
162 {
163 Init();
164
165 /**
166 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
167 * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
168 */
169 DistributedUI distributedUI;
170 auto array = distributedUI.DumpUITree();
171 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
172
173 /**
174 * @tc.steps: step2. call OnTreeUpdate.
175 * @tc.expected: step2. distributedUI.pageChangeFlag_ change.
176 */
177 distributedUI.OnTreeUpdate();
__anon70da084d0402(int32_t num, SerializeableObjectArray& array) 178 std::function<void(int32_t, SerializeableObjectArray&)> fun = [](int32_t num, SerializeableObjectArray& array) {};
179 distributedUI.SubscribeUpdate(fun);
180 EXPECT_TRUE(distributedUI.onUpdateCb_);
181 distributedUI.OnPageChanged(0);
182 EXPECT_TRUE(distributedUI.pageChangeFlag_);
183 distributedUI.OnTreeUpdate();
184 EXPECT_FALSE(distributedUI.pageChangeFlag_);
185 distributedUI.OnTreeUpdate();
186 EXPECT_TRUE(distributedUI.onUpdateCb_);
187
188 distributedUI.status_ = DistributedUI::StateMachine::STOP;
189 distributedUI.OnPageChanged(distributedUI.GetCurrentPageId());
190 EXPECT_FALSE(distributedUI.pageChangeFlag_);
191 }
192
193 /**
194 * @tc.name: DistributedUiTestNg004
195 * @tc.desc: DistributedUi of tests
196 * @tc.type: FUNC
197 */
198 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg004, TestSize.Level1)
199 {
200 Init();
201 /**
202 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
203 * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
204 */
205 DistributedUI distributedUI;
206 auto array = distributedUI.DumpUITree();
207 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
208
209 /**
210 * @tc.steps: step2. call SubscribeInputEventProcess
211 * @tc.expected: step2. creat eventFun and eventFun destroy
212 */
__anon70da084d0502(SerializeableObjectArray& array) 213 std::function<void(SerializeableObjectArray&)> eventFun = [](SerializeableObjectArray& array) {};
214 distributedUI.SubscribeInputEventProcess(eventFun);
215 TouchEvent touchEvent;
216 distributedUI.BypassEvent(touchEvent, false);
217 distributedUI.status_ = DistributedUI::StateMachine::SINK_START;
218 EXPECT_TRUE(distributedUI.onEventCb_);
219 EXPECT_TRUE(distributedUI.IsSinkMode());
220 distributedUI.UnSubscribeInputEventProcess();
221 distributedUI.BypassEvent(touchEvent, false);
222 EXPECT_FALSE(distributedUI.onEventCb_);
223 EXPECT_FALSE(distributedUI.IsSinkMode());
224 }
225
226 /**
227 * @tc.name: DistributedUiTestNg005
228 * @tc.desc: DistributedUi of tests
229 * @tc.type: FUNC
230 */
231 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg005, TestSize.Level1)
232 {
233 auto parentNode = FrameNode::CreateFrameNode(
234 V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
235 auto childNode = FrameNode::CreateFrameNode(
236 "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
237 parentNode->AddChild(childNode);
238 auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
239 MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
240 /**
241 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
242 * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
243 */
244 DistributedUI distributedUI;
245 auto array = distributedUI.DumpUITree();
246 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
247
248 /**
249 * @tc.steps: step2. call DumpUpdate().
250 * @tc.expected: step2. return SerializeableObjectArray is not empty.
251 */
__anon70da084d0602(int32_t num, SerializeableObjectArray& array) 252 std::function<void(int32_t, SerializeableObjectArray&)> fun = [](int32_t num, SerializeableObjectArray& array) {};
253 distributedUI.SubscribeUpdate(fun);
254 EXPECT_TRUE(distributedUI.onUpdateCb_);
255 distributedUI.AddDeletedNode(parentNode->GetId());
256 distributedUI.AddNewNode(parentNode->GetId());
257 distributedUI.AddDirtyCustomNode(parentNode->GetId());
258 distributedUI.AddDirtyRenderNode(parentNode->GetId());
259 distributedUI.AddDirtyLayoutNode(parentNode->GetId());
260 distributedUI.AddDeletedNode(100);
261 distributedUI.AddNewNode(100);
262 distributedUI.AddDirtyCustomNode(100);
263 distributedUI.AddDirtyRenderNode(100);
264 distributedUI.AddDirtyLayoutNode(100);
265 EXPECT_TRUE(distributedUI.IsNewNode(100));
266 auto newArray = distributedUI.DumpUpdate();
267 EXPECT_TRUE(!newArray.empty());
268 distributedUI.ResetDirtyNodes();
269 EXPECT_TRUE(distributedUI.newNodes_.empty());
270 EXPECT_FALSE(distributedUI.IsNewNode(100));
271 }
272
273 /**
274 * @tc.name: DistributedUiTestNg006
275 * @tc.desc: DistributedUi of tests
276 * @tc.type: FUNC
277 */
278 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg006, TestSize.Level1)
279 {
280 auto parentNode = FrameNode::CreateFrameNode(
281 V2::JS_SYNTAX_ITEM_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
282 auto childNode = FrameNode::CreateFrameNode(
283 "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
284 parentNode->AddChild(childNode);
285 auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
286 MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
287 /**
288 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
289 * @tc.expected: step1. call DumpUITree() return SerializeableObjectArray
290 */
291 DistributedUI distributedUI;
292 auto array = distributedUI.DumpUITree();
293 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::SOURCE_START);
294
295 /**
296 * @tc.steps: step2. call SetIdMapping
297 * @tc.expected: step2. nodeIdMapping_.size() > 0
298 */
299 int32_t srcNodeId = 0;
300 int32_t sinkNodeId = 0;
301 distributedUI.SetIdMapping(srcNodeId, sinkNodeId);
302 EXPECT_EQ(distributedUI.GetIdMapping(srcNodeId), sinkNodeId);
303 /**
304 * @tc.steps: step3. call SetIdMapping
305 * @tc.expected: step3. set same numerals fix value price
306 */
307 distributedUI.SetIdMapping(srcNodeId, sinkNodeId + 1);
308 EXPECT_EQ(distributedUI.nodeIdMapping_.size(), 1);
309 /**
310 * @tc.steps: step4. call GetIdMapping
311 * @tc.expected: step4. Enter a value that does not exist and return -1
312 */
313 EXPECT_EQ(distributedUI.GetIdMapping(10), -1);
314
315 /**
316 * @tc.steps: step5. call IsRecordHash
317 * @tc.expected: step5. Returns false or true to determine whether a value already exists
318 */
319 distributedUI.AddNodeHash(0, 0);
320 EXPECT_FALSE(distributedUI.IsRecordHash(0, 0));
321 EXPECT_TRUE(distributedUI.IsRecordHash(10, 0));
322 EXPECT_TRUE(distributedUI.IsRecordHash(0, 10));
323 EXPECT_TRUE(distributedUI.IsRecordHash(10, 10));
324
325 /**
326 * @tc.steps: step6. call IsInCurrentPage
327 * @tc.expected: step6. Returns false or true to determine whether a value already exists
328 */
329 EXPECT_TRUE(distributedUI.IsInCurrentPage(parentNode, 0));
330 EXPECT_TRUE(distributedUI.IsInCurrentPage(childNode, 0));
331 EXPECT_FALSE(distributedUI.IsInCurrentPage(childNode, 5));
332 }
333
334 /**
335 * @tc.name: DistributedUiTestNg007
336 * @tc.desc: DistributedUi of tests
337 * @tc.type: FUNC
338 */
339 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg007, TestSize.Level1)
340 {
341 auto parentNode = FrameNode::CreateFrameNode(
342 V2::JS_SYNTAX_ITEM_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
343 auto childNode = FrameNode::CreateFrameNode(
344 "child", ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
345 parentNode->AddChild(childNode);
346 auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
347 MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
348
349 auto nodeObject = std::make_unique<OHOS::Ace::NodeObject>();
350 /**
351 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
352 * @tc.expected: step1. call AttachToTree() return SerializeableObjectArray
353 */
354 DistributedUI distributedUI;
355 distributedUI.AttachToTree(parentNode, childNode, nodeObject);
356 EXPECT_TRUE(distributedUI.IsInCurrentPage(parentNode, 0));
357
358 nodeObject->Put(DISTRIBUTE_UI_DEPTH, 1);
359 distributedUI.AttachToTree(parentNode, childNode, nodeObject);
360 EXPECT_TRUE(distributedUI.IsInCurrentPage(parentNode, 0));
361 }
362
363 /**
364 * @tc.name: DistributedUiTestNg008
365 * @tc.desc: DistributedUi of tests
366 * @tc.type: FUNC
367 */
368 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg008, TestSize.Level1)
369 {
370 auto parentNodeId = ElementRegister::GetInstance()->MakeUniqueId();
371 auto parentNode =
372 FrameNode::CreateFrameNode(V2::JS_SYNTAX_ITEM_ETS_TAG, parentNodeId, AceType::MakeRefPtr<Pattern>());
373 auto childNodeId = ElementRegister::GetInstance()->MakeUniqueId();
374 auto childNode = FrameNode::CreateFrameNode("child", childNodeId, AceType::MakeRefPtr<Pattern>());
375 parentNode->AddChild(childNode);
376 auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
377 MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
378
379 auto nodeObject = std::make_unique<OHOS::Ace::NodeObject>();
380 nodeObject->Put(DISTRIBUTE_UI_ID, childNodeId);
381 /**
382 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
383 * @tc.expected: step1. call AttachToTree() return SerializeableObjectArray
384 */
385 DistributedUI distributedUI;
386 distributedUI.DelNode(nodeObject);
387 EXPECT_FALSE(parentNode->GetChildren().empty());
388
389 distributedUI.SetIdMapping(childNodeId, childNodeId);
390 distributedUI.DelNode(nodeObject);
391 EXPECT_TRUE(parentNode->GetChildren().empty());
392
393 distributedUI.DelNode(nodeObject);
394 EXPECT_EQ(childNode->GetParent(), nullptr);
395 }
396
397 /**
398 * @tc.name: DistributedUiTestNg009
399 * @tc.desc: DistributedUi of tests
400 * @tc.type: FUNC
401 */
402 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg009, TestSize.Level1)
403 {
404 auto parentNodeId = ElementRegister::GetInstance()->MakeUniqueId();
405 auto parentNode =
406 FrameNode::CreateFrameNode(V2::JS_SYNTAX_ITEM_ETS_TAG, parentNodeId, AceType::MakeRefPtr<Pattern>());
407 auto childNodeId = ElementRegister::GetInstance()->MakeUniqueId();
408 auto childNode = FrameNode::CreateFrameNode("child", childNodeId, AceType::MakeRefPtr<Pattern>());
409 parentNode->AddChild(childNode);
410 auto stageManager = AceType::MakeRefPtr<StageManager>(parentNode);
411 MockPipelineContext::GetCurrent()->stageManager_ = stageManager;
412
413 auto nodeObject = std::make_unique<OHOS::Ace::NodeObject>();
414 nodeObject->Put(DISTRIBUTE_UI_ID, childNodeId);
415
416 auto attrValue = "{padding: 1px}";
417 nodeObject->Put(DISTRIBUTE_UI_ATTRS, OHOS::Ace::JsonUtil::ParseJsonString(attrValue));
418 /**
419 * @tc.steps: step1. creat distributedUI and creat parentNode add childNode
420 * @tc.expected: step1. call AttachToTree() return SerializeableObjectArray
421 */
422 DistributedUI distributedUI;
423 distributedUI.ModNode(nodeObject);
424 EXPECT_NE(childNode, nullptr);
425
426 distributedUI.SetIdMapping(childNodeId, childNodeId);
427 distributedUI.ModNode(nodeObject);
428 EXPECT_NE(childNode->GetLayoutProperty()->GetPaddingProperty()->left->calcValue_, "0.0");
429 }
430
431 /**
432 * @tc.name: DistributedUiTestNg010
433 * @tc.desc: DistributedUi UpdateUITree
434 * @tc.type: FUNC
435 */
436 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg010, TestSize.Level1)
437 {
438 /**
439 * @tc.steps: step1. statement distributedUI and SerializeableObjectArray
440 */
441 SerializeableObjectArray array;
442 DistributedUI distributedUI;
443
444 /**
445 * @tc.steps: step2. call UpdateUITree()
446 * @tc.expected: step2. call AttachToTree() and cover branch status_ is INIT
447 */
448 distributedUI.UpdateUITree(array);
449 EXPECT_EQ(distributedUI.status_, DistributedUI::StateMachine::INIT);
450
451 /**
452 * @tc.steps: step3. call UpdateUITree()
453 * @tc.expected: step3. call AttachToTree() and cover branch status_ is not INIT
454 */
455 distributedUI.status_ = DistributedUI::StateMachine::SINK_START;
456 distributedUI.UpdateUITree(array);
457 EXPECT_NE(distributedUI.status_, DistributedUI::StateMachine::INIT);
458 }
459
460 /**
461 * @tc.name: DistributedUiTestNg011
462 * @tc.desc: DistributedUi UpdateUITree
463 * @tc.type: FUNC
464 */
465 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg011, TestSize.Level1)
466 {
467 /**
468 * @tc.steps: step1. statement distributedUI and SerializeableObjectArray
469 */
470 DistributedUI distributedUI;
471 distributedUI.ApplyOneUpdate();
472 EXPECT_EQ(distributedUI.pendingUpdates_.size() == 0, true);
473 SerializeableObjectArray array;
474 std::unique_ptr<SerializeableObject> value = std::make_unique<JsonValue>();
475 array.push_back(std::move(value));
476 distributedUI.RestoreUITree(array);
477 distributedUI.UpdateUITree(array);
478 EXPECT_EQ(distributedUI.pendingUpdates_.size() == 1, true);
479 distributedUI.ApplyOneUpdate();
480 EXPECT_EQ(distributedUI.pendingUpdates_.size() == 0, true);
481 }
482
483 /**
484 * @tc.name: DistributedUiTestNg012
485 * @tc.desc: RestoreUITreeInner
486 * @tc.type: FUNC
487 */
488 HWTEST_F(DistributedUiTestNg, DistributedUiTestNg012, TestSize.Level1)
489 {
490 /**
491 * @tc.steps: step1. prepare the environment variables for the function.
492 */
493 SerializeableObjectArray array;
494 DistributedUI distributedUI;
495 distributedUI.RestoreUITreeInner(array);
496 EXPECT_EQ(distributedUI.sinkPageChildren_.empty(), true);
497 }
498 } // namespace OHOS::Ace::NG