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