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
CreateLazyForEachBuilder(bool deleteExpiringItemImmediately=false)102 static RefPtr<LazyForEachBuilder> CreateLazyForEachBuilder(bool deleteExpiringItemImmediately = false)
103 {
104 /**
105 * @tc.steps: step1. Create Text and push it to view stack processor.
106 * @tc.expected: Make Text as LazyForEach parent.
107 */
108 auto pattern = AceType::MakeRefPtr<Pattern>();
109 if (!pattern) {
110 return nullptr;
111 }
112 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::TEXT_ETS_TAG, -1, pattern);
113 if (!frameNode) {
114 return nullptr;
115 }
116 pattern->AttachToFrameNode(frameNode);
117 ViewStackProcessor::GetInstance()->Push(frameNode);
118
119 /**
120 * @tc.steps: step2. Invoke lazyForEach Create function.
121 * @tc.expected: Create lazyForEachBuilder and can be pop from ViewStackProcessor.
122 */
123 LazyForEachModelNG lazyForEach;
124 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
125 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>(deleteExpiringItemImmediately);
126 if (!mockLazyForEachActuator) {
127 return nullptr;
128 }
129 lazyForEach.Create(mockLazyForEachActuator);
130 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
131 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
132 /**
133 * @tc.steps: step3. Add children items to lazyForEachNode.
134 */
135 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
136 return lazyForEachBuilder;
137 }
138 };
139
SetUp()140 void LazyForEachSyntaxTestNg::SetUp()
141 {
142 MockPipelineContext::SetUp();
143 }
144
TearDown()145 void LazyForEachSyntaxTestNg::TearDown()
146 {
147 MockPipelineContext::TearDown();
148 }
149
CreateNode(const std::string & tag)150 RefPtr<FrameNode> LazyForEachSyntaxTestNg::CreateNode(const std::string& tag)
151 {
152 auto pattern = AceType::MakeRefPtr<Pattern>();
153 auto frameNode = AceType::MakeRefPtr<FrameNode>(tag, -1, pattern);
154 pattern->AttachToFrameNode(frameNode);
155 ViewStackProcessor::GetInstance()->Push(frameNode);
156 return frameNode;
157 }
158
159 /**
160 * @tc.name: LazyForEachOnDataBulkChangedTest001
161 * @tc.desc: Create LazyForEach.
162 * @tc.type: FUNC
163 */
164 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDataBulkChangedTest001, TestSize.Level1)
165 {
166 /**
167 * @tc.steps: step1. Create Text and push it to view stack processor.
168 * @tc.expected: Make Text as LazyForEach parent.
169 */
170 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
171
172 /**
173 * @tc.steps: step2. Invoke lazyForEach Create function.
174 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
175 */
176 LazyForEachModelNG lazyForEach;
177 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
178 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
179 lazyForEach.Create(mockLazyForEachActuator);
180 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
181 ASSERT_NE(lazyForEachNode, nullptr);
182 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
183 ASSERT_NE(lazyForEachBuilder, nullptr);
184
185 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
186 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
187 }
188
189 lazyForEachNode->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
190 lazyForEachNode->OnDataBulkChanged(INDEX_EQUAL_WITH_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
191
192 lazyForEachNode->builder_ = nullptr;
193 lazyForEachNode->OnDataAdded(INDEX_EQUAL_WITH_START_INDEX);
194 lazyForEachNode->OnDataBulkChanged(INDEX_EQUAL_WITH_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
195 }
196
197 /**
198 * @tc.name: LazyForEachOnDataMoveToNewPlaceTest001
199 * @tc.desc: Create LazyForEach.
200 * @tc.type: FUNC
201 */
202 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDataMoveToNewPlaceTest001, TestSize.Level1)
203 {
204 /**
205 * @tc.steps: step1. Create Text and push it to view stack processor.
206 * @tc.expected: Make Text as LazyForEach parent.
207 */
208 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
209
210 /**
211 * @tc.steps: step2. Invoke lazyForEach Create function.
212 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
213 */
214 LazyForEachModelNG lazyForEach;
215 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
216 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
217 lazyForEach.Create(mockLazyForEachActuator);
218 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
219 ASSERT_NE(lazyForEachNode, nullptr);
220 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
221 ASSERT_NE(lazyForEachBuilder, nullptr);
222
223 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
224 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
225 }
226
227 lazyForEachNode->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
228 lazyForEachNode->OnDataMoveToNewPlace(INDEX_EQUAL_WITH_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
229 lazyForEachNode->OnDataMoveToNewPlace(INDEX_EQUAL_WITH_START_INDEX, INDEX_EQUAL_WITH_START_INDEX);
230 lazyForEachNode->OnDataMoveToNewPlace(INDEX_GREATER_THAN_END_INDEX, INDEX_EQUAL_WITH_START_INDEX);
231 lazyForEachNode->OnDataMoveToNewPlace(INDEX_GREATER_THAN_END_INDEX, INDEX_GREATER_THAN_END_INDEX);
232
233 lazyForEachNode->builder_ = nullptr;
234 lazyForEachNode->OnDataAdded(INDEX_EQUAL_WITH_START_INDEX);
235 lazyForEachNode->OnDataMoveToNewPlace(INDEX_EQUAL_WITH_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
236 lazyForEachNode->OnDataMoveToNewPlace(INDEX_EQUAL_WITH_START_INDEX, INDEX_EQUAL_WITH_START_INDEX);
237 }
238
239 /**
240 * @tc.name: LazyForEachOnDatasetChangeTest001
241 * @tc.desc: Create LazyForEach.
242 * @tc.type: FUNC
243 */
244 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDatasetChangeTest001, TestSize.Level1)
245 {
246 /**
247 * @tc.steps: step1. Create Text and push it to view stack processor.
248 * @tc.expected: Make Text as LazyForEach parent.
249 */
250 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
251
252 /**
253 * @tc.steps: step2. Invoke lazyForEach Create function.
254 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
255 */
256 LazyForEachModelNG lazyForEach;
257 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
258 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
259 lazyForEach.Create(mockLazyForEachActuator);
260 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
261 ASSERT_NE(lazyForEachNode, nullptr);
262 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
263 ASSERT_NE(lazyForEachBuilder, nullptr);
264
265 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
266 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
267 }
268 lazyForEachBuilder->OnDataAdded(INDEX_0);
269 std::list<V2::Operation> DataOperations;
270 V2::Operation operation1 = {.type = "text"};
271 DataOperations.push_back(operation1);
272 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
273 lazyForEachNode->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
274 lazyForEachNode->OnDatasetChange(DataOperations);
275 lazyForEachNode->builder_ = nullptr;
276 lazyForEachNode->OnDatasetChange(DataOperations);
277 }
278
279 /**
280 * @tc.name: LazyForEachOnDatasetChangeTest002
281 * @tc.desc: Test OnDatasetChange.
282 * @tc.type: FUNC
283 */
284 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDatasetChangeTest002, TestSize.Level1)
285 {
286 /**
287 * @tc.steps: step1. Create LazyForEachNode
288 * @tc.expected: Create LazyForEachNode success.
289 */
290 auto lazyForEachNode = CreateLazyForEachNode();
291 ASSERT_NE(lazyForEachNode, nullptr);
292 auto lazyForEachBuilder = lazyForEachNode->builder_;
293 ASSERT_NE(lazyForEachBuilder, nullptr);
294 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
295 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
296 }
297 /**
298 * @tc.steps: step2. Invoke OnDatasetChange function.
299 * @tc.expected: Create delete operation and Invoke OnDatasetChange function.
300 */
301 lazyForEachBuilder->UpdateHistoricalTotalCount(lazyForEachBuilder->GetTotalCount());
302 std::list<V2::Operation> DataOperations;
303 V2::Operation operation1 = { .type = "delete", .index = INDEX_0, .count = 1 };
304 DataOperations.push_back(operation1);
305 lazyForEachNode->OnDatasetChange(DataOperations);
306 auto pipeline = PipelineContext::GetCurrentContext();
307 ASSERT_NE(pipeline, nullptr);
308 pipeline->FlushBuild();
309 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 6);
310 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
311 }
312
313 /**
314 * @tc.name: LazyForEachGetFrameChildByIndexTest001
315 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
316 * @tc.type: FUNC
317 */
318 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachGetFrameChildByIndexTest001, TestSize.Level1)
319 {
320 /**
321 * @tc.steps: step1. Create Text and push it to view stack processor.
322 * @tc.expected: Make Text as LazyForEach parent.
323 */
324 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
325
326 /**
327 * @tc.steps: step2. Invoke lazyForEach Create function.
328 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
329 */
330 LazyForEachModelNG lazyForEach;
331 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
332 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
333 lazyForEach.Create(mockLazyForEachActuator);
334 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
335 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
336 ASSERT_NE(lazyForEachBuilder, nullptr);
337 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
338
339 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
340
341 lazyForEachNode->GetFrameChildByIndex(0, true, true);
342 EXPECT_TRUE(lazyForEachNode->ids_.empty());
343 }
344
345 /**
346 * @tc.name: LazyForEachOnDataBulkChangedTest002
347 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
348 * @tc.type: FUNC
349 */
350 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDataBulkChangedTest002, TestSize.Level1)
351 {
352 /**
353 * @tc.steps: step1. Create Text and push it to view stack processor.
354 * @tc.expected: Make Text as LazyForEach parent.
355 */
356 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
357
358 /**
359 * @tc.steps: step2. Invoke lazyForEach Create function.
360 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
361 */
362 LazyForEachModelNG lazyForEach;
363 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
364 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
365 lazyForEach.Create(mockLazyForEachActuator);
366 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
367 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
368 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
369 }
370 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
371 lazyForEachBuilder->OnDataBulkChanged(0, 5);
372 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 2);
373 lazyForEachBuilder->OnDataBulkChanged(10, 20);
374 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 2);
375 }
376
377 /**
378 * @tc.name: LazyForEachCollectIndexChangedCountTest001
379 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
380 * @tc.type: FUNC
381 */
382 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachCollectIndexChangedCountTest001, TestSize.Level1)
383 {
384 /**
385 * @tc.steps: step1. Create Text and push it to view stack processor.
386 * @tc.expected: Make Text as LazyForEach parent.
387 */
388 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
389
390 /**
391 * @tc.steps: step2. Invoke lazyForEach Create function.
392 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
393 */
394 LazyForEachModelNG lazyForEach;
395 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
396 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
397 lazyForEach.Create(mockLazyForEachActuator);
398 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
399 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
400 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
401 }
402
403 std::map<int32_t, OperationInfo> operationList;
404 OperationInfo itemInfo;
405 operationList[7] = itemInfo;
406 operationList[8] = itemInfo;
407
408 std::map<int32_t, int32_t> indexChangedMap;
409 indexChangedMap[1] = 1;
410 indexChangedMap[2] = 2;
411 indexChangedMap[3] = 3;
412 indexChangedMap[4] = 4;
413 indexChangedMap[5] = 5;
414 indexChangedMap[6] = 6;
415
416 lazyForEachBuilder->operationList_ = operationList;
417 EXPECT_EQ(indexChangedMap.size(), 6);
418 lazyForEachBuilder->CollectIndexChangedCount(indexChangedMap);
419 EXPECT_EQ(indexChangedMap.size(), 8);
420 }
421
422 /**
423 * @tc.name: LazyForEachOperateDeleteTest001
424 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
425 * @tc.type: FUNC
426 */
427 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateDeleteTest001, TestSize.Level1)
428 {
429 /**
430 * @tc.steps: step1. Create Text and push it to view stack processor.
431 * @tc.expected: Make Text as LazyForEach parent.
432 */
433 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
434
435 /**
436 * @tc.steps: step2. Invoke lazyForEach Create function.
437 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
438 */
439 LazyForEachModelNG lazyForEach;
440 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
441 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
442 lazyForEach.Create(mockLazyForEachActuator);
443 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
444 ASSERT_NE(lazyForEachBuilder, nullptr);
445 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
446 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
447 }
448
449 V2::Operation operation1 = {.type = "delete", .index = INDEX_0, .count = INDEX_8};
450 int32_t num;
451 num = 1;
452 lazyForEachBuilder->OperateDelete(operation1, num);
453
454 V2::Operation operation2 = {.type = "delete", .index = INDEX_8, .count = INDEX_8};
455 lazyForEachBuilder->OperateDelete(operation2, num);
456 }
457
458 /**
459 * @tc.name: LazyForEachOperateChangeTest001
460 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
461 * @tc.type: FUNC
462 */
463 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateChangeTest001, TestSize.Level1)
464 {
465 /**
466 * @tc.steps: step1. Create Text and push it to view stack processor.
467 * @tc.expected: Make Text as LazyForEach parent.
468 */
469 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
470
471 /**
472 * @tc.steps: step2. Invoke lazyForEach Create function.
473 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
474 */
475 LazyForEachModelNG lazyForEach;
476 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
477 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
478 lazyForEach.Create(mockLazyForEachActuator);
479 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
480 ASSERT_NE(lazyForEachBuilder, nullptr);
481 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
482 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
483 }
484
485 std::list<V2::Operation> DataOperations;
486 V2::Operation operation1 = {.type = "change", .index = INDEX_0, .count = INDEX_8};
487 DataOperations.push_back(operation1);
488 lazyForEachBuilder->OnDatasetChange(DataOperations);
489 }
490
491 /**
492 * @tc.name: LazyForEachOperateMoveTest001
493 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
494 * @tc.type: FUNC
495 */
496 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateMoveTest001, TestSize.Level1)
497 {
498 /**
499 * @tc.steps: step1. Create Text and push it to view stack processor.
500 * @tc.expected: Make Text as LazyForEach parent.
501 */
502 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
503
504 /**
505 * @tc.steps: step2. Invoke lazyForEach Create function.
506 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
507 */
508 LazyForEachModelNG lazyForEach;
509 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
510 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
511 lazyForEach.Create(mockLazyForEachActuator);
512 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
513 ASSERT_NE(lazyForEachBuilder, nullptr);
514 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
515 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
516 }
517
518 std::list<V2::Operation> DataOperations;
519 V2::Operation operation1 = {.type = "move", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(8, 8)};
520 DataOperations.push_back(operation1);
521 lazyForEachBuilder->OnDatasetChange(DataOperations);
522
523 std::list<V2::Operation> DataOperations1;
524 V2::Operation operation2 = {.type = "move", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(0, 8)};
525 DataOperations1.push_back(operation2);
526 lazyForEachBuilder->OnDatasetChange(DataOperations1);
527
528 std::list<V2::Operation> DataOperations2;
529 V2::Operation operation3 = {.type = "move", .index = INDEX_3, .key = "", .coupleIndex = std::pair(0, 1)};
530 DataOperations2.push_back(operation3);
531 lazyForEachBuilder->OnDatasetChange(DataOperations2);
532 }
533
534 /**
535 * @tc.name: LazyForEachOperateExchangeTest001
536 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
537 * @tc.type: FUNC
538 */
539 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateExchangeTest001, TestSize.Level1)
540 {
541 /**
542 * @tc.steps: step1. Create Text and push it to view stack processor.
543 * @tc.expected: Make Text as LazyForEach parent.
544 */
545 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
546
547 /**
548 * @tc.steps: step2. Invoke lazyForEach Create function.
549 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
550 */
551 LazyForEachModelNG lazyForEach;
552 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
553 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
554 lazyForEach.Create(mockLazyForEachActuator);
555 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
556 ASSERT_NE(lazyForEachBuilder, nullptr);
557 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
558 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
559 }
560
561 std::list<V2::Operation> DataOperations;
562 V2::Operation operation1 = {.type = "exchange", .index = INDEX_0, .count = INDEX_8,
563 .coupleIndex = std::pair(1, 3)};
564 DataOperations.push_back(operation1);
565 lazyForEachBuilder->OnDatasetChange(DataOperations);
566
567 std::list<V2::Operation> DataOperations1;
568 V2::Operation operation2 = {.type = "exchange", .index = INDEX_0, .count = INDEX_8,
569 .coupleIndex = std::pair(20, 3)};
570 DataOperations1.push_back(operation2);
571 lazyForEachBuilder->OnDatasetChange(DataOperations1);
572
573 std::list<V2::Operation> DataOperations2;
574 V2::Operation operation3 = {.type = "exchange", .index = INDEX_3, .coupleKey = std::pair("", ""),
575 .coupleIndex = std::pair(0, 20)};
576 DataOperations2.push_back(operation3);
577 lazyForEachBuilder->OnDatasetChange(DataOperations2);
578
579 std::list<V2::Operation> DataOperations3;
580 V2::Operation operation4 = {.type = "exchange", .index = INDEX_3, .coupleKey = std::pair("1", "1"),
581 .coupleIndex = std::pair(0, 20)};
582 DataOperations3.push_back(operation4);
583 lazyForEachBuilder->OnDatasetChange(DataOperations3);
584 }
585
586 /**
587 * @tc.name: LazyForEachOperateReloadTest001
588 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
589 * @tc.type: FUNC
590 */
591 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOperateReloadTest001, TestSize.Level1)
592 {
593 /**
594 * @tc.steps: step1. Create Text and push it to view stack processor.
595 * @tc.expected: Make Text as LazyForEach parent.
596 */
597 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
598
599 /**
600 * @tc.steps: step2. Invoke lazyForEach Create function.
601 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
602 */
603 LazyForEachModelNG lazyForEach;
604 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
605 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
606 lazyForEach.Create(mockLazyForEachActuator);
607 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
608 ASSERT_NE(lazyForEachBuilder, nullptr);
609 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
610 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
611 }
612
613 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
614 std::list<V2::Operation> DataOperations;
615 V2::Operation operation1 = {.type = "reload", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(1, 3)};
616 DataOperations.push_back(operation1);
617 lazyForEachBuilder->OnDatasetChange(DataOperations);
618 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 0);
619 }
620
621 /**
622 * @tc.name: LazyForEachThrowRepeatOperationErrorTest001
623 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
624 * @tc.type: FUNC
625 */
626 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachThrowRepeatOperationErrorTest001, TestSize.Level1)
627 {
628 /**
629 * @tc.steps: step1. Create Text and push it to view stack processor.
630 * @tc.expected: Make Text as LazyForEach parent.
631 */
632 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
633
634 /**
635 * @tc.steps: step2. Invoke lazyForEach Create function.
636 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
637 */
638 LazyForEachModelNG lazyForEach;
639 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
640 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
641 lazyForEach.Create(mockLazyForEachActuator);
642 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
643 ASSERT_NE(lazyForEachBuilder, nullptr);
644 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
645 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
646 }
647
648 lazyForEachBuilder->ThrowRepeatOperationError(INDEX_0);
649 }
650
651 /**
652 * @tc.name: LazyForEachRecycleChildByIndexTest001
653 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
654 * @tc.type: FUNC
655 */
656 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachRecycleChildByIndexTest001, TestSize.Level1)
657 {
658 /**
659 * @tc.steps: step1. Create Text and push it to view stack processor.
660 * @tc.expected: Make Text as LazyForEach parent.
661 */
662 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
663
664 /**
665 * @tc.steps: step2. Invoke lazyForEach Create function.
666 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
667 */
668 LazyForEachModelNG lazyForEach;
669 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
670 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
671 lazyForEach.Create(mockLazyForEachActuator);
672 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
673 ASSERT_NE(lazyForEachBuilder, nullptr);
674 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
675 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
676 }
677
678 std::list<V2::Operation> DataOperations;
679 V2::Operation operation1 = {.type = "add", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(1, 3)};
680 DataOperations.push_back(operation1);
681 lazyForEachBuilder->OnDatasetChange(DataOperations);
682 lazyForEachBuilder->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
683
684 lazyForEachBuilder->RecycleChildByIndex(INDEX_1);
685
686 lazyForEachBuilder->RecycleChildByIndex(8);
687 }
688
689 /**
690 * @tc.name: LazyForEachRecordOutOfBoundaryNodesTest001
691 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
692 * @tc.type: FUNC
693 */
694 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachRecordOutOfBoundaryNodesTest001, TestSize.Level1)
695 {
696 /**
697 * @tc.steps: step1. Create Text and push it to view stack processor.
698 * @tc.expected: Make Text as LazyForEach parent.
699 */
700 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
701
702 /**
703 * @tc.steps: step2. Invoke lazyForEach Create function.
704 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
705 */
706 LazyForEachModelNG lazyForEach;
707 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
708 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
709 lazyForEach.Create(mockLazyForEachActuator);
710 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
711 ASSERT_NE(lazyForEachBuilder, nullptr);
712 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
713 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
714 }
715
716 EXPECT_EQ(lazyForEachBuilder->outOfBoundaryNodes_.size(), 0);
717 lazyForEachBuilder->RecordOutOfBoundaryNodes(INDEX_0);
718 EXPECT_EQ(lazyForEachBuilder->outOfBoundaryNodes_.size(), 1);
719 }
720
721 /**
722 * @tc.name: LazyForEachRecycleItemsOutOfBoundaryTest001
723 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
724 * @tc.type: FUNC
725 */
726 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachRecycleItemsOutOfBoundaryTest001, TestSize.Level1)
727 {
728 /**
729 * @tc.steps: step1. Create Text and push it to view stack processor.
730 * @tc.expected: Make Text as LazyForEach parent.
731 */
732 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
733
734 /**
735 * @tc.steps: step2. Invoke lazyForEach Create function.
736 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
737 */
738 LazyForEachModelNG lazyForEach;
739 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
740 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
741 lazyForEach.Create(mockLazyForEachActuator);
742 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
743 ASSERT_NE(lazyForEachBuilder, nullptr);
744 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
745 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
746 }
747
748 lazyForEachBuilder->outOfBoundaryNodes_ = LAZY_FOR_EACH_ITEMS;
749 EXPECT_EQ(lazyForEachBuilder->outOfBoundaryNodes_.size(), LAZY_FOR_EACH_ITEMS.size());
750 lazyForEachBuilder->RecycleItemsOutOfBoundary();
751 EXPECT_EQ(lazyForEachBuilder->outOfBoundaryNodes_.size(), 0);
752 }
753
754 /**
755 * @tc.name: LazyForEachOnDataDeletedTest001
756 * @tc.desc: Test OnDataDeleted.
757 * @tc.type: FUNC
758 */
759 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachOnDataDeletedTest001, TestSize.Level1)
760 {
761 /**
762 * @tc.steps: step1. Create LazyForEachNode
763 * @tc.expected: Create LazyForEachNode success.
764 */
765 auto lazyForEachNode = CreateLazyForEachNode();
766 ASSERT_NE(lazyForEachNode, nullptr);
767 auto lazyForEachBuilder = lazyForEachNode->builder_;
768 ASSERT_NE(lazyForEachBuilder, nullptr);
769 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
770 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
771 }
772 /**
773 * @tc.steps: step2. Invoke OnDataDeleted function.
774 * @tc.expected: Create delete operation and Invoke OnDataDeleted function.
775 */
776 lazyForEachBuilder->UpdateHistoricalTotalCount(lazyForEachBuilder->GetTotalCount());
777 lazyForEachNode->OnDataDeleted(INDEX_0);
778 auto pipeline = PipelineContext::GetCurrentContext();
779 ASSERT_NE(pipeline, nullptr);
780 pipeline->FlushBuild();
781 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 6);
782 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
783 }
784
785 /**
786 * @tc.name: LazyForEachBuilder01
787 * @tc.desc: LazyForEachBuilder::GetChildByIndex
788 * @tc.type: FUNC
789 */
790 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder01, TestSize.Level1)
791 {
792 LazyForEachModelNG lazyForEach;
793 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
794 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
795 lazyForEach.Create(mockLazyForEachActuator);
796 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
797
798 /**
799 * @tc.steps: step1. iter->second.second == nullptr;
800 */
801 std::string str0 = "0";
802 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
803 auto step1 = lazyForEachBuilder->GetChildByIndex(0, true);
804 EXPECT_EQ(step1.first.size(), 1);
805
806 /**
807 * @tc.steps: step2. keyIter != expiringItem_.end(), keyIter->second.second == nullptr;
808 */
809 std::string str1 = "1";
810 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
811 lazyForEachBuilder->expiringItem_[str1] = LazyForEachCacheChild(1, nullptr);
812 auto step2 = lazyForEachBuilder->GetChildByIndex(1, true);
813 EXPECT_EQ(step2.first.size(), 1);
814
815 /**
816 * @tc.steps: step3. keyIter != expiringItem_.end(), keyIter->second.second != nullptr;
817 */
818 auto iter02 = lazyForEachBuilder->cachedItems_.find(0);
819 std::string str2 = "2";
820 lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
821 lazyForEachBuilder->expiringItem_[str2] = LazyForEachCacheChild(2, iter02->second.second);
822 auto step3 = lazyForEachBuilder->GetChildByIndex(2, true);
823 EXPECT_EQ(step3.first.size(), 1);
824
825 /**
826 * @tc.steps: step4. isCache == true;
827 */
828 auto iter03 = lazyForEachBuilder->cachedItems_.find(0);
829 std::string str3 = "3";
830 lazyForEachBuilder->cachedItems_[3] = LazyForEachChild(str3, nullptr);
831 lazyForEachBuilder->expiringItem_[str3] = LazyForEachCacheChild(3, iter03->second.second);
832 auto step4 = lazyForEachBuilder->GetChildByIndex(3, true, true);
833 EXPECT_EQ(step4.first.size(), 1);
834
835 /**
836 * @tc.steps: step5. needBuild == false;
837 */
838 std::string str4 = "4";
839 lazyForEachBuilder->cachedItems_[4] = LazyForEachChild(str4, nullptr);
840 auto step5 = lazyForEachBuilder->GetChildByIndex(4, false);
841 EXPECT_EQ(step5.first.size(), 0);
842
843 /**
844 * @tc.steps: step6. useNewInterface_ == true, isCache == true;
845 */
846 std::string str5 = "5";
847 lazyForEachBuilder->cachedItems_[5] = LazyForEachChild(str5, nullptr);
848 lazyForEachBuilder->useNewInterface_ = true;
849 auto step6 = lazyForEachBuilder->GetChildByIndex(5, true, true);
850 EXPECT_EQ(step6.first.size(), 1);
851 }
852
853 /**
854 * @tc.name: LazyForEachBuilder02
855 * @tc.desc: LazyForEachBuilder::ConvertFromToIndex
856 * @tc.type: FUNC
857 */
858 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder02, TestSize.Level1)
859 {
860 LazyForEachModelNG lazyForEach;
861 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
862 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
863 lazyForEach.Create(mockLazyForEachActuator);
864 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
865
866 /**
867 * @tc.steps: step1. !moveFromTo_;
868 */
869 auto step1 = lazyForEachBuilder->ConvertFromToIndex(0);
870 EXPECT_EQ(step1, 0);
871
872 /**
873 * @tc.steps: step2. (1, 1);
874 */
875 lazyForEachBuilder->moveFromTo_.emplace(1, 1);
876 auto step2 = lazyForEachBuilder->ConvertFromToIndex(0);
877 EXPECT_EQ(step2, 0);
878
879 /**
880 * @tc.steps: step3. moveFromTo_.value().second == index;
881 */
882 lazyForEachBuilder->moveFromTo_.value().second = 0;
883 auto step3 = lazyForEachBuilder->ConvertFromToIndex(0);
884 EXPECT_EQ(step3, 1);
885
886 /**
887 * @tc.steps: step4. (0, 0);
888 */
889 lazyForEachBuilder->moveFromTo_.value().first = 0;
890 lazyForEachBuilder->moveFromTo_.value().second = 0;
891 auto step4 = lazyForEachBuilder->ConvertFromToIndex(1);
892 EXPECT_EQ(step4, 1);
893
894 /**
895 * @tc.steps: step5. (0, 2);
896 */
897 lazyForEachBuilder->moveFromTo_.value().first = 0;
898 lazyForEachBuilder->moveFromTo_.value().second = 2;
899 auto step5 = lazyForEachBuilder->ConvertFromToIndex(1);
900 EXPECT_EQ(step5, 2);
901
902 /**
903 * @tc.steps: step6. (2, 0);
904 */
905 lazyForEachBuilder->moveFromTo_.value().first = 2;
906 lazyForEachBuilder->moveFromTo_.value().second = 0;
907 auto step6 = lazyForEachBuilder->ConvertFromToIndex(1);
908 EXPECT_EQ(step6, 0);
909 }
910
911 /**
912 * @tc.name: LazyForEachBuilder03
913 * @tc.desc: LazyForEachBuilder::PreBuild
914 * @tc.type: FUNC
915 */
916 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder03, TestSize.Level1)
917 {
918 LazyForEachModelNG lazyForEach;
919 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
920 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
921 lazyForEach.Create(mockLazyForEachActuator);
922 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
923 ASSERT_NE(lazyForEachBuilder, nullptr);
924 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
925 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
926 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
927
928 for (auto& [index, node] : lazyForEachBuilder->cachedItems_) {
929 lazyForEachBuilder->expiringItem_.try_emplace(node.first, LazyForEachCacheChild(-1, std::move(node.second)));
930 }
931 LayoutConstraintF layoutConstraint;
932
933 /**
934 * @tc.steps: step1. all == false;
935 */
936 auto step1 = lazyForEachBuilder->PreBuild(10, layoutConstraint, true);
937 EXPECT_TRUE(step1);
938
939 /**
940 * @tc.steps: step2. itemConstraint, startIndex_ != -1;
941 */
942 layoutConstraint.parentIdealSize = OptionalSizeF(768, 1024);
943 layoutConstraint.selfIdealSize = OptionalSizeF(480, 960);
944 lazyForEachBuilder->startIndex_ = 3;
945 auto step2 = lazyForEachBuilder->PreBuild(10, layoutConstraint, true);
946 EXPECT_TRUE(step2);
947
948 /**
949 * @tc.steps: step3. startIndex_ != -1 && endIndex_ != -1;
950 */
951 lazyForEachBuilder->endIndex_ = 1;
952 auto step3 = lazyForEachBuilder->PreBuild(10, layoutConstraint, true);
953 EXPECT_TRUE(step3);
954
955 /**
956 * @tc.steps: step4. !canRunLongPredictTask;
957 */
958 auto step4 = lazyForEachBuilder->PreBuild(10, layoutConstraint, false);
959 EXPECT_FALSE(step4);
960
961 /**
962 * @tc.steps: step5. Set cacheCount_ is 7 and check PreBuild fuction;
963 */
964 lazyForEachBuilder->SetCacheCount(7);
965 auto step5 = lazyForEachBuilder->PreBuild(10, layoutConstraint, true);
966 EXPECT_FALSE(step5);
967
968 /**
969 * @tc.steps: step6. Set cacheCount_ is 7 and check PreBuild fuction;
970 */
971 lazyForEachBuilder->preBuildingIndex_ = 0;
972 auto step6 = lazyForEachBuilder->PreBuild(10, layoutConstraint, true);
973 EXPECT_FALSE(step6);
974 }
975
976 /**
977 * @tc.name: LazyForEachBuilder04
978 * @tc.desc: LazyForEachBuilder::OnDataBulkChanged
979 * @tc.type: FUNC
980 */
981 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder04, TestSize.Level1)
982 {
983 LazyForEachModelNG lazyForEach;
984 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
985 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
986 lazyForEach.Create(mockLazyForEachActuator);
987 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
988
989 /**
990 * @tc.steps: step1. cachedItems_.empty();
991 */
992 auto step1 = lazyForEachBuilder->OnDataBulkChanged(0, 0);
993 EXPECT_EQ(step1.size(), 0);
994
995 /**
996 * @tc.steps: step1. node.first;
997 */
998 std::string str0 = "0";
999 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
1000 lazyForEachBuilder->expiringItem_[str0] = LazyForEachCacheChild(2, nullptr);
1001 std::string str1 = "1";
1002 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
1003 lazyForEachBuilder->expiringItem_[str1] = LazyForEachCacheChild(7, nullptr);
1004 std::string str2 = "2";
1005 lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
1006 lazyForEachBuilder->expiringItem_[str2] = LazyForEachCacheChild(0, nullptr);
1007 lazyForEachBuilder->OnDataBulkChanged(1, 5);
1008 EXPECT_EQ(lazyForEachBuilder->expiringItem_[str0].first, -1);
1009 EXPECT_EQ(lazyForEachBuilder->expiringItem_[str1].first, 7);
1010 EXPECT_EQ(lazyForEachBuilder->expiringItem_[str2].first, 0);
1011 }
1012
1013 /**
1014 * @tc.name: LazyForEachBuilder05
1015 * @tc.desc: LazyForEachBuilder::RecycleChildByIndex
1016 * @tc.type: FUNC
1017 */
1018 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder05, TestSize.Level1)
1019 {
1020 LazyForEachModelNG lazyForEach;
1021 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1022 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1023 lazyForEach.Create(mockLazyForEachActuator);
1024 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1025
1026 /**
1027 * @tc.steps: step1. !iter->second.second;
1028 */
1029 std::string str0 = "0";
1030 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
1031 lazyForEachBuilder->RecycleChildByIndex(0);
1032 EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 1);
1033
1034 /**
1035 * @tc.steps: step2. !dummyNode;
1036 */
1037 std::string str1 = "1";
1038 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
1039 lazyForEachBuilder->GetChildByIndex(1, true);
1040 lazyForEachBuilder->RecycleChildByIndex(1);
1041 EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 2);
1042
1043 /**
1044 * @tc.steps: step3. dummyNode;
1045 */
1046 std::string str2 = "2";
1047 lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
1048 lazyForEachBuilder->GetChildByIndex(2, true);
1049 auto iter = lazyForEachBuilder->cachedItems_.find(2);
1050 iter->second.second->SetNeedCallChildrenUpdate(true);
1051 iter->second.second->debugLine_ = str2;
1052 lazyForEachBuilder->RecycleChildByIndex(2);
1053 EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 3);
1054 }
1055
1056 /**
1057 * @tc.name: LazyForEachBuilder06
1058 * @tc.desc: LazyForEachBuilder::OnDataBulkDeleted
1059 * @tc.type: FUNC
1060 */
1061 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder06, TestSize.Level1)
1062 {
1063 LazyForEachModelNG lazyForEach;
1064 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1065 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1066 lazyForEach.Create(mockLazyForEachActuator);
1067 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1068
1069 /**
1070 * @tc.steps: step1. Override the branch of the judgment expiringItem_;
1071 */
1072 std::string str1 = "1";
1073 std::string str2 = "3";
1074 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
1075 lazyForEachBuilder->expiringItem_[str1] = LazyForEachCacheChild(1, nullptr);
1076 lazyForEachBuilder->expiringItem_[str2] = LazyForEachCacheChild(3, nullptr);
1077 lazyForEachBuilder->OnDataBulkDeleted(2, 5);
1078 EXPECT_EQ(lazyForEachBuilder->nodeList_.size(), 0);
1079
1080 /**
1081 * @tc.steps: step1. Override the branch of the judgment cachedItems_;
1082 */
1083 lazyForEachBuilder->cachedItems_[3] = LazyForEachChild(str2, nullptr);
1084 lazyForEachBuilder->OnDataBulkDeleted(2, 5);
1085 EXPECT_NE(lazyForEachBuilder->nodeList_.size(), 0);
1086 }
1087
1088 /**
1089 * @tc.name: LazyForEachBuilder07
1090 * @tc.desc: LazyForEachBuilder::OnDataBulkDeleted
1091 * @tc.type: FUNC
1092 */
1093 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder07, TestSize.Level1)
1094 {
1095 LazyForEachModelNG lazyForEach;
1096 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1097 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1098 lazyForEach.Create(mockLazyForEachActuator);
1099 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1100
1101 /**
1102 * @tc.steps: step1. operation.index >= totalCountOfOriginalDataset_;
1103 */
1104 V2::Operation operation;
1105 operation.index = 0;
1106 int32_t initialIndex = 0;
1107 std::map<int32_t, LazyForEachChild> cachedTemp;
1108 std::map<int32_t, LazyForEachChild> expiringTemp;
1109 lazyForEachBuilder->OperateChange(operation, initialIndex, cachedTemp, expiringTemp);
1110 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 0);
1111
1112 /**
1113 * @tc.steps: step2. !indexExist == operationList_.end();
1114 */
1115 lazyForEachBuilder->totalCountOfOriginalDataset_ = 1;
1116 OperationInfo operationinfo;
1117 lazyForEachBuilder->operationList_[1] = operationinfo;
1118 lazyForEachBuilder->OperateChange(operation, initialIndex, cachedTemp, expiringTemp);
1119 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 1);
1120
1121 /**
1122 * @tc.steps: step3. !operation.key.empty();
1123 */
1124 std::string str0 = "0";
1125 expiringTemp[0] = LazyForEachChild(str0, nullptr);
1126 cachedTemp[0] = LazyForEachChild(str0, nullptr);
1127 operation.key = "0";
1128 lazyForEachBuilder->OperateChange(operation, initialIndex, cachedTemp, expiringTemp);
1129 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 2);
1130
1131 /**
1132 * @tc.steps: step4. !indexExist == operationList_.end();
1133 */
1134 lazyForEachBuilder->operationList_[0] = operationinfo;
1135 lazyForEachBuilder->OperateChange(operation, initialIndex, cachedTemp, expiringTemp);
1136 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 2);
1137 }
1138
1139 /**
1140 * @tc.name: LazyForEachBuilder08
1141 * @tc.desc: LazyForEachBuilder::GetAllItems
1142 * @tc.type: FUNC
1143 */
1144 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder08, TestSize.Level1)
1145 {
1146 /**
1147 * @tc.steps: step1. Create LazyForEachBuilder
1148 * @tc.expected: Create LazyForEachBuilder success.
1149 */
1150 auto lazyForEachBuilder = CreateLazyForEachBuilder();
1151 ASSERT_NE(lazyForEachBuilder, nullptr);
1152 for (auto& [index, node] : lazyForEachBuilder->cachedItems_) {
1153 lazyForEachBuilder->expiringItem_.try_emplace(node.first, LazyForEachCacheChild(-1, std::move(node.second)));
1154 }
1155 for (auto& [index, node] : lazyForEachBuilder->cachedItems_) {
1156 lazyForEachBuilder->nodeList_.emplace_back(node.first, node.second);
1157 }
1158
1159 /**
1160 * @tc.steps: step2. LazyForEachBuilder::GetAllItems(std::vector<UINode*>& items)
1161 */
1162 std::vector<UINode*> children;
1163 lazyForEachBuilder->GetAllItems(children);
1164 EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 7);
1165 EXPECT_EQ(lazyForEachBuilder->expiringItem_.size(), 7);
1166 EXPECT_EQ(lazyForEachBuilder->nodeList_.size(), 7);
1167
1168 /**
1169 * @tc.steps: step3. Mock the UINode of expiringItem_ is nullptr and the other is not nullptr
1170 */
1171 std::list<std::pair<std::string, RefPtr<UINode>>> childList;
1172 lazyForEachBuilder->needTransition = true;
1173 lazyForEachBuilder->expiringItem_["0"].second = nullptr;
1174 lazyForEachBuilder->expiringItem_["1"].second->GetFrameChildByIndex(0, true)->onMainTree_ = true;
1175 lazyForEachBuilder->Transit(childList);
1176 EXPECT_EQ(childList.size(), 1);
1177
1178 /**
1179 * @tc.steps: step4. !node.second
1180 */
1181 childList.clear();
1182 lazyForEachBuilder->cachedItems_[0].second = nullptr;
1183 lazyForEachBuilder->GetItems(childList);
1184 EXPECT_EQ(childList.size(), 0);
1185
1186 /**
1187 * @tc.steps: step5. iter->first < index
1188 */
1189 std::list<V2::Operation> DataOperations;
1190 V2::Operation operation = { .type = "change", .index = INDEX_0, .count = INDEX_3 };
1191 DataOperations.push_back(operation);
1192 lazyForEachBuilder->expiringItem_["2"].first = 2;
1193 lazyForEachBuilder->OnDatasetChange(DataOperations);
1194 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 0);
1195
1196 /**
1197 * @tc.steps: step6. info.moveIn || info.isExchange
1198 */
1199 std::list<V2::Operation> DataOperations1;
1200 V2::Operation operation1 = { .type = "move", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(8, 8) };
1201 DataOperations1.push_back(operation1);
1202 lazyForEachBuilder->OnDatasetChange(DataOperations1);
1203 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 0);
1204 }
1205
1206 /**
1207 * @tc.name: LazyForEachBuilder09
1208 * @tc.desc: LazyForEachBuilder::OnDatasetChange
1209 * @tc.type: FUNC
1210 */
1211 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder09, TestSize.Level1)
1212 {
1213 /**
1214 * @tc.steps: step1. Create LazyForEachBuilder
1215 * @tc.expected: Create LazyForEachBuilder success.
1216 */
1217 auto lazyForEachBuilder = CreateLazyForEachBuilder();
1218 ASSERT_NE(lazyForEachBuilder, nullptr);
1219 for (auto& [index, node] : lazyForEachBuilder->cachedItems_) {
1220 lazyForEachBuilder->expiringItem_.try_emplace(node.first, LazyForEachCacheChild(-1, std::move(node.second)));
1221 }
1222 for (auto& [index, node] : lazyForEachBuilder->cachedItems_) {
1223 lazyForEachBuilder->nodeList_.emplace_back(node.first, node.second);
1224 }
1225
1226 /**
1227 * @tc.steps: step2. cacheChild.first > -1
1228 */
1229 std::list<V2::Operation> DataOperations;
1230 V2::Operation operation = { .type = "change", .index = INDEX_0, .count = INDEX_8 };
1231 DataOperations.push_back(operation);
1232 lazyForEachBuilder->expiringItem_["0"].first = 0;
1233 lazyForEachBuilder->OnDatasetChange(DataOperations);
1234 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 0);
1235
1236 /**
1237 * @tc.steps: step3. indexChangedMap can not find the node
1238 */
1239 std::list<V2::Operation> DataOperations1;
1240 V2::Operation operation1 = { .type = "add", .index = INDEX_8, .count = INDEX_8, .coupleIndex = std::pair(1, 3) };
1241 DataOperations1.push_back(operation1);
1242 lazyForEachBuilder->OnDatasetChange(DataOperations1);
1243 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 0);
1244
1245 /**
1246 * @tc.steps: step4. !operation.key.empty()
1247 */
1248 std::list<V2::Operation> DataOperations2;
1249 V2::Operation operation2 = { .type = "add", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(1, 3) };
1250 operation2.key = "0";
1251 DataOperations2.push_back(operation2);
1252 lazyForEachBuilder->OnDatasetChange(DataOperations2);
1253 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 0);
1254
1255 /**
1256 * @tc.steps: step5. operation.keyList.size() >= static_cast<size_t>(1)
1257 */
1258 std::list<V2::Operation> DataOperations3;
1259 V2::Operation operation3 = { .type = "add", .index = INDEX_0, .count = INDEX_8, .coupleIndex = std::pair(1, 3) };
1260 std::list<std::string> keyList;
1261 keyList.push_back("0");
1262 operation3.keyList = keyList;
1263 DataOperations3.push_back(operation3);
1264 lazyForEachBuilder->OnDatasetChange(DataOperations3);
1265 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 0);
1266 }
1267
1268 /**
1269 * @tc.name: LazyForEachBuilder10
1270 * @tc.desc: LazyForEachBuilder::OperateMove
1271 * @tc.type: FUNC
1272 */
1273 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder10, TestSize.Level1)
1274 {
1275 /**
1276 * @tc.steps: step1. Create LazyForEachBuilder
1277 * @tc.expected: Create LazyForEachBuilder success.
1278 */
1279 auto lazyForEachBuilder = CreateLazyForEachBuilder();
1280 ASSERT_NE(lazyForEachBuilder, nullptr);
1281
1282 /**
1283 * @tc.steps: step2. !ValidateIndex(operation.coupleIndex.first, operation.type)
1284 */
1285 V2::Operation operation;
1286 operation.index = 0;
1287 operation.type = "move";
1288 operation.count = 8;
1289 operation.coupleIndex = std::pair(8, 8);
1290 int32_t initialIndex = 0;
1291 lazyForEachBuilder->totalCountOfOriginalDataset_ = 9;
1292 std::map<int32_t, LazyForEachChild> cachedTemp;
1293 std::map<int32_t, LazyForEachChild> expiringTemp;
1294 lazyForEachBuilder->OperateMove(operation, initialIndex, cachedTemp, expiringTemp);
1295 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 1);
1296
1297 /**
1298 * @tc.steps: step3. fromIndexExist == operationList_.end()
1299 */
1300 std::string str0 = "0";
1301 expiringTemp[0] = LazyForEachChild(str0, nullptr);
1302 cachedTemp[0] = LazyForEachChild(str0, nullptr);
1303 OperationInfo operationinfo;
1304 lazyForEachBuilder->operationList_[0] = operationinfo;
1305 lazyForEachBuilder->OperateMove(operation, initialIndex, cachedTemp, expiringTemp);
1306 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 2);
1307 }
1308
1309 /**
1310 * @tc.name: LazyForEachBuilder11
1311 * @tc.desc: LazyForEachBuilder::OperateExchange
1312 * @tc.type: FUNC
1313 */
1314 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder11, TestSize.Level1)
1315 {
1316 /**
1317 * @tc.steps: step1. Create LazyForEachBuilder
1318 * @tc.expected: Create LazyForEachBuilder success.
1319 */
1320 auto lazyForEachBuilder = CreateLazyForEachBuilder();
1321 ASSERT_NE(lazyForEachBuilder, nullptr);
1322
1323 /**
1324 * @tc.steps: step2. !ValidateIndex(operation.coupleIndex.first, operation.type)
1325 */
1326 V2::Operation operation;
1327 operation.index = 0;
1328 operation.type = "exchange";
1329 operation.count = 8;
1330 operation.coupleIndex = std::pair(1, 3);
1331 int32_t initialIndex = 0;
1332 lazyForEachBuilder->totalCountOfOriginalDataset_ = 9;
1333 std::map<int32_t, LazyForEachChild> cachedTemp;
1334 std::map<int32_t, LazyForEachChild> expiringTemp;
1335 lazyForEachBuilder->OperateExchange(operation, initialIndex, cachedTemp, expiringTemp);
1336 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 2);
1337
1338 /**
1339 * @tc.steps: step3. fromIndexExist == operationList_.end()
1340 */
1341 std::string str0 = "0";
1342 expiringTemp[0] = LazyForEachChild(str0, nullptr);
1343 cachedTemp[0] = LazyForEachChild(str0, nullptr);
1344 OperationInfo operationinfo;
1345 lazyForEachBuilder->operationList_[0] = operationinfo;
1346 lazyForEachBuilder->OperateExchange(operation, initialIndex, cachedTemp, expiringTemp);
1347 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 3);
1348
1349 /**
1350 * @tc.steps: step4. moveFromTo_ is not null
1351 */
1352 lazyForEachBuilder->moveFromTo_ = { 1, 3 };
1353 lazyForEachBuilder->UpdateMoveFromTo(2, 4);
1354 EXPECT_EQ(lazyForEachBuilder->moveFromTo_.value().second, 4);
1355 }
1356
1357 /**
1358 * @tc.name: LazyForEachBuilder12
1359 * @tc.desc: Create LazyForEach, invoke OnDatasetChange function.
1360 * @tc.type: FUNC
1361 */
1362 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder12, TestSize.Level1)
1363 {
1364 /**
1365 * @tc.steps: step1. Create LazyForEachNode
1366 * @tc.expected: Create LazyForEachNode success.
1367 */
1368 auto lazyForEachNode = CreateLazyForEachNode();
1369 ASSERT_NE(lazyForEachNode, nullptr);
1370
1371 std::list<V2::Operation> DataOperations;
1372 V2::Operation operation1 = { .type = "add", .index = INDEX_0, .count = 1 };
1373 DataOperations.push_back(operation1);
1374
1375 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1376 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1377 }
1378 lazyForEachNode->builder_->OnDatasetChange(DataOperations);
1379 lazyForEachNode->OnDatasetChange(DataOperations);
1380 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 7);
1381 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
1382
1383 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1384 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1385 }
1386 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 9);
1387 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
1388 }
1389
1390 /**
1391 * @tc.name: LazyForEachBuilder13
1392 * @tc.desc: Create LazyForEach, update its Items and invoke InitDragManager function.
1393 * @tc.type: FUNC
1394 */
1395 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder13, TestSize.Level1)
1396 {
1397 /**
1398 * @tc.steps: step1. Create LazyForEachNode
1399 * @tc.expected: Create LazyForEachNode success.
1400 */
1401 auto lazyForEachNode = CreateLazyForEachNode();
1402 ASSERT_NE(lazyForEachNode, nullptr);
1403
1404 /**
1405 * @tc.steps: step2. parentNode->GetTag() != V2::LIST_ETS_TAG.
1406 * @tc.expected: LazyForEachNode ids_ will be cleared.
1407 */
1408 auto parentNode = CreateNode(V2::TEXT_ETS_TAG);
1409 lazyForEachNode->SetParent(parentNode);
1410 auto frameChild = AceType::DynamicCast<FrameNode>(lazyForEachNode->GetFrameChildByIndex(0, true));
1411 lazyForEachNode->InitDragManager(frameChild);
1412 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1413
1414 /**
1415 * @tc.steps: step3. Invoke NotifyCountChange.
1416 * @tc.expected: LazyForEachNode ids_ will be cleared.
1417 */
1418 parentNode = CreateNode(V2::LIST_ETS_TAG);
1419 lazyForEachNode->SetParent(parentNode);
1420 lazyForEachNode->InitDragManager(frameChild);
1421 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1422 }
1423
1424 /**
1425 * @tc.name: LazyForEachBuilder14
1426 * @tc.desc: Create LazyForEach, update its Items and invoke GetFrameChildByIndex function.
1427 * @tc.type: FUNC
1428 */
1429 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder14, TestSize.Level1)
1430 {
1431 /**
1432 * @tc.steps: step1. Create LazyForEachNode
1433 * @tc.expected: Create LazyForEachNode success.
1434 */
1435 auto lazyForEachNode = CreateLazyForEachNode();
1436 ASSERT_NE(lazyForEachNode, nullptr);
1437
1438 /**
1439 * @tc.steps: step2. Invoke GetFrameChildByIndex.
1440 * @tc.expected: LazyForEachNode ids_ will be cleared.
1441 */
1442 lazyForEachNode->needPredict_ = false;
1443 EXPECT_NE(lazyForEachNode->GetFrameChildByIndex(0, true, true), nullptr);
1444
1445 lazyForEachNode->needPredict_ = false;
1446 EXPECT_NE(lazyForEachNode->GetFrameChildByIndex(0, true, true, true), nullptr);
1447
1448 lazyForEachNode->needPredict_ = false;
1449 EXPECT_NE(lazyForEachNode->GetFrameChildByIndex(0, true, false, true), nullptr);
1450
1451 /**
1452 * @tc.steps: step3. Invoke GetFrameChildByIndex.
1453 * @tc.expected: LazyForEachNode ids_ will be cleared.
1454 */
1455 lazyForEachNode->needPredict_ = true;
1456 EXPECT_NE(lazyForEachNode->GetFrameChildByIndex(0, false, true), nullptr);
1457
1458 lazyForEachNode->needPredict_ = true;
1459 EXPECT_NE(lazyForEachNode->GetFrameChildByIndex(0, false, true, true), nullptr);
1460
1461 lazyForEachNode->needPredict_ = true;
1462 EXPECT_NE(lazyForEachNode->GetFrameChildByIndex(0, false, false, true), nullptr);
1463
1464 /**
1465 * @tc.steps: step4. Invoke GetFrameChildByIndex.
1466 * @tc.expected: LazyForEachNode ids_ will be cleared.
1467 */
1468 lazyForEachNode->onMainTree_ = true;
__anon7902275b0202(int32_t a, int32_t b) 1469 std::function<void(int32_t, int32_t)> lambda = [](int32_t a, int32_t b) {};
1470 lazyForEachNode->onMoveEvent_ = std::move(lambda);
1471 lazyForEachNode->needPredict_ = true;
1472 lazyForEachNode->GetFrameChildByIndex(0, false);
1473 EXPECT_NE(lazyForEachNode->GetFrameChildByIndex(0, false), nullptr);
1474 }
1475
1476 /**
1477 * @tc.name: LazyForEachBuilder15
1478 * @tc.desc: Create LazyForEach, update its Items and invoke GetIndexByUINode function.
1479 * @tc.type: FUNC
1480 */
1481 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder15, TestSize.Level1)
1482 {
1483 /**
1484 * @tc.steps: step1. Create LazyForEachNode
1485 * @tc.expected: Create LazyForEachNode success.
1486 */
1487 auto lazyForEachNode = CreateLazyForEachNode();
1488 ASSERT_NE(lazyForEachNode, nullptr);
1489
1490 /**
1491 * @tc.steps: step2. Invoke GetIndexByUINode.
1492 * @tc.expected: LazyForEachNode ids_ will be cleared.
1493 */
1494 lazyForEachNode->needPredict_ = true;
1495 auto& node = lazyForEachNode->builder_->cachedItems_[0].second;
1496 EXPECT_GE(lazyForEachNode->GetIndexByUINode(node), 0);
1497 }
1498
1499 /**
1500 * @tc.name: LazyForEachBuilder16
1501 * @tc.desc: Create LazyForEach, update its Items and invoke :OnDataBulkDeleted function.
1502 * @tc.type: FUNC
1503 */
1504 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder16, TestSize.Level1)
1505 {
1506 /**
1507 * @tc.steps: step1. Create LazyForEachNode
1508 * @tc.expected: Create LazyForEachNode success.
1509 */
1510 auto lazyForEachNode = CreateLazyForEachNode();
1511 ASSERT_NE(lazyForEachNode, nullptr);
1512 auto lazyForEachBuilder = lazyForEachNode->builder_;
1513 ASSERT_NE(lazyForEachBuilder, nullptr);
1514
1515 lazyForEachBuilder->OnDataBulkDeleted(INDEX_0, INDEX_0);
1516 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1517 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1518 }
1519 lazyForEachBuilder->OnDataChanged(INDEX_1);
1520 lazyForEachBuilder->cachedItems_[INDEX_1].second = nullptr;
1521 lazyForEachBuilder->OnDataChanged(INDEX_1);
1522 lazyForEachNode->OnDataBulkDeleted(INDEX_0, INDEX_1);
1523 }
1524
1525 /**
1526 * @tc.name: LazyForEachBuilder17
1527 * @tc.desc: Create LazyForEach, update its Items and invoke OnConfigurationUpdate function.
1528 * @tc.type: FUNC
1529 */
1530 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder17, TestSize.Level1)
1531 {
1532 /**
1533 * @tc.steps: step1. Create LazyForEachNode
1534 * @tc.expected: Create LazyForEachNode success.
1535 */
1536 ConfigurationChange configurationChange;
1537 auto lazyForEachNode = CreateLazyForEachNode();
1538 ASSERT_NE(lazyForEachNode, nullptr);
1539
1540 /**
1541 * @tc.steps: step2. Invoke colorModeUpdate = true and UINode is not null
1542 */
1543 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1544 lazyForEachNode->builder_->expiringItem_["0"] = LazyForEachCacheChild(0, frameNode);
1545 configurationChange.colorModeUpdate = true;
1546 lazyForEachNode->OnConfigurationUpdate(configurationChange);
1547 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1548
1549 /**
1550 * @tc.steps: step3. colorModeUpdate = false and UINode is not null
1551 */
1552 configurationChange.colorModeUpdate = false;
1553 lazyForEachNode->OnConfigurationUpdate(configurationChange);
1554 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1555
1556 /**
1557 * @tc.steps: step4. Invoke OnConfigurationUpdate and UINode is null
1558 */
1559 lazyForEachNode->builder_->expiringItem_["0"] = LazyForEachCacheChild(0, nullptr);
1560 configurationChange.colorModeUpdate = true;
1561 lazyForEachNode->OnConfigurationUpdate(configurationChange);
1562 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1563 }
1564
1565 /**
1566 * @tc.name: LazyForEachBuilder18
1567 * @tc.desc: Create LazyForEach, update its Items and invoke UpdateChildrenFreezeState function.
1568 * @tc.type: FUNC
1569 */
1570 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder18, TestSize.Level1)
1571 {
1572 /**
1573 * @tc.steps: step1. Create LazyForEachNode
1574 * @tc.expected: Create LazyForEachNode success.
1575 */
1576 auto lazyForEachNode = CreateLazyForEachNode();
1577 ASSERT_NE(lazyForEachNode, nullptr);
1578
1579 /**
1580 * @tc.steps: step2. Invoke UpdateChildrenFreezeState.
1581 * @tc.expected: LazyForEachNode ids_ will be cleared.
1582 */
1583 lazyForEachNode->UpdateChildrenFreezeState(true);
1584 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1585
1586 /**
1587 * @tc.steps: step3. Invoke UpdateChildrenFreezeState.
1588 * @tc.expected: LazyForEachNode ids_ will be cleared.
1589 */
1590 lazyForEachNode->builder_ = nullptr;
1591 lazyForEachNode->UpdateChildrenFreezeState(true);
1592 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1593 }
1594
1595 /**
1596 * @tc.name: LazyForEachBuilder19
1597 * @tc.desc: Create LazyForEach, update its Items and invoke InitDragManager function.
1598 * @tc.type: FUNC
1599 */
1600 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder19, TestSize.Level1)
1601 {
1602 /**
1603 * @tc.steps: step1. Create LazyForEachNode
1604 * @tc.expected: Create LazyForEachNode success.
1605 */
1606 auto lazyForEachNode = CreateLazyForEachNode();
1607 ASSERT_NE(lazyForEachNode, nullptr);
1608
1609 /**
1610 * @tc.steps: step2. Invoke InitAllChilrenDragManager.
1611 * @tc.expected: LazyForEachNode ids_ will be cleared.
1612 */
1613 auto parentNode = CreateNode(V2::TEXT_ETS_TAG);
1614 lazyForEachNode->SetParent(parentNode);
1615 lazyForEachNode->InitAllChilrenDragManager(true);
1616 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1617
1618 /**
1619 * @tc.steps: step3. Invoke InitAllChilrenDragManager.
1620 * @tc.expected: LazyForEachNode ids_ will be cleared.
1621 */
1622 parentNode = CreateNode(V2::LIST_ETS_TAG);
1623 lazyForEachNode->SetParent(parentNode);
1624 lazyForEachNode->InitAllChilrenDragManager(true);
1625 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1626 }
1627
1628 /**
1629 * @tc.name: LazyForEachBuilder20
1630 * @tc.desc: Create LazyForEach.
1631 * @tc.type: FUNC
1632 */
1633 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder20, TestSize.Level1)
1634 {
1635 /**
1636 * @tc.steps: step1. Create LazyForEachNode
1637 * @tc.expected: Create LazyForEachNode success.
1638 */
1639 auto lazyForEachNode = CreateLazyForEachNode();
1640 ASSERT_NE(lazyForEachNode, nullptr);
1641 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1642 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1643 }
1644
1645 /**
1646 * @tc.steps: step2. Invoke OnDatasetChange function.
1647 * @tc.expected: Create reload operation and Invoke OnDatasetChange function.
1648 */
1649 std::list<V2::Operation> DataOperations;
1650 V2::Operation operation1 = { .type = "reload" };
1651 DataOperations.push_back(operation1);
1652 lazyForEachNode->OnDatasetChange(DataOperations);
1653 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 0);
1654 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
1655 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1656 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1657 }
1658 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 7);
1659 }
1660
1661 /**
1662 * @tc.name: LazyForEachBuilder21
1663 * @tc.desc: Create LazyForEach.
1664 * @tc.type: FUNC
1665 */
1666 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder21, TestSize.Level1)
1667 {
1668 /**
1669 * @tc.steps: step1. Create LazyForEachNode
1670 * @tc.expected: Create LazyForEachNode success.
1671 */
1672 auto lazyForEachNode = CreateLazyForEachNode();
1673 ASSERT_NE(lazyForEachNode, nullptr);
1674
1675 /**
1676 * @tc.steps: step2. Invoke OnDatasetChange function.
1677 * @tc.expected: Create add operation and Invoke OnDatasetChange function.
1678 */
1679 std::list<V2::Operation> DataOperations;
1680 V2::Operation operation1 = { .type = "add", .index = INDEX_0, .count = 1 };
1681 DataOperations.push_back(operation1);
1682 lazyForEachNode->OnDatasetChange(DataOperations);
1683 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1684 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1685 }
1686 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 8);
1687 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
1688
1689 /**
1690 * @tc.steps: step3. Invoke OnDatasetChange function.
1691 * @tc.expected: Create add operation and Invoke OnDatasetChange function.
1692 */
1693 DataOperations.clear();
1694 V2::Operation operation2 = { .type = "add", .index = INDEX_0, .count = 2 };
1695 DataOperations.push_back(operation2);
1696 lazyForEachNode->OnDatasetChange(DataOperations);
1697 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1698 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1699 }
1700 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 10);
1701 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
1702 }
1703
1704 /**
1705 * @tc.name: LazyForEachBuilder22
1706 * @tc.desc: Create LazyForEach.
1707 * @tc.type: FUNC
1708 */
1709 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder22, TestSize.Level1)
1710 {
1711 /**
1712 * @tc.steps: step1. Create LazyForEachNode
1713 * @tc.expected: Create LazyForEachNode success.
1714 */
1715 auto lazyForEachNode = CreateLazyForEachNode();
1716 ASSERT_NE(lazyForEachNode, nullptr);
1717 auto lazyForEachBuilder = lazyForEachNode->builder_;
1718 ASSERT_NE(lazyForEachBuilder, nullptr);
1719 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1720 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1721 }
1722
1723 /**
1724 * @tc.steps: step2. Invoke OnDatasetChange function.
1725 * @tc.expected: Create delete operation and Invoke OnDatasetChange function.
1726 */
1727 lazyForEachBuilder->UpdateHistoricalTotalCount(lazyForEachBuilder->GetTotalCount());
1728 std::list<V2::Operation> DataOperations;
1729 V2::Operation operation1 = { .type = "delete", .index = INDEX_0, .count = 1 };
1730 DataOperations.push_back(operation1);
1731 lazyForEachNode->OnDatasetChange(DataOperations);
1732 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 6);
1733 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
1734
1735 /**
1736 * @tc.steps: step3. Invoke OnDatasetChange function.
1737 * @tc.expected: Create delete operation and Invoke OnDatasetChange function.
1738 */
1739 DataOperations.clear();
1740 lazyForEachBuilder->UpdateHistoricalTotalCount(lazyForEachBuilder->GetTotalCount());
1741 V2::Operation operation2 = { .type = "delete", .index = INDEX_0, .count = 2 };
1742 DataOperations.push_back(operation2);
1743 lazyForEachNode->OnDatasetChange(DataOperations);
1744 EXPECT_EQ(lazyForEachNode->builder_->cachedItems_.size(), 4);
1745 EXPECT_EQ(lazyForEachNode->builder_->operationList_.size(), 0);
1746 }
1747
1748 /**
1749 * @tc.name: LazyForEachBuilder23
1750 * @tc.desc: Create LazyForEach.
1751 * @tc.type: FUNC
1752 */
1753 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder23, TestSize.Level1)
1754 {
1755 /**
1756 * @tc.steps: step1. Create LazyForEachNode
1757 * @tc.expected: Create LazyForEachNode success.
1758 */
1759 auto lazyForEachNode = CreateLazyForEachNode();
1760 ASSERT_NE(lazyForEachNode, nullptr);
1761 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1762 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1763 }
1764
1765 /**
1766 * @tc.steps: step3. Invoke OnDatasetChange function.
1767 * @tc.expected: Create change operation and Invoke OnDatasetChange function.
1768 */
1769 std::list<V2::Operation> DataOperations;
1770 V2::Operation operation1 = { .type = "change", .index = INDEX_0 };
1771 DataOperations.push_back(operation1);
1772 lazyForEachNode->OnDatasetChange(DataOperations);
1773 EXPECT_EQ(lazyForEachNode->builder_->OnGetTotalCount(), 7);
1774 }
1775
1776 /**
1777 * @tc.name: LazyForEachBuilder24
1778 * @tc.desc: Create LazyForEach.
1779 * @tc.type: FUNC
1780 */
1781 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder24, TestSize.Level1)
1782 {
1783 /**
1784 * @tc.steps: step1. Create LazyForEachNode
1785 * @tc.expected: Create LazyForEachNode success.
1786 */
1787 auto lazyForEachNode = CreateLazyForEachNode();
1788 ASSERT_NE(lazyForEachNode, nullptr);
1789 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1790 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1791 }
1792
1793 /**
1794 * @tc.steps: step2. Invoke OnDatasetChange function.
1795 * @tc.expected: Create move operation and Invoke OnDatasetChange function.
1796 */
1797 std::list<V2::Operation> DataOperations;
1798 V2::Operation operation1 = { .type = "move", .coupleIndex = std::pair(0, 2) };
1799 DataOperations.push_back(operation1);
1800 lazyForEachNode->OnDatasetChange(DataOperations);
1801 EXPECT_EQ(lazyForEachNode->builder_->OnGetTotalCount(), 7);
1802 }
1803
1804 /**
1805 * @tc.name: LazyForEachBuilder25
1806 * @tc.desc: Create LazyForEach.
1807 * @tc.type: FUNC
1808 */
1809 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder25, TestSize.Level1)
1810 {
1811 /**
1812 * @tc.steps: step1. Create LazyForEachNode
1813 * @tc.expected: Create LazyForEachNode success.
1814 */
1815 auto lazyForEachNode = CreateLazyForEachNode();
1816 ASSERT_NE(lazyForEachNode, nullptr);
1817 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1818 lazyForEachNode->builder_->GetChildByIndex(iter.value_or(0), true);
1819 }
1820
1821 /**
1822 * @tc.steps: step2. Invoke OnDatasetChange function.
1823 * @tc.expected: Create exchange operation and Invoke OnDatasetChange function.
1824 */
1825 std::list<V2::Operation> DataOperations;
1826 V2::Operation operation1 = { .type = "exchange", .coupleIndex = std::pair(1, 3) };
1827 DataOperations.push_back(operation1);
1828 lazyForEachNode->OnDatasetChange(DataOperations);
1829 EXPECT_EQ(lazyForEachNode->builder_->OnGetTotalCount(), 7);
1830 }
1831
1832 /**
1833 * @tc.name: LazyForEachBuilder26
1834 * @tc.desc: test the founction of OnDataAdded in LazyForEachBuilder.
1835 * @tc.type: FUNC
1836 */
1837 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder26, TestSize.Level1)
1838 {
1839 auto lazyForEachBuilder = CreateLazyForEachBuilder();
1840 ASSERT_NE(lazyForEachBuilder, nullptr);
1841 /**
1842 * @tc.expected: No cachedItems_ is added in index > static_cast<size_t>(cachedItems_.rbegin()->first).
1843 */
1844 EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 7);
1845 lazyForEachBuilder->OnDataAdded(9);
1846 EXPECT_EQ(lazyForEachBuilder->cachedItems_.size(), 7);
1847 /**
1848 * @tc.expected: node.first++ in static_cast<size_t>(node.first) >= index && node.first != -1.
1849 */
1850 lazyForEachBuilder->expiringItem_["6"] = LazyForEachCacheChild(6, nullptr);
1851 lazyForEachBuilder->OnDataAdded(6);
1852 EXPECT_EQ(lazyForEachBuilder->expiringItem_["6"].first, 7);
1853 /**
1854 * @tc.expected: node.first dont change in node.first == -1.
1855 */
1856 lazyForEachBuilder->expiringItem_["6"] = LazyForEachCacheChild(-1, nullptr);
1857 lazyForEachBuilder->OnDataAdded(-1);
1858 EXPECT_EQ(lazyForEachBuilder->expiringItem_["6"].first, -1);
1859 }
1860
1861 /**
1862 * @tc.name: LazyForEachBuilder27
1863 * @tc.desc: test the founction of OnDataBulkAdded in LazyForEachBuilder.
1864 * @tc.type: FUNC
1865 */
1866 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder27, TestSize.Level1)
1867 {
1868 auto lazyForEachBuilder = CreateLazyForEachBuilder();
1869 ASSERT_NE(lazyForEachBuilder, nullptr);
1870 /**
1871 * @tc.expected: node.first + count in static_cast<size_t>(node.first) >= index && node.first != -1.
1872 */
1873 lazyForEachBuilder->expiringItem_["6"] = LazyForEachCacheChild(6, nullptr);
1874 lazyForEachBuilder->OnDataBulkAdded(6, 3);
1875 EXPECT_EQ(lazyForEachBuilder->expiringItem_["6"].first, 9);
1876 /**
1877 * @tc.expected: node.first dont change in node.first == -1.
1878 */
1879 lazyForEachBuilder->expiringItem_["6"] = LazyForEachCacheChild(-1, nullptr);
1880 lazyForEachBuilder->OnDataAdded(-1);
1881 EXPECT_EQ(lazyForEachBuilder->expiringItem_["6"].first, -1);
1882 }
1883
1884 /**
1885 * @tc.name: LazyForEachBuilder28
1886 * @tc.desc: test the founction of OnDataDeleted in LazyForEachBuilder.
1887 * @tc.type: FUNC
1888 */
1889 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder28, TestSize.Level1)
1890 {
1891 auto lazyForEachBuilder = CreateLazyForEachBuilder();
1892 ASSERT_NE(lazyForEachBuilder, nullptr);
1893 /**
1894 * @tc.expected: child.first = -1 in static_cast<size_t>(child.first) == index.
1895 */
1896 lazyForEachBuilder->expiringItem_["6"] = LazyForEachCacheChild(6, nullptr);
1897 lazyForEachBuilder->OnDataDeleted(6);
1898 EXPECT_EQ(lazyForEachBuilder->expiringItem_["6"].first, -1);
1899 /**
1900 * @tc.expected: return node nullptr in static_cast<size_t>(child.first) < index.
1901 */
1902 lazyForEachBuilder->expiringItem_["6"] = LazyForEachCacheChild(6, nullptr);
1903 ASSERT_EQ(lazyForEachBuilder->OnDataDeleted(10), nullptr);
1904 }
1905
1906 /**
1907 * @tc.name: LazyForEachBuilder29
1908 * @tc.desc: test the founction of OnDataBulkDeleted in LazyForEachBuilder.
1909 * @tc.type: FUNC
1910 */
1911 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder29, TestSize.Level1)
1912 {
1913 auto lazyForEachBuilder = CreateLazyForEachBuilder(true);
1914 ASSERT_NE(lazyForEachBuilder, nullptr);
1915 lazyForEachBuilder->expiringItem_["-1"] = LazyForEachCacheChild(-1, nullptr);
1916 lazyForEachBuilder->expiringItem_["5"] = LazyForEachCacheChild(5, nullptr);
1917 lazyForEachBuilder->expiringItem_["7"] = LazyForEachCacheChild(7, nullptr);
1918 lazyForEachBuilder->expiringItem_["10"] = LazyForEachCacheChild(10, nullptr);
1919 lazyForEachBuilder->OnDataBulkDeleted(6, 2);
1920 /**
1921 * @tc.expected: child.first -= count when static_cast<size_t>(child.first) >= index + count.
1922 */
1923 EXPECT_EQ(lazyForEachBuilder->expiringItem_.find("10")->second.first, 8);
1924 /**
1925 * @tc.expected: child.first no change when child.first < index and child.first>0.
1926 */
1927 EXPECT_EQ(lazyForEachBuilder->expiringItem_.find("5")->second.first, 5);
1928 bool negativeFlag = false;
1929 bool normalLimitFlag = false;
1930 for (const auto& item : lazyForEachBuilder->nodeList_) {
1931 if (item.first == "-1") {
1932 negativeFlag = true;
1933 } else if (item.first == "7") {
1934 normalLimitFlag = true;
1935 }
1936 }
1937 /**
1938 * @tc.expected: nodeList_ contains -1 when child.first < 0.
1939 */
1940 EXPECT_TRUE(negativeFlag);
1941 /**
1942 * @tc.expected: nodeList_ contains 7 when child.first >= index && child.first < index + count.
1943 */
1944 EXPECT_TRUE(normalLimitFlag);
1945 }
1946
1947 /**
1948 * @tc.name: LazyForEachBuilder30
1949 * @tc.desc: test the founction of GetItems in LazyForEachBuilder.
1950 * @tc.type: FUNC
1951 */
1952 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder30, TestSize.Level1)
1953 {
1954 auto lazyForEachBuilder = CreateLazyForEachBuilder(true);
1955 ASSERT_NE(lazyForEachBuilder, nullptr);
1956 std::list<std::pair<std::string, RefPtr<UINode>>> childList;
1957 lazyForEachBuilder->isLoop_ = true;
1958 auto node = AceType::MakeRefPtr<NG::FrameNode>(V2::TEXT_ETS_TAG, 666, AceType::MakeRefPtr<NG::Pattern>());
1959 node->isActive_ = true;
1960 lazyForEachBuilder->cachedItems_ = { { 1, { "1", node } }, { 3, { "3", node } }, { 5, { "5", node } } };
1961 lazyForEachBuilder->GetItems(childList);
1962 /**
1963 * @tc.expected: startIndex_ = 3 and endIndex_ = 1 when lastIndex > -1 && index - lastIndex > 1.
1964 */
1965 EXPECT_EQ(lazyForEachBuilder->startIndex_, 3);
1966 EXPECT_EQ(lazyForEachBuilder->endIndex_, 1);
1967 /**
1968 * @tc.expected: startIndex_ = 1 and endIndex_ = 3 when index - lastIndex <= 1.
1969 */
1970 lazyForEachBuilder->cachedItems_ = { { 1, { "1", node } }, { 2, { "2", node } }, { 3, { "3", node } } };
1971 lazyForEachBuilder->GetItems(childList);
1972 EXPECT_EQ(lazyForEachBuilder->startIndex_, 1);
1973 EXPECT_EQ(lazyForEachBuilder->endIndex_, 3);
1974 }
1975
1976 /**
1977 * @tc.name: LazyForEachBuilder31
1978 * @tc.desc: test the founction of RepairDatasetItems in LazyForEachBuilder.
1979 * @tc.type: FUNC
1980 */
1981 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder31, TestSize.Level1)
1982 {
1983 auto lazyForEachBuilder = CreateLazyForEachBuilder(true);
1984 ASSERT_NE(lazyForEachBuilder, nullptr);
1985 std::map<int32_t, LazyForEachChild> cachedTemp = {
1986 { 1, { "1", nullptr } },
1987 { 2, { "2", nullptr } },
1988 };
1989 std::map<int32_t, int32_t> indexChangedMap;
1990 std::map<int32_t, LazyForEachChild> expiringTempItem;
1991 OperationInfo operationinfo;
1992 lazyForEachBuilder->operationList_[0] = operationinfo;
1993 lazyForEachBuilder->RepairDatasetItems(cachedTemp, expiringTempItem, indexChangedMap);
1994 /**
1995 * @tc.expected: key = 1 when OperationInfo default & indexChangedMap.empty().
1996 */
1997 EXPECT_TRUE(expiringTempItem.find(1) != expiringTempItem.end());
1998 lazyForEachBuilder->operationList_.clear();
1999 expiringTempItem.clear();
2000 indexChangedMap = {
2001 { 1, 3 },
2002 };
2003 operationinfo.isChanged = true;
2004 lazyForEachBuilder->operationList_[0] = operationinfo;
2005 lazyForEachBuilder->RepairDatasetItems(cachedTemp, expiringTempItem, indexChangedMap);
2006 /**
2007 * @tc.expected: key = 4 when OperationInfo isChanged.
2008 */
2009 EXPECT_TRUE(expiringTempItem.find(4) != expiringTempItem.end());
2010 }
2011
2012 /**
2013 * @tc.name: LazyForEachBuilder32
2014 * @tc.desc: test the founction of RepairMoveOrExchange in LazyForEachBuilder.
2015 * @tc.type: FUNC
2016 */
2017 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder32, TestSize.Level1)
2018 {
2019 auto lazyForEachBuilder = CreateLazyForEachBuilder(true);
2020 ASSERT_NE(lazyForEachBuilder, nullptr);
2021 auto node = AceType::MakeRefPtr<NG::FrameNode>(V2::TEXT_ETS_TAG, 666, AceType::MakeRefPtr<NG::Pattern>());
2022 std::map<int32_t, LazyForEachChild> cachedTemp = {
2023 { 0, { "0", node } },
2024 { 1, { "1", nullptr } },
2025 };
2026 std::map<int32_t, LazyForEachChild> expiringTempItem;
2027 OperationInfo operationinfo;
2028 operationinfo.isExchange = true;
2029 lazyForEachBuilder->RepairMoveOrExchange(expiringTempItem, operationinfo, cachedTemp[0], 1, 0);
2030 /**
2031 * @tc.expected: nodeList size = 1 when info.node == nullptr && child.second != nullptr.
2032 */
2033 EXPECT_EQ(lazyForEachBuilder->nodeList_.size(), 1);
2034 EXPECT_EQ(expiringTempItem.size(), 0);
2035 lazyForEachBuilder->nodeList_.clear();
2036 /**
2037 * @tc.expected: nodeList expiringTempItem size = 0 when info.node == nullptr && child.second == nullptr.
2038 */
2039 lazyForEachBuilder->RepairMoveOrExchange(expiringTempItem, operationinfo, cachedTemp[1], 1, 0);
2040 EXPECT_EQ(lazyForEachBuilder->nodeList_.size(), 0);
2041 EXPECT_EQ(expiringTempItem.size(), 0);
2042 /**
2043 * @tc.expected: expiringTempItem size = 1 when info.node != nullptrr.
2044 */
2045 operationinfo.node = node;
2046 lazyForEachBuilder->RepairMoveOrExchange(expiringTempItem, operationinfo, cachedTemp[0], 1, 0);
2047 EXPECT_EQ(lazyForEachBuilder->nodeList_.size(), 0);
2048 EXPECT_EQ(expiringTempItem.size(), 1);
2049 operationinfo.isExchange = false;
2050 operationinfo.moveIn = true;
2051 operationinfo.fromDiffTo = 1;
2052 operationinfo.key = "6";
2053 expiringTempItem.clear();
2054 lazyForEachBuilder->RepairMoveOrExchange(expiringTempItem, operationinfo, cachedTemp[0], 1, 1);
2055 /**
2056 * @tc.expected: expiringTempItem size = 2 when fromDiffTo > 0.
2057 */
2058 EXPECT_EQ(expiringTempItem.size(), 2);
2059 }
2060
2061 /**
2062 * @tc.name: LazyForEachBuilderRemoveAllChild001
2063 * @tc.desc: Create LazyForEach.
2064 * @tc.type: FUNC
2065 */
2066 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilderRemoveAllChild001, TestSize.Level1)
2067 {
2068 /**
2069 * @tc.steps: step1. Create CreateLazyForEachBuilder
2070 * @tc.expected: Create CreateLazyForEachBuilder success.
2071 */
2072 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2073 ASSERT_NE(lazyForEachBuilder, nullptr);
2074
2075 /**
2076 * @tc.steps: step2. Invoke RemoveAllChild function.
2077 * @tc.expected: Mock cachedItems_ to RemoveAllChild success.
2078 */
2079 std::string str1 = "1";
2080 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
2081 lazyForEachBuilder->RemoveAllChild();
2082 EXPECT_EQ(lazyForEachBuilder->expiringItem_.size(), 6);
2083 }
2084
2085 /**
2086 * @tc.name: LazyForEachBuilderSetActiveChildRange001
2087 * @tc.desc: Create LazyForEach.
2088 * @tc.type: FUNC
2089 */
2090 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilderSetActiveChildRange001, TestSize.Level1)
2091 {
2092 /**
2093 * @tc.steps: step1. Create CreateLazyForEachBuilder
2094 * @tc.expected: Create CreateLazyForEachBuilder success.
2095 */
2096 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2097 ASSERT_NE(lazyForEachBuilder, nullptr);
2098 for (auto& [index, node] : lazyForEachBuilder->cachedItems_) {
2099 lazyForEachBuilder->expiringItem_.try_emplace(node.first, LazyForEachCacheChild(-1, std::move(node.second)));
2100 }
2101
2102 /**
2103 * @tc.steps: step2. Invoke SetActiveChildRange function.
2104 * @tc.expected: Mock cachedItems_ to SetActiveChildRange success.
2105 */
2106 std::string str0 = "0";
2107 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
2108 std::string str9 = "9";
2109 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str9, nullptr);
2110 auto ret = lazyForEachBuilder->SetActiveChildRange(0, 1);
2111 EXPECT_EQ(lazyForEachBuilder->expiringItem_.size(), 6);
2112 EXPECT_TRUE(ret);
2113 }
2114
2115 /**
2116 * @tc.name: LazyForEachBuilderSetActiveChildRange002
2117 * @tc.desc: Create LazyForEach.
2118 * @tc.type: FUNC
2119 */
2120 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilderSetActiveChildRange002, TestSize.Level1)
2121 {
2122 /**
2123 * @tc.steps: step1. Create CreateLazyForEachBuilder
2124 * @tc.expected: Create CreateLazyForEachBuilder success.
2125 */
2126 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2127 ASSERT_NE(lazyForEachBuilder, nullptr);
2128
2129 lazyForEachBuilder->expiringItem_.try_emplace(lazyForEachBuilder->cachedItems_[2].first,
2130 LazyForEachCacheChild(-1, lazyForEachBuilder->cachedItems_[2].second));
2131 lazyForEachBuilder->expiringItem_.try_emplace(lazyForEachBuilder->cachedItems_[3].first,
2132 LazyForEachCacheChild(-1, std::move(lazyForEachBuilder->cachedItems_[3].second)));
2133
2134 /**
2135 * @tc.steps: step2. Invoke SetActiveChildRange function.
2136 * @tc.expected: Mock cachedItems_ to SetActiveChildRange success.
2137 */
2138 auto ret = lazyForEachBuilder->SetActiveChildRange(0, 1);
2139 EXPECT_EQ(lazyForEachBuilder->expiringItem_.size(), 5);
2140 EXPECT_TRUE(ret);
2141 }
2142
2143 /**
2144 * @tc.name: LazyForEachBuilderGetChildIndex001
2145 * @tc.desc: Create LazyForEach.
2146 * @tc.type: FUNC
2147 */
2148 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilderGetChildIndex001, TestSize.Level1)
2149 {
2150 /**
2151 * @tc.steps: step1. Create CreateLazyForEachBuilder
2152 * @tc.expected: Create CreateLazyForEachBuilder success.
2153 */
2154 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2155 ASSERT_NE(lazyForEachBuilder, nullptr);
2156 for (auto& [index, node] : lazyForEachBuilder->cachedItems_) {
2157 lazyForEachBuilder->expiringItem_.try_emplace(node.first, LazyForEachCacheChild(-1, std::move(node.second)));
2158 }
2159 /**
2160 * @tc.steps: step2. Invoke GetChildIndex function.
2161 * @tc.expected: Mock cachedItems_ and expiringItem_ to GetChildIndex success.
2162 */
2163 std::string str0 = "0";
2164 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
2165 lazyForEachBuilder->expiringItem_["0"] = LazyForEachCacheChild(0, nullptr);
2166 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
2167 lazyForEachBuilder->expiringItem_["2"] = LazyForEachCacheChild(2, frameNode);
2168 auto ret = lazyForEachBuilder->GetChildIndex(frameNode);
2169 EXPECT_NE(ret, -1);
2170
2171 /**
2172 * @tc.steps: step3. Invoke GetChildIndex function.
2173 * @tc.expected: Mock cachedItems_ and expiringItem_ to GetChildIndex failed and return default value.
2174 */
2175 auto listNode = CreateNode(V2::LIST_ETS_TAG);
2176 ret = lazyForEachBuilder->GetChildIndex(listNode);
2177 EXPECT_EQ(ret, -1);
2178 }
2179
2180 /**
2181 * @tc.name: LazyForEachBuilderCacheItem001
2182 * @tc.desc: Create LazyForEach.
2183 * @tc.type: FUNC
2184 */
2185 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilderCacheItem001, TestSize.Level1)
2186 {
2187 /**
2188 * @tc.steps: step1. Create CreateLazyForEachBuilder
2189 * @tc.expected: Create CreateLazyForEachBuilder success.
2190 */
2191 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2192 ASSERT_NE(lazyForEachBuilder, nullptr);
2193 for (auto& [index, node] : lazyForEachBuilder->cachedItems_) {
2194 lazyForEachBuilder->expiringItem_.try_emplace(node.first, LazyForEachCacheChild(-1, std::move(node.second)));
2195 }
2196 /**
2197 * @tc.steps: step2. Invoke GetChildIndex function.
2198 * @tc.expected: Mock cachedItems_ and expiringItem_ to GetChildIndex success.
2199 */
2200 LayoutConstraintF layoutConstraint;
2201 layoutConstraint.parentIdealSize = OptionalSizeF(768, 1024);
2202 layoutConstraint.selfIdealSize = OptionalSizeF(480, 960);
2203 std::unordered_map<std::string, LazyForEachCacheChild> cache;
2204 bool isTimeout = false;
2205 auto ret = lazyForEachBuilder->CacheItem(0, cache, layoutConstraint, 10, isTimeout);
2206 EXPECT_EQ(ret->GetId(), -1);
2207 }
2208
2209 /**
2210 * @tc.name: LazyForEachBuilderOperateReload001
2211 * @tc.desc: LazyForEachBuilder::OperateReload
2212 * @tc.type: FUNC
2213 */
2214 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilderOperateReload001, TestSize.Level1)
2215 {
2216 /**
2217 * @tc.steps: step1. Create LazyForEachBuilder
2218 * @tc.expected: Create LazyForEachBuilder success.
2219 */
2220 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2221 ASSERT_NE(lazyForEachBuilder, nullptr);
2222
2223 /**
2224 * @tc.steps: step2. Mock expiringTemp
2225 * @tc.expected: the count of expiringItem_ add the count of expiringTemp.
2226 */
2227 std::map<int32_t, LazyForEachChild> expiringTemp;
2228 expiringTemp.emplace(8, LazyForEachChild("8", nullptr));
2229 lazyForEachBuilder->OperateReload(expiringTemp);
2230 EXPECT_EQ(lazyForEachBuilder->expiringItem_.size(), 8);
2231 }
2232
2233 /**
2234 * @tc.name: LazyForEachBuilderFindItem001
2235 * @tc.desc: LazyForEachBuilder::FindItem
2236 * @tc.type: FUNC
2237 */
2238 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilderFindItem001, TestSize.Level1)
2239 {
2240 /**
2241 * @tc.steps: step1. Create LazyForEachBuilder
2242 * @tc.expected: Create LazyForEachBuilder success.
2243 */
2244 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2245 ASSERT_NE(lazyForEachBuilder, nullptr);
2246
2247 /**
2248 * @tc.steps: step2. Mock cachedTemp
2249 * @tc.expected: Find the node success.
2250 */
2251 std::map<int32_t, LazyForEachChild> cachedTemp;
2252 std::map<int32_t, LazyForEachChild> expiringTemp;
2253 cachedTemp.emplace(8, LazyForEachChild("8", CreateNode(V2::TEXT_ETS_TAG)));
2254 auto iter = lazyForEachBuilder->FindItem(8, cachedTemp, expiringTemp);
2255 EXPECT_EQ(iter->first, 8);
2256 }
2257
2258 /**
2259 * @tc.name: LazyForEachBuilderOperateExchange001
2260 * @tc.desc: LazyForEachBuilder::OperateExchange
2261 * @tc.type: FUNC
2262 */
2263 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilderOperateExchange001, TestSize.Level1)
2264 {
2265 /**
2266 * @tc.steps: step1. Create LazyForEachBuilder
2267 * @tc.expected: Create LazyForEachBuilder success.
2268 */
2269 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2270 ASSERT_NE(lazyForEachBuilder, nullptr);
2271
2272 /**
2273 * @tc.steps: step2. Mock cachedTemp and expiringTemp to Invoke OperateExchange Function
2274 * @tc.expected: Invoke OperateExchange success.
2275 */
2276 std::map<int32_t, LazyForEachChild> cachedTemp;
2277 std::map<int32_t, LazyForEachChild> expiringTemp;
2278 V2::Operation operation;
2279 operation.index = 0;
2280 operation.type = "exchange";
2281 operation.count = 8;
2282 operation.coupleIndex = std::pair(1, 3);
2283 int32_t initialIndex = 0;
2284 lazyForEachBuilder->totalCountOfOriginalDataset_ = 9;
2285 cachedTemp.emplace(1, LazyForEachChild("1", CreateNode(V2::TEXT_ETS_TAG)));
2286 expiringTemp.emplace(3, LazyForEachChild("3", CreateNode(V2::TEXT_ETS_TAG)));
2287 lazyForEachBuilder->OperateExchange(operation, initialIndex, cachedTemp, expiringTemp);
2288 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 2);
2289 EXPECT_TRUE(lazyForEachBuilder->operationList_.find(3) != lazyForEachBuilder->operationList_.end());
2290 /**
2291 * @tc.steps: step3. Set coupleKey Invoke OperateExchange Function
2292 * @tc.expected: Invoke OperateExchange success.
2293 */
2294 lazyForEachBuilder->operationList_.clear();
2295 operation.coupleKey = std::pair("1", "3");
2296 lazyForEachBuilder->OperateExchange(operation, initialIndex, cachedTemp, expiringTemp);
2297 EXPECT_EQ(lazyForEachBuilder->operationList_.size(), 2);
2298 EXPECT_TRUE(lazyForEachBuilder->operationList_.find(1) != lazyForEachBuilder->operationList_.end());
2299 }
2300
2301 /**
2302 * @tc.name: CheckCacheIndex01
2303 * @tc.desc: Test the CheckCacheIndex function.
2304 * @tc.type: FUNC
2305 */
2306 HWTEST_F(LazyForEachSyntaxTestNg, CheckCacheIndex01, TestSize.Level1)
2307 {
2308 /**
2309 * @tc.steps: step1. Create ForEachBuilder and make count = 0.
2310 * @tc.expected: Create lazyForEachBuilder success and Invoke CheckCacheIndex function.
2311 */
2312 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2313 ASSERT_NE(lazyForEachBuilder, nullptr);
2314 std::set<int32_t> idleIndexes;
2315 lazyForEachBuilder->CheckCacheIndex(idleIndexes, 0);
2316 EXPECT_EQ(idleIndexes.size(), 0);
2317 /**
2318 * @tc.steps: step2. Create ForEachBuilder and make isLoop = true.
2319 * @tc.expected: make (startIndex_ <= endIndex_ && endIndex_ + i < count) = true.
2320 */
2321 idleIndexes.clear();
2322 lazyForEachBuilder->isLoop_ = true;
2323 lazyForEachBuilder->cacheCount_ = 3;
2324 lazyForEachBuilder->startIndex_ = 1;
2325 lazyForEachBuilder->endIndex_ = 1;
2326 lazyForEachBuilder->CheckCacheIndex(idleIndexes, 5);
2327 EXPECT_EQ(idleIndexes.count(2), 1);
2328 /**
2329 * @tc.steps: step3. Create ForEachBuilder and make isLoop = true.
2330 * @tc.expected: Create lazyForEachBuilder success and startIndex_ > endIndex_ + i.
2331 */
2332 idleIndexes.clear();
2333 lazyForEachBuilder->isLoop_ = true;
2334 lazyForEachBuilder->cacheCount_ = 2;
2335 lazyForEachBuilder->startIndex_ = 4;
2336 lazyForEachBuilder->endIndex_ = 1;
2337 lazyForEachBuilder->CheckCacheIndex(idleIndexes, 5);
2338 EXPECT_EQ(idleIndexes.count(2), 1);
2339 EXPECT_EQ(idleIndexes.count(3), 1);
2340 }
2341
2342 /**
2343 * @tc.name: CheckCacheIndex02
2344 * @tc.desc: Test the CheckCacheIndex function.
2345 * @tc.type: FUNC
2346 */
2347 HWTEST_F(LazyForEachSyntaxTestNg, CheckCacheIndex02, TestSize.Level1)
2348 {
2349 /**
2350 * @tc.steps: step1. Create ForEachBuilder and make isLoop = true.
2351 * @tc.expected: Create lazyForEachBuilder success and (endIndex_ + i) % count < startIndex_.
2352 */
2353 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2354 ASSERT_NE(lazyForEachBuilder, nullptr);
2355 lazyForEachBuilder->isLoop_ = true;
2356 lazyForEachBuilder->cacheCount_ = 3;
2357 lazyForEachBuilder->startIndex_ = 2;
2358 lazyForEachBuilder->endIndex_ = 4;
2359 std::set<int32_t> idleIndexes;
2360 lazyForEachBuilder->CheckCacheIndex(idleIndexes, 5);
2361 EXPECT_EQ(idleIndexes.count(1), 1);
2362 /**
2363 * @tc.steps: step2. Create ForEachBuilder and make isLoop = true.
2364 * @tc.expected: Create lazyForEachBuilder success and (startIndex_ <= endIndex_ && startIndex_ >= i).
2365 */
2366 idleIndexes.clear();
2367 lazyForEachBuilder->cacheCount_ = 3;
2368 lazyForEachBuilder->startIndex_ = 2;
2369 lazyForEachBuilder->endIndex_ = 3;
2370 lazyForEachBuilder->CheckCacheIndex(idleIndexes, 5);
2371 EXPECT_EQ(idleIndexes.count(1), 1);
2372 /**
2373 * @tc.steps: step3. Create ForEachBuilder and make isLoop = true.
2374 * @tc.expected: Create lazyForEachBuilder success and startIndex_ > endIndex_ + i.
2375 */
2376 idleIndexes.clear();
2377 lazyForEachBuilder->cacheCount_ = 3;
2378 lazyForEachBuilder->startIndex_ = 3;
2379 lazyForEachBuilder->endIndex_ = 1;
2380 lazyForEachBuilder->CheckCacheIndex(idleIndexes, 5);
2381 EXPECT_EQ(idleIndexes.count(2), 1);
2382 /**
2383 * @tc.steps: step4. Create ForEachBuilder and make isLoop = true.
2384 * @tc.expected: Create lazyForEachBuilder success and (startIndex_ - i + count) % count > endIndex_.
2385 */
2386 idleIndexes.clear();
2387 lazyForEachBuilder->cacheCount_ = 3;
2388 lazyForEachBuilder->startIndex_ = 5;
2389 lazyForEachBuilder->endIndex_ = 1;
2390 lazyForEachBuilder->CheckCacheIndex(idleIndexes, 6);
2391 EXPECT_EQ(idleIndexes.count(2), 1);
2392 }
2393
2394 /**
2395 * @tc.name: PreBuildByIndex01
2396 * @tc.desc: Test the PreBuildByIndex function.
2397 * @tc.type: FUNC
2398 */
2399 HWTEST_F(LazyForEachSyntaxTestNg, PreBuildByIndex01, TestSize.Level1)
2400 {
2401 /**
2402 * @tc.steps: make GetSysTimestamp() > deadline make canRunLongPredictTask to false.
2403 * @tc.expected: Create lazyForEachBuilder success and make isTimeout to false.
2404 */
2405 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2406 ASSERT_NE(lazyForEachBuilder, nullptr);
2407 int32_t index = 0;
2408 std::unordered_map<std::string, LazyForEachCacheChild> cache;
2409 int64_t deadline = GetSysTimestamp() + 10000;
2410 auto itemConstraint = LayoutConstraintF();
2411 bool canRunLongPredictTask = false;
2412 bool result = lazyForEachBuilder->PreBuildByIndex(index, cache, deadline, itemConstraint, canRunLongPredictTask);
2413 EXPECT_EQ(result, false);
2414 }
2415
2416 /**
2417 * @tc.name: PreBuildByIndex02
2418 * @tc.desc: Test the PreBuildByIndex function.
2419 * @tc.type: FUNC
2420 */
2421 HWTEST_F(LazyForEachSyntaxTestNg, PreBuildByIndex02, TestSize.Level1)
2422 {
2423 /**
2424 * @tc.steps: make GetSysTimestamp() > deadline and canRunLongPredictTask to true.
2425 * @tc.expected: Create lazyForEachBuilder success and isTimeout to false.
2426 */
2427 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2428 ASSERT_NE(lazyForEachBuilder, nullptr);
2429 int32_t index = 0;
2430 std::unordered_map<std::string, LazyForEachCacheChild> cache;
2431 int64_t deadline = GetSysTimestamp() + 10000;
2432 std::optional<LayoutConstraintF> itemConstraint;
2433 bool canRunLongPredictTask = true;
2434 bool result = lazyForEachBuilder->PreBuildByIndex(index, cache, deadline, itemConstraint, canRunLongPredictTask);
2435 EXPECT_EQ(result, true);
2436 }
2437 /**
2438 * @tc.name: LazyForEachBuilder33
2439 * @tc.desc: Test the ProcessOffscreenNode function.
2440 * @tc.type: FUNC
2441 */
2442 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder33, TestSize.Level1)
2443 {
2444 /**
2445 * @tc.steps: step1. Invoke lazyForEach Create function.
2446 * @tc.expected: Create lazyForEachBuilder.
2447 */
2448 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2449 ASSERT_NE(lazyForEachBuilder, nullptr);
2450 /**
2451 * @tc.steps: step2. Invoke lazyForEach CacheItem function.
2452 * @tc.expected: Create uiNode.
2453 */
2454 LayoutConstraintF layoutConstraint;
2455 layoutConstraint.parentIdealSize = OptionalSizeF(768, 1024);
2456 layoutConstraint.selfIdealSize = OptionalSizeF(480, 960);
2457 std::unordered_map<std::string, LazyForEachCacheChild> cache;
2458 bool isTimeout = false;
2459 auto uiNode = lazyForEachBuilder->CacheItem(0, cache, layoutConstraint, 10, isTimeout);
2460 /**
2461 * @tc.steps: step3. Invoke ProcessOffscreenNode function.
2462 * @tc.expected: Create ProcessOffscreenNode.
2463 */
2464 lazyForEachBuilder->ProcessOffscreenNode(uiNode, false);
2465 EXPECT_NE(uiNode, nullptr);
2466 }
2467
2468 /**
2469 * @tc.name: LazyForEachBuilder34
2470 * @tc.desc: Test the ProcessCachedIndex function.
2471 * @tc.type: FUNC
2472 */
2473 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder34, TestSize.Level1)
2474 {
2475 /**
2476 * @tc.steps: step1. Invoke lazyForEach Create function.
2477 * @tc.expected: Create lazyForEachBuilder.
2478 */
2479 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2480 ASSERT_NE(lazyForEachBuilder, nullptr);
2481 /**
2482 * @tc.steps: step2. Create node and lazyForEach expiringItem_ and idleIndexes.
2483 */
2484 auto node = AceType::MakeRefPtr<NG::FrameNode>(V2::TEXT_ETS_TAG, 666, AceType::MakeRefPtr<NG::Pattern>());
2485 std::unordered_map<std::string, LazyForEachCacheChild> cache;
2486 std::set<int32_t> idleIndexes;
2487 idleIndexes.insert(1);
2488 idleIndexes.insert(2);
2489 idleIndexes.insert(3);
2490 idleIndexes.insert(4);
2491 lazyForEachBuilder->expiringItem_["0"].second = node;
2492 lazyForEachBuilder->expiringItem_["1"].second = node;
2493 lazyForEachBuilder->expiringItem_["2"].second = node;
2494 lazyForEachBuilder->expiringItem_["0"].first = 1;
2495 lazyForEachBuilder->expiringItem_["1"].first = 2;
2496 lazyForEachBuilder->expiringItem_["2"].first = 3;
2497 /**
2498 * @tc.steps: step3. Invoke the ProcessCachedIndex function.
2499 * @tc.expected: Create ProcessCachedIndex.
2500 */
2501 lazyForEachBuilder->ProcessCachedIndex(cache, idleIndexes);
2502 EXPECT_EQ(lazyForEachBuilder->expiringItem_["0"].first, 1);
2503 EXPECT_EQ(lazyForEachBuilder->expiringItem_["1"].first, 2);
2504 EXPECT_EQ(lazyForEachBuilder->expiringItem_["2"].first, 3);
2505 }
2506
2507 /**
2508 * @tc.name: LazyForEachBuilder35
2509 * @tc.desc: Test the SetJSViewActive function.
2510 * @tc.type: FUNC
2511 */
2512 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder35, TestSize.Level1)
2513 {
2514 /**
2515 * @tc.steps: step1. Invoke lazyForEach Create function.
2516 * @tc.expected: Create lazyForEachBuilder.
2517 */
2518 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2519 /**
2520 * @tc.steps: step2. Create node and lazyForEach expiringItem_ and cachedItems_.
2521 */
2522 auto node = AceType::MakeRefPtr<NG::FrameNode>(V2::TEXT_ETS_TAG, 666, AceType::MakeRefPtr<NG::Pattern>());
2523 std::string str0 = "0";
2524 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
2525 std::string str1 = "1";
2526 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
2527 std::string str2 = "2";
2528 lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
2529 lazyForEachBuilder->expiringItem_["1"] = LazyForEachCacheChild(-1, nullptr);
2530 lazyForEachBuilder->expiringItem_["2"] = LazyForEachCacheChild(5, nullptr);
2531 lazyForEachBuilder->expiringItem_["3"] = LazyForEachCacheChild(7, node);
2532 /**
2533 * @tc.steps: step3. Invoke the SetJSViewActive function.
2534 * @tc.expected: Set active to true.
2535 */
2536 lazyForEachBuilder->SetJSViewActive(true);
2537 EXPECT_EQ(lazyForEachBuilder->expiringItem_.size(), 3);
2538 }
2539
2540 /**
2541 * @tc.name: LazyForEachBuilder36
2542 * @tc.desc: Test the PaintDebugBoundaryTreeAll function.
2543 * @tc.type: FUNC
2544 */
2545 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder36, TestSize.Level1)
2546 {
2547 /**
2548 * @tc.steps: step1. Invoke lazyForEach Create function.
2549 * @tc.expected: Create lazyForEachBuilder.
2550 */
2551 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2552 /**
2553 * @tc.steps: step2. Create node and lazyForEach expiringItem_ and cachedItems_.
2554 */
2555 auto node = AceType::MakeRefPtr<NG::FrameNode>(V2::TEXT_ETS_TAG, 666, AceType::MakeRefPtr<NG::Pattern>());
2556 std::string str0 = "0";
2557 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
2558 std::string str1 = "1";
2559 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
2560 std::string str2 = "2";
2561 lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
2562 lazyForEachBuilder->expiringItem_["1"] = LazyForEachCacheChild(-1, nullptr);
2563 lazyForEachBuilder->expiringItem_["2"] = LazyForEachCacheChild(5, nullptr);
2564 lazyForEachBuilder->expiringItem_["3"] = LazyForEachCacheChild(7, node);
2565 /**
2566 * @tc.steps: step3. Invoke the PaintDebugBoundaryTreeAll function.
2567 * @tc.expected: Set condition to true.
2568 */
2569 lazyForEachBuilder->PaintDebugBoundaryTreeAll(true);
2570 EXPECT_EQ(lazyForEachBuilder->expiringItem_.size(), 3);
2571 }
2572
2573 /**
2574 * @tc.name: LazyForEachBuilder37
2575 * @tc.desc: Test the NotifyColorModeChange function.
2576 * @tc.type: FUNC
2577 */
2578 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder37, TestSize.Level1)
2579 {
2580 /**
2581 * @tc.steps: step1. Invoke lazyForEach Create function.
2582 * @tc.expected: Create lazyForEachBuilder.
2583 */
2584 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2585 /**
2586 * @tc.steps: step2. Create node and lazyForEach expiringItem_ and cachedItems_.
2587 */
2588 auto node = AceType::MakeRefPtr<NG::FrameNode>(V2::TEXT_ETS_TAG, 666, AceType::MakeRefPtr<NG::Pattern>());
2589 std::string str0 = "0";
2590 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild(str0, nullptr);
2591 std::string str1 = "1";
2592 lazyForEachBuilder->cachedItems_[1] = LazyForEachChild(str1, nullptr);
2593 std::string str2 = "2";
2594 lazyForEachBuilder->cachedItems_[2] = LazyForEachChild(str2, nullptr);
2595 lazyForEachBuilder->expiringItem_["1"] = LazyForEachCacheChild(-1, nullptr);
2596 lazyForEachBuilder->expiringItem_["2"] = LazyForEachCacheChild(5, nullptr);
2597 lazyForEachBuilder->expiringItem_["3"] = LazyForEachCacheChild(7, node);
2598 /**
2599 * @tc.steps: step3. Invoke the PaintDebugBoundaryTreeAll function.
2600 * @tc.expected: Set condition to true.
2601 */
2602 node->shouldRerender_ = false;
2603 lazyForEachBuilder->NotifyColorModeChange(1, true);
2604 EXPECT_TRUE(node->measureAnyWay_);
2605 EXPECT_TRUE(node->shouldRerender_);
2606 }
2607
2608 /**
2609 * @tc.name: LazyForEachBuilder38
2610 * @tc.desc: Test the NotifyColorModeChange function.
2611 * @tc.type: FUNC
2612 */
2613 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachBuilder38, TestSize.Level1)
2614 {
2615 auto lazyForEachBuilder = CreateLazyForEachBuilder();
2616 auto uiNode = AceType::MakeRefPtr<NG::CustomNode>(666, "node");
2617 auto childNode = AceType::MakeRefPtr<NG::CustomNode>(666, "childNode");
2618 uiNode->children_ = { childNode };
2619 uiNode->SetDarkMode(true);
2620 lazyForEachBuilder->cachedItems_[0] = LazyForEachChild("0", uiNode);
2621 EXPECT_FALSE(childNode->CheckIsDarkMode());
2622 lazyForEachBuilder->NotifyColorModeChange(1, true);
2623 EXPECT_TRUE(childNode->CheckIsDarkMode());
2624 }
2625 } // namespace OHOS::Ace::NG