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