1 /*
2  * Copyright (c) 2024 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 <optional>
17 #include <utility>
18 
19 #include "gtest/gtest.h"
20 
21 #include "base/memory/ace_type.h"
22 #include "base/memory/referenced.h"
23 
24 #define private public
25 #define protected public
26 #include "mock_lazy_for_each_actuator.h"
27 #include "mock_lazy_for_each_builder.h"
28 #include "test/mock/core/pipeline/mock_pipeline_context.h"
29 
30 #include "core/components_ng/base/view_stack_processor.h"
31 #include "core/components_ng/syntax/lazy_for_each_model_ng.h"
32 #include "core/components_ng/syntax/lazy_for_each_node.h"
33 #include "core/components_ng/syntax/lazy_layout_wrapper_builder.h"
34 #undef private
35 #undef protected
36 
37 using namespace testing;
38 using namespace testing::ext;
39 
40 namespace OHOS::Ace::NG {
41 namespace {
42 const std::list<std::optional<std::string>> LAZY_FOR_EACH_NODE_IDS = { "0", "1", "2", "3", "4", "5", "6" };
43 const std::list<std::optional<std::string>> DEFAULT_LAZY_FOR_EACH_NODE_IDS = {};
44 const std::list<std::optional<int32_t>> LAZY_FOR_EACH_NODE_IDS_INT = { 0, 1, 2, 3, 4, 5, 6 };
45 const std::unordered_map<int32_t, std::optional<std::string>> LAZY_FOR_EACH_CACHED_ITEMS = { { 0, "0" }, { 1, "1" } };
46 const std::list<int32_t> LAZY_FOR_EACH_ITEMS = { 0, 1, 2, 3, 4, 5 };
47 constexpr int32_t INDEX_8 = 8;
48 constexpr int32_t INDEX_1 = 1;
49 constexpr int32_t INDEX_3 = 3;
50 constexpr int32_t INDEX_0 = 0;
51 constexpr int32_t INDEX_GREATER_THAN_END_INDEX = 20;
52 constexpr int32_t INDEX_EQUAL_WITH_START_INDEX = 1;
53 } // namespace
54 
55 class LazyForEachSyntaxTestNg : public testing::Test {
56 public:
57     void SetUp() override;
58     void TearDown() override;
59 
60     RefPtr<FrameNode> CreateNode(const std::string& tag);
61 
UpdateItems(const RefPtr<LazyForEachNode> & lazyForEachNode,const RefPtr<LazyForEachActuator> & mockLazyForEachActuator)62     static void UpdateItems(
63         const RefPtr<LazyForEachNode>& lazyForEachNode, const RefPtr<LazyForEachActuator>& mockLazyForEachActuator)
64     {
65         /**
66          * @tc.steps: step1. Add child found in generatedItem_.
67          */
68         auto ids = LAZY_FOR_EACH_NODE_IDS;
69         auto builder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
70         for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
71             builder->GetChildByIndex(iter.value_or(0), true);
72         }
73     }
74 
CreateLazyForEachNode()75     static RefPtr<LazyForEachNode> CreateLazyForEachNode()
76     {
77         /**
78          * @tc.steps: step1. Create Text and push it to view stack processor.
79          * @tc.expected: Make Text as LazyForEach parent.
80          */
81         auto pattern = AceType::MakeRefPtr<Pattern>();
82         auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::TEXT_ETS_TAG, -1, pattern);
83         pattern->AttachToFrameNode(frameNode);
84         ViewStackProcessor::GetInstance()->Push(frameNode);
85 
86         /**
87          * @tc.steps: step2. Invoke lazyForEach Create function.
88          * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
89          */
90         LazyForEachModelNG lazyForEach;
91         const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
92             AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
93         lazyForEach.Create(mockLazyForEachActuator);
94         auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
95         /**
96          * @tc.steps: step3. Add children items to lazyForEachNode.
97          */
98         UpdateItems(lazyForEachNode, mockLazyForEachActuator);
99         return lazyForEachNode;
100     }
101 };
102 
SetUp()103 void LazyForEachSyntaxTestNg::SetUp()
104 {
105     MockPipelineContext::SetUp();
106 }
107 
TearDown()108 void LazyForEachSyntaxTestNg::TearDown()
109 {
110     MockPipelineContext::TearDown();
111 }
112 
CreateNode(const std::string & tag)113 RefPtr<FrameNode> LazyForEachSyntaxTestNg::CreateNode(const std::string& tag)
114 {
115     auto pattern = AceType::MakeRefPtr<Pattern>();
116     auto frameNode = AceType::MakeRefPtr<FrameNode>(tag, -1, pattern);
117     pattern->AttachToFrameNode(frameNode);
118     ViewStackProcessor::GetInstance()->Push(frameNode);
119     return frameNode;
120 }
121 
122 /**
123  * @tc.name: LazyForEachOnDataBulkChangedTest001
124  * @tc.desc: Create LazyForEach.
125  * @tc.type: FUNC
126  */
127 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDataBulkChangedTest001, TestSize.Level1)
128 {
129     /**
130      * @tc.steps: step1. Create Text and push it to view stack processor.
131      * @tc.expected: Make Text as LazyForEach parent.
132      */
133     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
134 
135     /**
136      * @tc.steps: step2. Invoke lazyForEach Create function.
137      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
138      */
139     LazyForEachModelNG lazyForEach;
140     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
141         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
142     lazyForEach.Create(mockLazyForEachActuator);
143     auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
144     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
145 
146     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
147         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
148     }
149 
150     lazyForEachNode->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
151     lazyForEachNode->OnDataBulkChanged(INDEX_EQUAL_WITH_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
152 
153     lazyForEachNode->builder_ = nullptr;
154     lazyForEachNode->OnDataAdded(INDEX_EQUAL_WITH_START_INDEX);
155     lazyForEachNode->OnDataBulkChanged(INDEX_EQUAL_WITH_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
156 }
157 
158 /**
159  * @tc.name: LazyForEachOnDataMoveToNewPlaceTest001
160  * @tc.desc: Create LazyForEach.
161  * @tc.type: FUNC
162  */
163 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDataMoveToNewPlaceTest001, TestSize.Level1)
164 {
165     /**
166      * @tc.steps: step1. Create Text and push it to view stack processor.
167      * @tc.expected: Make Text as LazyForEach parent.
168      */
169     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
170 
171     /**
172      * @tc.steps: step2. Invoke lazyForEach Create function.
173      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
174      */
175     LazyForEachModelNG lazyForEach;
176     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
177         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
178     lazyForEach.Create(mockLazyForEachActuator);
179     auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
180     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
181 
182     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
183         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
184     }
185 
186     lazyForEachNode->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
187     lazyForEachNode->OnDataMoveToNewPlace(INDEX_EQUAL_WITH_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
188 
189     lazyForEachNode->builder_ = nullptr;
190     lazyForEachNode->OnDataAdded(INDEX_EQUAL_WITH_START_INDEX);
191     lazyForEachNode->OnDataMoveToNewPlace(INDEX_EQUAL_WITH_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
192     lazyForEachNode->OnDataMoveToNewPlace(INDEX_EQUAL_WITH_START_INDEX, INDEX_EQUAL_WITH_START_INDEX);
193 }
194 
195 /**
196  * @tc.name: LazyForEachOnDatasetChangeTest001
197  * @tc.desc: Create LazyForEach.
198  * @tc.type: FUNC
199  */
200 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDatasetChangeTest001, TestSize.Level1)
201 {
202     /**
203      * @tc.steps: step1. Create Text and push it to view stack processor.
204      * @tc.expected: Make Text as LazyForEach parent.
205      */
206     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
207 
208     /**
209      * @tc.steps: step2. Invoke lazyForEach Create function.
210      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
211      */
212     LazyForEachModelNG lazyForEach;
213     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
214         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
215     lazyForEach.Create(mockLazyForEachActuator);
216     auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
217     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
218 
219     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
220         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
221     }
222     lazyForEachBuilder->OnDataAdded(INDEX_0);
223     std::list<V2::Operation> DataOperations;
224     V2::Operation operation1 = {.type = "text"};
225     DataOperations.push_back(operation1);
226     UpdateItems(lazyForEachNode, mockLazyForEachActuator);
227     lazyForEachNode->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
228     lazyForEachNode->OnDatasetChange(DataOperations);
229     lazyForEachNode->builder_ = nullptr;
230     lazyForEachNode->OnDatasetChange(DataOperations);
231 }
232 
233 /**
234  * @tc.name: LazyForEachGetFrameChildByIndexTest001
235  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
236  * @tc.type: FUNC
237  */
238 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachGetFrameChildByIndexTest001, TestSize.Level1)
239 {
240     /**
241      * @tc.steps: step1. Create Text and push it to view stack processor.
242      * @tc.expected: Make Text as LazyForEach parent.
243      */
244     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
245 
246     /**
247      * @tc.steps: step2. Invoke lazyForEach Create function.
248      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
249      */
250     LazyForEachModelNG lazyForEach;
251     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
252         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
253     lazyForEach.Create(mockLazyForEachActuator);
254     auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
255     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
256     EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
257 
258     UpdateItems(lazyForEachNode, mockLazyForEachActuator);
259 
260     lazyForEachNode->GetFrameChildByIndex(0, true, true);
261     EXPECT_TRUE(lazyForEachNode->ids_.empty());
262 }
263 
264 /**
265  * @tc.name: LazyForEachOnDataBulkChangedTest002
266  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
267  * @tc.type: FUNC
268  */
269 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDataBulkChangedTest002, TestSize.Level1)
270 {
271     /**
272      * @tc.steps: step1. Create Text and push it to view stack processor.
273      * @tc.expected: Make Text as LazyForEach parent.
274      */
275     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
276 
277     /**
278      * @tc.steps: step2. Invoke lazyForEach Create function.
279      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
280      */
281     LazyForEachModelNG lazyForEach;
282     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
283         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
284     lazyForEach.Create(mockLazyForEachActuator);
285     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
286     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
287         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
288     }
289 
290     lazyForEachBuilder->OnDataBulkChanged(0, 5);
291 
292     lazyForEachBuilder->OnDataBulkChanged(10, 20);
293 }
294 
295 /**
296  * @tc.name: LazyForEachCollectIndexChangedCountTest001
297  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
298  * @tc.type: FUNC
299  */
300 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachCollectIndexChangedCountTest001, TestSize.Level1)
301 {
302     /**
303      * @tc.steps: step1. Create Text and push it to view stack processor.
304      * @tc.expected: Make Text as LazyForEach parent.
305      */
306     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
307 
308     /**
309      * @tc.steps: step2. Invoke lazyForEach Create function.
310      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
311      */
312     LazyForEachModelNG lazyForEach;
313     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
314         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
315     lazyForEach.Create(mockLazyForEachActuator);
316     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
317     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
318         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
319     }
320 
321     std::map<int32_t, OperationInfo> operationList;
322     OperationInfo itemInfo;
323     operationList[1] = itemInfo;
324     operationList[2] = itemInfo;
325 
326     std::map<int32_t, int32_t> indexChangedMap;
327     indexChangedMap[1] = 1;
328     indexChangedMap[2] = 2;
329     indexChangedMap[3] = 3;
330     indexChangedMap[4] = 4;
331     indexChangedMap[5] = 5;
332     indexChangedMap[6] = 6;
333 
334     lazyForEachBuilder->operationList_ = operationList;
335     lazyForEachBuilder->CollectIndexChangedCount(indexChangedMap);
336 }
337 
338 /**
339  * @tc.name: LazyForEachOperateDeleteTest001
340  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
341  * @tc.type: FUNC
342  */
343 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateDeleteTest001, TestSize.Level1)
344 {
345     /**
346      * @tc.steps: step1. Create Text and push it to view stack processor.
347      * @tc.expected: Make Text as LazyForEach parent.
348      */
349     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
350 
351     /**
352      * @tc.steps: step2. Invoke lazyForEach Create function.
353      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
354      */
355     LazyForEachModelNG lazyForEach;
356     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
357         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
358     lazyForEach.Create(mockLazyForEachActuator);
359     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
360     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
361         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
362     }
363 
364     V2::Operation operation1 = {.type = "delete", .index = INDEX_0, .count = INDEX_8};
365     int32_t num;
366     num = 1;
367     lazyForEachBuilder->OperateDelete(operation1, num);
368 
369     V2::Operation operation2 = {.type = "delete", .index = INDEX_8, .count = INDEX_8};
370     lazyForEachBuilder->OperateDelete(operation2, num);
371 }
372 
373 /**
374  * @tc.name: LazyForEachOperateChangeTest001
375  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
376  * @tc.type: FUNC
377  */
378 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateChangeTest001, TestSize.Level1)
379 {
380     /**
381      * @tc.steps: step1. Create Text and push it to view stack processor.
382      * @tc.expected: Make Text as LazyForEach parent.
383      */
384     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
385 
386     /**
387      * @tc.steps: step2. Invoke lazyForEach Create function.
388      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
389      */
390     LazyForEachModelNG lazyForEach;
391     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
392         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
393     lazyForEach.Create(mockLazyForEachActuator);
394     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
395     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
396         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
397     }
398 
399     std::list<V2::Operation> DataOperations;
400     V2::Operation operation1 = {.type = "change", .index = INDEX_0, .count = INDEX_8};
401     DataOperations.push_back(operation1);
402     lazyForEachBuilder->OnDatasetChange(DataOperations);
403 }
404 
405 /**
406  * @tc.name: LazyForEachOperateMoveTest001
407  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
408  * @tc.type: FUNC
409  */
410 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateMoveTest001, TestSize.Level1)
411 {
412     /**
413      * @tc.steps: step1. Create Text and push it to view stack processor.
414      * @tc.expected: Make Text as LazyForEach parent.
415      */
416     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
417 
418     /**
419      * @tc.steps: step2. Invoke lazyForEach Create function.
420      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
421      */
422     LazyForEachModelNG lazyForEach;
423     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
424         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
425     lazyForEach.Create(mockLazyForEachActuator);
426     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
427     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
428         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
429     }
430 
431     std::list<V2::Operation> DataOperations;
432     V2::Operation operation1 = {.type = "move", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(8, 8)};
433     DataOperations.push_back(operation1);
434     lazyForEachBuilder->OnDatasetChange(DataOperations);
435 
436     std::list<V2::Operation> DataOperations1;
437     V2::Operation operation2 = {.type = "move", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(0, 8)};
438     DataOperations1.push_back(operation2);
439     lazyForEachBuilder->OnDatasetChange(DataOperations1);
440 
441     std::list<V2::Operation> DataOperations2;
442     V2::Operation operation3 = {.type = "move", .index = INDEX_3, .key = "", .coupleIndex = std::pair(0, 1)};
443     DataOperations2.push_back(operation3);
444     lazyForEachBuilder->OnDatasetChange(DataOperations2);
445 }
446 
447 /**
448  * @tc.name: LazyForEachOperateExchangeTest001
449  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
450  * @tc.type: FUNC
451  */
452 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateExchangeTest001, TestSize.Level1)
453 {
454     /**
455      * @tc.steps: step1. Create Text and push it to view stack processor.
456      * @tc.expected: Make Text as LazyForEach parent.
457      */
458     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
459 
460     /**
461      * @tc.steps: step2. Invoke lazyForEach Create function.
462      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
463      */
464     LazyForEachModelNG lazyForEach;
465     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
466         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
467     lazyForEach.Create(mockLazyForEachActuator);
468     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
469     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
470         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
471     }
472 
473     std::list<V2::Operation> DataOperations;
474     V2::Operation operation1 = {.type = "exchange", .index = INDEX_0, .count = INDEX_8,
475      .coupleIndex = std::pair(1, 3)};
476     DataOperations.push_back(operation1);
477     lazyForEachBuilder->OnDatasetChange(DataOperations);
478 
479     std::list<V2::Operation> DataOperations1;
480     V2::Operation operation2 = {.type = "exchange", .index = INDEX_0, .count = INDEX_8,
481      .coupleIndex = std::pair(20, 3)};
482     DataOperations1.push_back(operation2);
483     lazyForEachBuilder->OnDatasetChange(DataOperations1);
484 
485     std::list<V2::Operation> DataOperations2;
486     V2::Operation operation3 = {.type = "exchange", .index = INDEX_3, .coupleKey = std::pair("", ""),
487      .coupleIndex = std::pair(0, 20)};
488     DataOperations2.push_back(operation3);
489     lazyForEachBuilder->OnDatasetChange(DataOperations2);
490 
491     std::list<V2::Operation> DataOperations3;
492     V2::Operation operation4 = {.type = "exchange", .index = INDEX_3, .coupleKey = std::pair("1", "1"),
493      .coupleIndex = std::pair(0, 20)};
494     DataOperations3.push_back(operation4);
495     lazyForEachBuilder->OnDatasetChange(DataOperations3);
496 }
497 
498 /**
499  * @tc.name: LazyForEachOperateReloadTest001
500  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
501  * @tc.type: FUNC
502  */
503 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateReloadTest001, TestSize.Level1)
504 {
505     /**
506      * @tc.steps: step1. Create Text and push it to view stack processor.
507      * @tc.expected: Make Text as LazyForEach parent.
508      */
509     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
510 
511     /**
512      * @tc.steps: step2. Invoke lazyForEach Create function.
513      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
514      */
515     LazyForEachModelNG lazyForEach;
516     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
517         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
518     lazyForEach.Create(mockLazyForEachActuator);
519     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
520     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
521         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
522     }
523 
524     std::list<V2::Operation> DataOperations;
525     V2::Operation operation1 = {.type = "reload", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(1, 3)};
526     DataOperations.push_back(operation1);
527     lazyForEachBuilder->OnDatasetChange(DataOperations);
528 }
529 
530 /**
531  * @tc.name: LazyForEachThrowRepeatOperationErrorTest001
532  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
533  * @tc.type: FUNC
534  */
535 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachThrowRepeatOperationErrorTest001, TestSize.Level1)
536 {
537     /**
538      * @tc.steps: step1. Create Text and push it to view stack processor.
539      * @tc.expected: Make Text as LazyForEach parent.
540      */
541     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
542 
543     /**
544      * @tc.steps: step2. Invoke lazyForEach Create function.
545      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
546      */
547     LazyForEachModelNG lazyForEach;
548     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
549         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
550     lazyForEach.Create(mockLazyForEachActuator);
551     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
552     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
553         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
554     }
555 
556     lazyForEachBuilder->ThrowRepeatOperationError(INDEX_0);
557 }
558 
559 /**
560  * @tc.name: LazyForEachRecycleChildByIndexTest001
561  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
562  * @tc.type: FUNC
563  */
564 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachRecycleChildByIndexTest001, TestSize.Level1)
565 {
566     /**
567      * @tc.steps: step1. Create Text and push it to view stack processor.
568      * @tc.expected: Make Text as LazyForEach parent.
569      */
570     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
571 
572     /**
573      * @tc.steps: step2. Invoke lazyForEach Create function.
574      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
575      */
576     LazyForEachModelNG lazyForEach;
577     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
578         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
579     lazyForEach.Create(mockLazyForEachActuator);
580     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
581     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
582         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
583     }
584 
585     std::list<V2::Operation> DataOperations;
586     V2::Operation operation1 = {.type = "add", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(1, 3)};
587     DataOperations.push_back(operation1);
588     lazyForEachBuilder->OnDatasetChange(DataOperations);
589     lazyForEachBuilder->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
590 
591     lazyForEachBuilder->RecycleChildByIndex(INDEX_1);
592 
593     lazyForEachBuilder->RecycleChildByIndex(8);
594 }
595 
596 /**
597  * @tc.name: LazyForEachRecordOutOfBoundaryNodesTest001
598  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
599  * @tc.type: FUNC
600  */
601 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachRecordOutOfBoundaryNodesTest001, TestSize.Level1)
602 {
603     /**
604      * @tc.steps: step1. Create Text and push it to view stack processor.
605      * @tc.expected: Make Text as LazyForEach parent.
606      */
607     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
608 
609     /**
610      * @tc.steps: step2. Invoke lazyForEach Create function.
611      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
612      */
613     LazyForEachModelNG lazyForEach;
614     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
615         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
616     lazyForEach.Create(mockLazyForEachActuator);
617     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
618     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
619         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
620     }
621 
622     lazyForEachBuilder->RecordOutOfBoundaryNodes(INDEX_0);
623 }
624 
625 /**
626  * @tc.name: LazyForEachRecycleItemsOutOfBoundaryTest001
627  * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
628  * @tc.type: FUNC
629  */
630 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachRecycleItemsOutOfBoundaryTest001, TestSize.Level1)
631 {
632     /**
633      * @tc.steps: step1. Create Text and push it to view stack processor.
634      * @tc.expected: Make Text as LazyForEach parent.
635      */
636     auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
637 
638     /**
639      * @tc.steps: step2. Invoke lazyForEach Create function.
640      * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
641      */
642     LazyForEachModelNG lazyForEach;
643     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
644         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
645     lazyForEach.Create(mockLazyForEachActuator);
646     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
647     for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
648         lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
649     }
650 
651     lazyForEachBuilder->outOfBoundaryNodes_ = LAZY_FOR_EACH_ITEMS;
652     lazyForEachBuilder->RecycleItemsOutOfBoundary();
653 }
654 
655 /**
656  * @tc.name: LazyForEachBuilder01
657  * @tc.desc: LazyForEachBuilder::GetChildByIndex
658  * @tc.type: FUNC
659  */
660 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder01, TestSize.Level1)
661 {
662     LazyForEachModelNG lazyForEach;
663     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
664         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
665     lazyForEach.Create(mockLazyForEachActuator);
666     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
667 
668     /**
669      * @tc.steps: step1. iter->second.second == nullptr;
670      */
671     std::string str0 = "0";
672     lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
673     auto step1 = lazyForEachBuilder->GetChildByIndex(0, true);
674     EXPECT_EQ(step1.first.size(), 1);
675 
676     /**
677      * @tc.steps: step2. keyIter != expiringItem_.end(), keyIter->second.second == nullptr;
678      */
679     std::string str1 = "1";
680     lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
681     lazyForEachBuilder->expiringItem_[str1] = LazyForEachCacheChild(1, nullptr);
682     auto step2 = lazyForEachBuilder->GetChildByIndex(1, true);
683     EXPECT_EQ(step2.first.size(), 1);
684 
685     /**
686      * @tc.steps: step3. keyIter != expiringItem_.end(), keyIter->second.second != nullptr;
687      */
688     auto iter02 = lazyForEachBuilder->cachedItems_.find(0);
689     std::string str2 = "2";
690     lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
691     lazyForEachBuilder->expiringItem_[str2] = LazyForEachCacheChild(2, iter02->second.second);
692     auto step3 = lazyForEachBuilder->GetChildByIndex(2, true);
693     EXPECT_EQ(step3.first.size(), 1);
694 
695     /**
696      * @tc.steps: step4. isCache == true;
697      */
698     auto iter03 = lazyForEachBuilder->cachedItems_.find(0);
699     std::string str3 = "3";
700     lazyForEachBuilder->cachedItems_[3] = LazyForEachChild(str3, nullptr);
701     lazyForEachBuilder->expiringItem_[str3] = LazyForEachCacheChild(3, iter03->second.second);
702     auto step4 = lazyForEachBuilder->GetChildByIndex(3, true, true);
703     EXPECT_EQ(step4.first.size(), 1);
704 
705     /**
706      * @tc.steps: step5. needBuild == false;
707      */
708     std::string str4 = "4";
709     lazyForEachBuilder->cachedItems_[4] = LazyForEachChild(str4, nullptr);
710     auto step5 = lazyForEachBuilder->GetChildByIndex(4, false);
711     EXPECT_EQ(step5.first.size(), 0);
712 
713     /**
714      * @tc.steps: step6. useNewInterface_ == true, isCache == true;
715      */
716     std::string str5 = "5";
717     lazyForEachBuilder->cachedItems_[5] = LazyForEachChild(str5, nullptr);
718     lazyForEachBuilder->useNewInterface_ = true;
719     auto step6 = lazyForEachBuilder->GetChildByIndex(5, true, true);
720     EXPECT_EQ(step6.first.size(), 1);
721 }
722 
723 /**
724  * @tc.name: LazyForEachBuilder02
725  * @tc.desc: LazyForEachBuilder::ConvertFormToIndex
726  * @tc.type: FUNC
727  */
728 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder02, TestSize.Level1)
729 {
730     LazyForEachModelNG lazyForEach;
731     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
732         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
733     lazyForEach.Create(mockLazyForEachActuator);
734     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
735 
736     /**
737      * @tc.steps: step1. !moveFromTo_;
738      */
739     auto step1 = lazyForEachBuilder->ConvertFormToIndex(0);
740     EXPECT_EQ(step1, 0);
741 
742     /**
743      * @tc.steps: step2. (1, 1);
744      */
745     lazyForEachBuilder->moveFromTo_.emplace(1, 1);
746     auto step2 = lazyForEachBuilder->ConvertFormToIndex(0);
747     EXPECT_EQ(step2, 0);
748 
749     /**
750      * @tc.steps: step3. moveFromTo_.value().second == index;
751      */
752     lazyForEachBuilder->moveFromTo_.value().second = 0;
753     auto step3 = lazyForEachBuilder->ConvertFormToIndex(0);
754     EXPECT_EQ(step3, 1);
755 
756     /**
757      * @tc.steps: step4. (0, 0);
758      */
759     lazyForEachBuilder->moveFromTo_.value().first = 0;
760     lazyForEachBuilder->moveFromTo_.value().second = 0;
761     auto step4 = lazyForEachBuilder->ConvertFormToIndex(1);
762     EXPECT_EQ(step4, 1);
763 
764     /**
765      * @tc.steps: step5. (0, 2);
766      */
767     lazyForEachBuilder->moveFromTo_.value().first = 0;
768     lazyForEachBuilder->moveFromTo_.value().second = 2;
769     auto step5 = lazyForEachBuilder->ConvertFormToIndex(1);
770     EXPECT_EQ(step5, 2);
771 
772     /**
773      * @tc.steps: step6. (2, 0);
774      */
775     lazyForEachBuilder->moveFromTo_.value().first = 2;
776     lazyForEachBuilder->moveFromTo_.value().second = 0;
777     auto step6 = lazyForEachBuilder->ConvertFormToIndex(1);
778     EXPECT_EQ(step6, 0);
779 }
780 
781 /**
782  * @tc.name: LazyForEachBuilder03
783  * @tc.desc: LazyForEachBuilder::PreBuild
784  * @tc.type: FUNC
785  */
786 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder03, TestSize.Level1)
787 {
788     LazyForEachModelNG lazyForEach;
789     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
790         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
791     lazyForEach.Create(mockLazyForEachActuator);
792     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
793     LayoutConstraintF layoutConstraint;
794 
795     /**
796      * @tc.steps: step1. all == false;
797      */
798     auto step1 = lazyForEachBuilder->PreBuild(10, layoutConstraint, true);
799     EXPECT_TRUE(step1);
800 
801     /**
802      * @tc.steps: step2. itemConstraint, startIndex_ != -1;
803      */
804     layoutConstraint.parentIdealSize = OptionalSizeF(768, 1024);
805     layoutConstraint.selfIdealSize = OptionalSizeF(480, 960);
806     lazyForEachBuilder->startIndex_ = 3;
807     auto step2 = lazyForEachBuilder->PreBuild(10, layoutConstraint, true);
808     EXPECT_TRUE(step2);
809 
810     /**
811      * @tc.steps: step3. startIndex_ != -1 && endIndex_ != -1;
812      */
813     lazyForEachBuilder->endIndex_ = 1;
814     auto step3 = lazyForEachBuilder->PreBuild(10, layoutConstraint, true);
815     EXPECT_TRUE(step3);
816 
817     /**
818      * @tc.steps: step4. !canRunLongPredictTask;
819      */
820     auto step4 = lazyForEachBuilder->PreBuild(10, layoutConstraint, false);
821     EXPECT_FALSE(step4);
822 }
823 
824 /**
825  * @tc.name: LazyForEachBuilder04
826  * @tc.desc: LazyForEachBuilder::OnDataBulkChanged
827  * @tc.type: FUNC
828  */
829 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder04, TestSize.Level1)
830 {
831     LazyForEachModelNG lazyForEach;
832     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
833         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
834     lazyForEach.Create(mockLazyForEachActuator);
835     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
836 
837     /**
838      * @tc.steps: step1. cachedItems_.empty();
839      */
840     auto step1 = lazyForEachBuilder->OnDataBulkChanged(0, 0);
841     EXPECT_EQ(step1.size(), 0);
842 
843     /**
844      * @tc.steps: step1. node.first;
845      */
846     std::string str0 = "0";
847     lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
848     lazyForEachBuilder->expiringItem_[str0] = LazyForEachCacheChild(2, nullptr);
849     std::string str1 = "1";
850     lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
851     lazyForEachBuilder->expiringItem_[str1] = LazyForEachCacheChild(7, nullptr);
852     std::string str2 = "2";
853     lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
854     lazyForEachBuilder->expiringItem_[str2] = LazyForEachCacheChild(0, nullptr);
855     lazyForEachBuilder->OnDataBulkChanged(1, 5);
856     EXPECT_EQ(lazyForEachBuilder->expiringItem_[str0].first, -1);
857     EXPECT_EQ(lazyForEachBuilder->expiringItem_[str1].first, 7);
858     EXPECT_EQ(lazyForEachBuilder->expiringItem_[str2].first, 0);
859 }
860 
861 /**
862  * @tc.name: LazyForEachBuilder05
863  * @tc.desc: LazyForEachBuilder::RecycleChildByIndex
864  * @tc.type: FUNC
865  */
866 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder05, TestSize.Level1)
867 {
868     LazyForEachModelNG lazyForEach;
869     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
870         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
871     lazyForEach.Create(mockLazyForEachActuator);
872     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
873 
874     /**
875      * @tc.steps: step1. !iter->second.second;
876      */
877     std::string str0 = "0";
878     lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
879     lazyForEachBuilder->RecycleChildByIndex(0);
880     EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 1);
881 
882     /**
883      * @tc.steps: step2. !dummyNode;
884      */
885     std::string str1 = "1";
886     lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
887     lazyForEachBuilder->GetChildByIndex(1, true);
888     lazyForEachBuilder->RecycleChildByIndex(1);
889     EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 2);
890 
891     /**
892      * @tc.steps: step3. dummyNode;
893      */
894     std::string str2 = "2";
895     lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
896     lazyForEachBuilder->GetChildByIndex(2, true);
897     auto iter = lazyForEachBuilder->cachedItems_.find(2);
898     iter->second.second->SetNeedCallChildrenUpdate(true);
899     iter->second.second->debugLine_ = str2;
900     lazyForEachBuilder->RecycleChildByIndex(2);
901     EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 3);
902 }
903 
904 /**
905  * @tc.name: LazyForEachBuilder06
906  * @tc.desc: LazyForEachBuilder::OnDataBulkDeleted
907  * @tc.type: FUNC
908  */
909 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder06, TestSize.Level1)
910 {
911     LazyForEachModelNG lazyForEach;
912     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
913         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
914     lazyForEach.Create(mockLazyForEachActuator);
915     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
916 
917     /**
918      * @tc.steps: step1. Override the branch of the judgment expiringItem_;
919      */
920     std::string str1 = "1";
921     std::string str2 = "3";
922     lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
923     lazyForEachBuilder->expiringItem_[str1] = LazyForEachCacheChild(1, nullptr);
924     lazyForEachBuilder->expiringItem_[str2] = LazyForEachCacheChild(3, nullptr);
925     lazyForEachBuilder->OnDataBulkDeleted(2, 5);
926     EXPECT_EQ(lazyForEachBuilder->nodeList_.size(), 0);
927 
928     /**
929      * @tc.steps: step1. Override the branch of the judgment cachedItems_;
930      */
931     lazyForEachBuilder->cachedItems_[3] = LazyForEachChild(str2, nullptr);
932     lazyForEachBuilder->OnDataBulkDeleted(2, 5);
933     EXPECT_NE(lazyForEachBuilder->nodeList_.size(), 0);
934 }
935 
936 /**
937  * @tc.name: LazyForEachBuilder07
938  * @tc.desc: LazyForEachBuilder::OnDataBulkDeleted
939  * @tc.type: FUNC
940  */
941 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder07, TestSize.Level1)
942 {
943     LazyForEachModelNG lazyForEach;
944     const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
945         AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
946     lazyForEach.Create(mockLazyForEachActuator);
947     auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
948 
949     /**
950      * @tc.steps: step1. operation.index >= totalCountOfOriginalDataset_;
951      */
952     V2::Operation operation;
953     operation.index = 0;
954     int32_t initialIndex = 0;
955     std::map<int32_t, LazyForEachChild> cachedTemp;
956     std::map<int32_t, LazyForEachChild> expiringTemp;
957     lazyForEachBuilder->OperateChange(operation, initialIndex, cachedTemp, expiringTemp);
958     EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 0);
959 
960     /**
961      * @tc.steps: step2. !indexExist == operationList_.end();
962      */
963     lazyForEachBuilder->totalCountOfOriginalDataset_ = 1;
964     OperationInfo operationinfo;
965     lazyForEachBuilder->operationList_[1] = operationinfo;
966     lazyForEachBuilder->OperateChange(operation, initialIndex, cachedTemp, expiringTemp);
967     EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 1);
968 
969     /**
970      * @tc.steps: step3. !operation.key.empty();
971      */
972     std::string str0 = "0";
973     expiringTemp[0] = LazyForEachChild(str0, nullptr);
974     cachedTemp[0] = LazyForEachChild(str0, nullptr);
975     operation.key = "0";
976     lazyForEachBuilder->OperateChange(operation, initialIndex, cachedTemp, expiringTemp);
977     EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 2);
978 
979     /**
980      * @tc.steps: step4. !indexExist == operationList_.end();
981      */
982     lazyForEachBuilder->operationList_[0] = operationinfo;
983     lazyForEachBuilder->OperateChange(operation, initialIndex, cachedTemp, expiringTemp);
984     EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 2);
985 }
986 } // namespace OHOS::Ace::NG
987