1 /*
2  * Copyright (c) 2022-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 <utility>
17 
18 #include "gtest/gtest.h"
19 
20 #include "base/memory/ace_type.h"
21 
22 #define private public
23 #define protected public
24 #include "core/components_ng/base/frame_node.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "core/components_ng/syntax/for_each_model_ng.h"
27 #include "core/components_ng/syntax/for_each_node.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 std::string NODE_TAG("node");
36 const std::string LIST_TAG("List");
37 constexpr bool IS_ATOMIC_NODE = false;
38 const std::list<std::string> ID_ARRAY = { "0" };
39 const std::list<std::string> FOR_EACH_ARRAY = { "0", "1", "2", "3" };
40 const std::list<std::string> FOR_EACH_IDS = { "0", "1", "2", "3", "4", "5" };
41 constexpr int32_t FOR_EACH_NODE_ID = 1;
42 } // namespace
43 
44 class ForEachSyntaxTestNg : public testing::Test {
45 public:
46     static void SetUpTestSuite();
47     static void TearDownTestSuite();
48 };
49 
SetUpTestSuite()50 void ForEachSyntaxTestNg::SetUpTestSuite()
51 {
52     MockPipelineContext::SetUp();
53 }
54 
TearDownTestSuite()55 void ForEachSyntaxTestNg::TearDownTestSuite()
56 {
57     MockPipelineContext::TearDown();
58 }
59 
SetOnMoveTestNg(int32_t a,int32_t b)60 void SetOnMoveTestNg(int32_t a, int32_t b) {}
61 
62 /**
63  * @tc.name: ForEachSyntaxCreateTest001
64  * @tc.desc: Create ForEach.
65  * @tc.type: FUNC
66  */
67 HWTEST_F(ForEachSyntaxTestNg, ForEachSyntaxTest001, TestSize.Level1)
68 {
69     ForEachModelNG forEach;
70     forEach.Create();
71     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
72     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
73     EXPECT_EQ(forEachNode->IsAtomicNode(), IS_ATOMIC_NODE);
74 }
75 
76 /**
77  * @tc.name: ForEachSyntaxTest002
78  * @tc.desc: Create ForEach.
79  * @tc.type: FUNC
80  */
81 HWTEST_F(ForEachSyntaxTestNg, ForEachSyntaxTest002, TestSize.Level1)
82 {
83     ForEachModelNG forEach;
84     forEach.Create();
85     forEach.Pop();
86     auto node = ViewStackProcessor::GetInstance()->GetMainElementNode();
87     // ViewStackProcessor will not pop when it's size equals 1.
88     EXPECT_FALSE(ViewStackProcessor::GetInstance()->GetMainElementNode() == nullptr);
89     // ViewStackProcessor will not pop when it's size equals 1.
90     EXPECT_TRUE(ViewStackProcessor::GetInstance()->GetMainFrameNode() == nullptr);
91 }
92 
93 /**
94  * @tc.name: ForEachSyntaxIdTest003
95  * @tc.desc: Create ForEach and set its ids.
96  * @tc.type: FUNC
97  */
98 HWTEST_F(ForEachSyntaxTestNg, ForEachSyntaxIdTest003, TestSize.Level1)
99 {
100     ForEachModelNG forEach;
101     forEach.Create();
102     std::list<std::string> ids = FOR_EACH_IDS;
103     forEach.SetNewIds(std::move(ids));
104 
105     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
106     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
107 
108     // tempIds_ is empty.
109     auto tempIds = forEachNode->GetTempIds();
110     EXPECT_TRUE(tempIds.empty());
111     // CreateTempItems, swap ids_ and tempIds_.
112     forEachNode->CreateTempItems();
113     EXPECT_EQ(forEachNode->GetTempIds(), FOR_EACH_IDS);
114 }
115 
116 /**
117  * @tc.name: ForEachSyntaxUpdateTest004
118  * @tc.desc: Create ForEach and update children.
119  * @tc.type: FUNC
120  */
121 HWTEST_F(ForEachSyntaxTestNg, ForEachSyntaxUpdateTest004, TestSize.Level1)
122 {
123     ForEachModelNG forEach;
124     forEach.Create();
125     std::list<std::string> ids = FOR_EACH_IDS;
126     forEach.SetNewIds(std::move(ids));
127 
128     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
129     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
130 
131     /**
132     // corresponding ets code:
133     //     ForEach(this.arr,
134     //         (item: number) => {
135     //             Blank()
136     //         })
137     */
138     for (auto iter = FOR_EACH_ARRAY.begin(); iter != FOR_EACH_ARRAY.end(); iter++) {
139         auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
140         forEachNode->AddChild(childFrameNode);
141     }
142     EXPECT_EQ(forEachNode->GetChildren().size(), FOR_EACH_ARRAY.size());
143 
144     // tempIds_ is empty.
145     auto tempIds = forEachNode->GetTempIds();
146     EXPECT_TRUE(tempIds.empty());
147     // CreateTempItems, swap ids_ and tempIds_, children_ and tempChildren_.
148     forEachNode->CreateTempItems();
149     EXPECT_EQ(forEachNode->GetTempIds(), FOR_EACH_IDS);
150 }
151 
152 /**
153  * @tc.name: ForEachSyntaxUpdateTest005
154  * @tc.desc: Create ForEach and update children.
155  * @tc.type: FUNC
156  */
157 HWTEST_F(ForEachSyntaxTestNg, ForEachSyntaxUpdateTest005, TestSize.Level1)
158 {
159     /**
160      * @tc.steps: step1. Set branch id which is same as before.
161      */
162     ForEachModelNG forEach;
163     forEach.Create();
164     std::list<std::string> ids = FOR_EACH_ARRAY;
165     forEach.SetNewIds(std::move(ids));
166     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
167     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
168 
169     /**
170      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
171      */
172     forEachNode->CreateTempItems();
173     std::list<std::string> ids2 = ID_ARRAY;
174     forEachNode->SetIds(std::move(ids2));
175     forEachNode->onMainTree_ = true;
176     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
177     forEachNode->SetParent(node);
178     forEachNode->children_ = { node };
179     forEachNode->CompareAndUpdateChildren();
180     forEachNode->FlushUpdateAndMarkDirty();
181     auto tempIds = forEachNode->GetTempIds();
182     EXPECT_TRUE(tempIds.empty());
183 }
184 
185 /**
186  * @tc.name: ForEachSyntaxUpdateTest006
187  * @tc.desc: FlushUpdateAndMarkDirty
188  * @tc.type: FUNC
189  */
190 HWTEST_F(ForEachSyntaxTestNg, ForEachSyntaxUpdateTest006, TestSize.Level1)
191 {
192     /**
193      * @tc.steps: step1. Set branch id which is same as before.
194      */
195     ForEachModelNG forEach;
196     forEach.Create();
197     std::list<std::string> ids = FOR_EACH_ARRAY;
198     forEach.SetNewIds(std::move(ids));
199     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
200     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
201 
202     /**
203      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
204      */
205     forEachNode->CreateTempItems();
206     std::list<std::string> ids2 = ID_ARRAY;
207     forEachNode->SetIds(std::move(ids2));
208     forEachNode->onMainTree_ = true;
209     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
210     forEachNode->SetParent(node);
211     forEachNode->children_ = { node };
212     forEachNode->CompareAndUpdateChildren();
213     forEachNode->ids_ = forEachNode->tempIds_;
214     forEachNode->FlushUpdateAndMarkDirty();
215     auto tempIds = forEachNode->GetTempIds();
216     EXPECT_TRUE(tempIds.empty());
217 }
218 
219 /**
220  * @tc.name: ForEachSyntaxCreateTest006
221  * @tc.desc: Create ForEach with same node id.
222  * @tc.type: FUNC
223  */
224 HWTEST_F(ForEachSyntaxTestNg, ForEachSyntaxTest006, TestSize.Level1)
225 {
226     auto forEachNode = ForEachNode::GetOrCreateForEachNode(FOR_EACH_NODE_ID);
227     auto anotherForEachNode = ForEachNode::GetOrCreateForEachNode(FOR_EACH_NODE_ID);
228     EXPECT_EQ(forEachNode, anotherForEachNode);
229 }
230 
231 /**
232  * @tc.name: ForEachSyntaxUpdateTest007
233  * @tc.desc: Create ForEach and update children.
234  * @tc.type: FUNC
235  */
236 HWTEST_F(ForEachSyntaxTestNg, ForEachSyntaxUpdateTest007, TestSize.Level1)
237 {
238     /**
239      * @tc.steps: step1. Set branch id which is same as before.
240      */
241     auto context = MockPipelineContext::GetCurrent();
242     ASSERT_NE(context, nullptr);
243     ForEachModelNG forEach;
244     forEach.Create();
245     std::list<std::string> ids = FOR_EACH_ARRAY;
246     forEach.SetNewIds(std::move(ids));
247     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
248     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
249 
250     /**
251      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
252      */
253     forEachNode->CreateTempItems();
254     std::list<std::string> ids2 = FOR_EACH_IDS;
255     forEachNode->SetIds(std::move(ids2));
256     forEachNode->context_ = AceType::RawPtr(context);
257     forEachNode->onMainTree_ = true;
258     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
259     forEachNode->SetParent(node);
260     auto childNode = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
261     forEachNode->children_ = { childNode };
262     forEachNode->CompareAndUpdateChildren();
263     forEachNode->FlushUpdateAndMarkDirty();
264     auto tempIds = forEachNode->GetTempIds();
265     EXPECT_TRUE(tempIds.empty());
266 }
267 
268 /**
269  * @tc.name: ForEachGetOrCreateRepeatNodeTest001
270  * @tc.desc: Create ForEach and update children.
271  * @tc.type: FUNC
272  */
273 HWTEST_F(ForEachSyntaxTestNg, ForEachGetOrCreateRepeatNodeTest001, TestSize.Level1)
274 {
275     /**
276      * @tc.steps: step1. Set branch id which is same as before.
277      */
278     auto context = MockPipelineContext::GetCurrent();
279     ASSERT_NE(context, nullptr);
280     ForEachModelNG forEach;
281     forEach.Create();
282     std::list<std::string> ids = FOR_EACH_ARRAY;
283     forEach.SetNewIds(std::move(ids));
284     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
285     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
286 
287     /**
288      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
289      */
290     forEachNode->CreateTempItems();
291     std::list<std::string> ids2 = FOR_EACH_IDS;
292     forEachNode->SetIds(std::move(ids2));
293     forEachNode->context_ = AceType::RawPtr(context);
294     forEachNode->onMainTree_ = true;
295     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
296     forEachNode->SetParent(node);
297     auto childNode = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
298     forEachNode->children_ = { childNode };
299     forEachNode->CompareAndUpdateChildren();
300     forEachNode->FlushUpdateAndMarkDirty();
301     forEachNode->GetOrCreateRepeatNode(0);
302 }
303 
304 /**
305  * @tc.name: ForEachCreateTempItemsTest001
306  * @tc.desc: Create ForEach and update children.
307  * @tc.type: FUNC
308  */
309 HWTEST_F(ForEachSyntaxTestNg, ForEachCreateTempItemsTest001, TestSize.Level1)
310 {
311     /**
312      * @tc.steps: step1. Set branch id which is same as before.
313      */
314     auto context = MockPipelineContext::GetCurrent();
315     ASSERT_NE(context, nullptr);
316     ForEachModelNG forEach;
317     forEach.Create();
318     std::list<std::string> ids = FOR_EACH_ARRAY;
319     forEach.SetNewIds(std::move(ids));
320     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
321     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
322 
323     /**
324      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
325      */
326     forEachNode->isThisRepeatNode_= true;
327     forEachNode->CreateTempItems();
328 }
329 
330 /**
331  * @tc.name: ForEachCompareAndUpdateChildrenTest001
332  * @tc.desc: Create ForEach and update children.
333  * @tc.type: FUNC
334  */
335 HWTEST_F(ForEachSyntaxTestNg, ForEachCompareAndUpdateChildrenTest001, TestSize.Level1)
336 {
337     /**
338      * @tc.steps: step1. Set branch id which is same as before.
339      */
340     auto context = MockPipelineContext::GetCurrent();
341     ASSERT_NE(context, nullptr);
342     ForEachModelNG forEach;
343     forEach.Create();
344     std::list<std::string> ids = FOR_EACH_ARRAY;
345     forEach.SetNewIds(std::move(ids));
346     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
347     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
348 
349     /**
350      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
351      */
352     forEachNode->isThisRepeatNode_= true;
353     forEachNode->CompareAndUpdateChildren();
354 
355     forEachNode->isThisRepeatNode_= false;
356     forEachNode->CreateTempItems();
357     std::list<std::string> ids2 = ID_ARRAY;
358     forEachNode->SetIds(std::move(ids2));
359     forEachNode->onMainTree_ = true;
360     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
361     forEachNode->SetParent(node);
362     forEachNode->children_ = { node };
363     forEachNode->CompareAndUpdateChildren();
364 }
365 
366 /**
367  * @tc.name: ForEachFinishRepeatRenderTest001
368  * @tc.desc: Create ForEach and update children.
369  * @tc.type: FUNC
370  */
371 HWTEST_F(ForEachSyntaxTestNg, ForEachFinishRepeatRenderTest001, TestSize.Level1)
372 {
373     /**
374      * @tc.steps: step1. Set branch id which is same as before.
375      */
376     auto context = MockPipelineContext::GetCurrent();
377     ASSERT_NE(context, nullptr);
378     ForEachModelNG forEach;
379     forEach.Create();
380     std::list<std::string> ids = FOR_EACH_ARRAY;
381     forEach.SetNewIds(std::move(ids));
382     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
383     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
384 
385     /**
386      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
387      */
388 
389     for (auto iter = FOR_EACH_ARRAY.begin(); iter != FOR_EACH_ARRAY.end(); iter++) {
390         auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
391         forEachNode->AddChild(childFrameNode);
392     }
393     forEachNode->isThisRepeatNode_= true;
394     forEachNode->CreateTempItems();
395     std::list<std::string> ids2 = ID_ARRAY;
396     forEachNode->SetIds(std::move(ids2));
397     forEachNode->onMainTree_ = true;
398     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
399     forEachNode->SetParent(node);
400     forEachNode->children_ = { node };
401     forEachNode->CompareAndUpdateChildren();
402     forEachNode->FlushUpdateAndMarkDirty();
403     std::list<int32_t> arr;
404     arr.push_back(0);
405     arr.push_back(1);
406     arr.push_back(2);
407     arr.push_back(3);
408     arr.push_back(4);
409     forEachNode->FinishRepeatRender(arr);
410 }
411 
412 /**
413  * @tc.name: ForEachMoveChildTest001
414  * @tc.desc: Create ForEach and update children.
415  * @tc.type: FUNC
416  */
417 HWTEST_F(ForEachSyntaxTestNg, ForEachMoveChildTest001, TestSize.Level1)
418 {
419     /**
420      * @tc.steps: step1. Set branch id which is same as before.
421      */
422     auto context = MockPipelineContext::GetCurrent();
423     ASSERT_NE(context, nullptr);
424     ForEachModelNG forEach;
425     forEach.Create();
426     std::list<std::string> ids = FOR_EACH_ARRAY;
427     forEach.SetNewIds(std::move(ids));
428     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
429     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
430 
431     /**
432      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
433      */
434 
435     for (auto iter = FOR_EACH_ARRAY.begin(); iter != FOR_EACH_ARRAY.end(); iter++) {
436         auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
437         forEachNode->AddChild(childFrameNode);
438     }
439     forEachNode->isThisRepeatNode_= true;
440     forEachNode->CreateTempItems();
441     std::list<std::string> ids2 = ID_ARRAY;
442     forEachNode->SetIds(std::move(ids2));
443     forEachNode->onMainTree_ = true;
444     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
445     forEachNode->SetParent(node);
446     forEachNode->children_ = { node };
447     forEachNode->CompareAndUpdateChildren();
448     forEachNode->FlushUpdateAndMarkDirty();
449     forEachNode->MoveChild(1);
450     forEachNode->MoveChild(4);
451 }
452 
453 /**
454  * @tc.name: ForEachSetOnMoveTest001
455  * @tc.desc: Create ForEach and update children.
456  * @tc.type: FUNC
457  */
458 HWTEST_F(ForEachSyntaxTestNg, ForEachSetOnMoveTest001, TestSize.Level1)
459 {
460     /**
461      * @tc.steps: step1. Set branch id which is same as before.
462      */
463     auto context = MockPipelineContext::GetCurrent();
464     ASSERT_NE(context, nullptr);
465     ForEachModelNG forEach;
466     forEach.Create();
467     std::list<std::string> ids = FOR_EACH_ARRAY;
468     forEach.SetNewIds(std::move(ids));
469     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
470     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
471 
472     /**
473      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
474      */
475 
476     forEachNode->SetOnMove(SetOnMoveTestNg);
477 
478     for (auto iter = FOR_EACH_ARRAY.begin(); iter != FOR_EACH_ARRAY.end(); iter++) {
479         auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
480         forEachNode->AddChild(childFrameNode);
481     }
482     forEachNode->isThisRepeatNode_= true;
483     forEachNode->CreateTempItems();
484     std::list<std::string> ids2 = ID_ARRAY;
485     forEachNode->SetIds(std::move(ids2));
486     forEachNode->onMainTree_ = true;
487     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
488     forEachNode->SetParent(node);
489     forEachNode->children_ = { node };
490     forEachNode->CompareAndUpdateChildren();
491     forEachNode->FlushUpdateAndMarkDirty();
492     forEachNode->SetOnMove(SetOnMoveTestNg);
493     forEachNode->SetOnMove(nullptr);
494 }
495 
496 /**
497  * @tc.name: ForEachMoveDataTest001
498  * @tc.desc: Create ForEach and update children.
499  * @tc.type: FUNC
500  */
501 HWTEST_F(ForEachSyntaxTestNg, ForEachMoveDataTest001, TestSize.Level1)
502 {
503     /**
504      * @tc.steps: step1. Set branch id which is same as before.
505      */
506     auto context = MockPipelineContext::GetCurrent();
507     ASSERT_NE(context, nullptr);
508     ForEachModelNG forEach;
509     forEach.Create();
510     std::list<std::string> ids = FOR_EACH_ARRAY;
511     forEach.SetNewIds(std::move(ids));
512     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
513     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
514 
515     /**
516      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
517      */
518 
519     for (auto iter = FOR_EACH_ARRAY.begin(); iter != FOR_EACH_ARRAY.end(); iter++) {
520         auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
521         forEachNode->AddChild(childFrameNode);
522     }
523     forEachNode->isThisRepeatNode_= true;
524     forEachNode->CreateTempItems();
525     std::list<std::string> ids2 = ID_ARRAY;
526     forEachNode->SetIds(std::move(ids2));
527     forEachNode->onMainTree_ = true;
528     auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
529     forEachNode->SetParent(node);
530     forEachNode->children_ = { node };
531     forEachNode->CompareAndUpdateChildren();
532     forEachNode->FlushUpdateAndMarkDirty();
533     forEachNode->MoveData(0, 5);
534     forEachNode->MoveData(1, 1);
535 }
536 
537 /**
538  * @tc.name: ForEachGetFrameNodeTest001
539  * @tc.desc: Create ForEach and update children.
540  * @tc.type: FUNC
541  */
542 HWTEST_F(ForEachSyntaxTestNg, ForEachGetFrameNodeTest001, TestSize.Level1)
543 {
544     /**
545      * @tc.steps: step1. Set branch id which is same as before.
546      */
547     auto context = MockPipelineContext::GetCurrent();
548     ASSERT_NE(context, nullptr);
549     ForEachModelNG forEach;
550     forEach.Create();
551     std::list<std::string> ids = FOR_EACH_ARRAY;
552     forEach.SetNewIds(std::move(ids));
553     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
554     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
555 
556     /**
557      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
558      */
559 
560     forEachNode->GetFrameNode(1);
561 }
562 
563 /**
564  * @tc.name: ForEachInitDragManagerTest001
565  * @tc.desc: Create ForEach and update children.
566  * @tc.type: FUNC
567  */
568 HWTEST_F(ForEachSyntaxTestNg, ForEachInitDragManagerTest001, TestSize.Level1)
569 {
570     /**
571      * @tc.steps: step1. Set branch id which is same as before.
572      */
573     auto context = MockPipelineContext::GetCurrent();
574     ASSERT_NE(context, nullptr);
575     ForEachModelNG forEach;
576     forEach.Create();
577     std::list<std::string> ids = FOR_EACH_ARRAY;
578     forEach.SetNewIds(std::move(ids));
579     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
580     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
581 
582     /**
583      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
584      */
585 
586     for (auto iter = FOR_EACH_ARRAY.begin(); iter != FOR_EACH_ARRAY.end(); iter++) {
587         auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
588         forEachNode->AddChild(childFrameNode);
589     }
590     forEachNode->isThisRepeatNode_= true;
591     forEachNode->CreateTempItems();
592     std::list<std::string> ids2 = ID_ARRAY;
593     forEachNode->SetIds(std::move(ids2));
594     forEachNode->onMainTree_ = true;
595     auto list_tag = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
596     forEachNode->SetParent(list_tag);
597     forEachNode->children_ = { list_tag };
598     forEachNode->CompareAndUpdateChildren();
599     forEachNode->FlushUpdateAndMarkDirty();
600     forEachNode->SetOnMove(SetOnMoveTestNg);
601     forEachNode->InitDragManager(list_tag);
602 
603     auto node_tag = AceType::MakeRefPtr<FrameNode>(LIST_TAG, -1, AceType::MakeRefPtr<Pattern>());
604     forEachNode->SetParent(node_tag);
605     forEachNode->children_ = { node_tag };
606     forEachNode->CompareAndUpdateChildren();
607     forEachNode->FlushUpdateAndMarkDirty();
608     forEachNode->SetOnMove(SetOnMoveTestNg);
609     forEachNode->InitDragManager(node_tag);
610 }
611 
612 /**
613  * @tc.name: ForEachInitAllChildrenDragManagerTest001
614  * @tc.desc: Create ForEach and update children.
615  * @tc.type: FUNC
616  */
617 HWTEST_F(ForEachSyntaxTestNg, ForEachInitAllChildrenDragManagerTest001, TestSize.Level1)
618 {
619     /**
620      * @tc.steps: step1. Set branch id which is same as before.
621      */
622     auto context = MockPipelineContext::GetCurrent();
623     ASSERT_NE(context, nullptr);
624     ForEachModelNG forEach;
625     forEach.Create();
626     std::list<std::string> ids = FOR_EACH_ARRAY;
627     forEach.SetNewIds(std::move(ids));
628     auto forEachNode = AceType::DynamicCast<ForEachNode>(ViewStackProcessor::GetInstance()->Finish());
629     EXPECT_TRUE(forEachNode != nullptr && forEachNode->GetTag() == V2::JS_FOR_EACH_ETS_TAG);
630 
631     /**
632      * @tc.steps: step2. CompareAndUpdateChildren when newIds and oldIds are same.
633      */
634 
635     for (auto iter = FOR_EACH_ARRAY.begin(); iter != FOR_EACH_ARRAY.end(); iter++) {
636         auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
637         forEachNode->AddChild(childFrameNode);
638     }
639     forEachNode->isThisRepeatNode_= true;
640     forEachNode->CreateTempItems();
641     std::list<std::string> ids2 = ID_ARRAY;
642     forEachNode->SetIds(std::move(ids2));
643     forEachNode->onMainTree_ = true;
644     auto childFrameNode = FrameNode::CreateFrameNode(V2::BLANK_ETS_TAG, 1, AceType::MakeRefPtr<Pattern>());
645     auto list_tag = AceType::MakeRefPtr<FrameNode>(LIST_TAG, -1, AceType::MakeRefPtr<Pattern>());
646     list_tag->AddChild(childFrameNode, DEFAULT_NODE_SLOT, true);
647     forEachNode->SetParent(list_tag);
648     forEachNode->children_ = { list_tag };
649     forEachNode->CompareAndUpdateChildren();
650     forEachNode->FlushUpdateAndMarkDirty();
651     forEachNode->SetOnMove(SetOnMoveTestNg);
652     forEachNode->InitAllChildrenDragManager(true);
653 
654     auto node_tag = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
655     forEachNode->SetParent(node_tag);
656     forEachNode->InitAllChildrenDragManager(true);
657 
658     forEachNode->children_.clear();
659     auto list_tag1 = AceType::MakeRefPtr<FrameNode>(LIST_TAG, -1, AceType::MakeRefPtr<Pattern>());
660     forEachNode->SetParent(list_tag1);
661     forEachNode->children_ = { list_tag1 };
662     forEachNode->CompareAndUpdateChildren();
663     forEachNode->FlushUpdateAndMarkDirty();
664     forEachNode->SetOnMove(SetOnMoveTestNg);
665     forEachNode->InitAllChildrenDragManager(true);
666 }
667 } // namespace OHOS::Ace::NG
668