1 /*
2 * Copyright (c) 2022 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 #include "core/pipeline/base/element_register.h"
24
25 #define private public
26 #define protected public
27 #include "mock_lazy_for_each_actuator.h"
28 #include "mock_lazy_for_each_builder.h"
29 #include "test/mock/core/pipeline/mock_pipeline_context.h"
30
31 #include "core/components_ng/base/view_stack_processor.h"
32 #include "core/components_ng/syntax/lazy_for_each_model_ng.h"
33 #include "core/components_ng/syntax/lazy_for_each_node.h"
34 #include "core/components_ng/syntax/lazy_layout_wrapper_builder.h"
35 #undef private
36 #undef protected
37
38 using namespace testing;
39 using namespace testing::ext;
40
41 namespace OHOS::Ace::NG {
42 namespace {
43 const std::list<std::optional<std::string>> LAZY_FOR_EACH_NODE_IDS = { "0", "1", "2", "3", "4", "5", "6" };
44 const std::list<std::optional<std::string>> DEFAULT_LAZY_FOR_EACH_NODE_IDS = {};
45 const std::list<std::optional<int32_t>> LAZY_FOR_EACH_NODE_IDS_INT = { 0, 1, 2, 3, 4, 5, 6 };
46 const std::unordered_map<int32_t, std::optional<std::string>> LAZY_FOR_EACH_CACHED_ITEMS = { { 0, "0" }, { 1, "1" } };
47 const std::list<int32_t> LAZY_FOR_EACH_ITEMS = { 0, 1, 2, 3, 4, 5 };
48 constexpr bool IS_ATOMIC_NODE = false;
49 constexpr int32_t NEW_START_ID = 0;
50 constexpr int32_t NEW_END_ID = 6;
51 constexpr int32_t INDEX_MIDDLE = 3;
52 constexpr int32_t INDEX_MIDDLE_2 = 4;
53 constexpr int32_t INDEX_2 = 2;
54 constexpr int32_t INDEX_8 = 8;
55 constexpr int32_t INDEX_1 = 1;
56 constexpr int32_t DEFAULT_INDEX = 0;
57 constexpr int32_t INDEX_4 = 4;
58 constexpr int32_t INDEX_3 = 3;
59 constexpr int32_t INDEX_5 = 5;
60 constexpr int32_t INDEX_0 = 0;
61 constexpr int32_t INDEX_7 = 7;
62 constexpr int32_t DEFAULT_SIZE = 0;
63 constexpr int32_t CACHE_COUNT = 5;
64 constexpr int32_t START_ID = 7;
65 constexpr int32_t INVALID_START_ID_LESS_THAN_0 = -1;
66 constexpr int32_t INVALID_START_ID_GREATER_THAN_TOTAL = 7;
67 constexpr int32_t INDEX_GREATER_THAN_END_INDEX = 20;
68 constexpr int32_t INDEX_LESS_THAN_START_INDEX = -1;
69 constexpr int32_t INDEX_EQUAL_WITH_START_INDEX = 1;
70 constexpr int32_t INDEX_EQUAL_WITH_START_INDEX_DELETED = -1;
71 constexpr int32_t LAZY_FOR_EACH_NODE_ID = 1;
72 constexpr size_t BUILDER_INDEX_ONDATADELETED_END = 4294967295;
73 } // namespace
74
75 class LazyForEachSyntaxTestNg : public testing::Test {
76 public:
77 void SetUp() override;
78 void TearDown() override;
79
80 RefPtr<FrameNode> CreateNode(const std::string& tag);
81
UpdateItems(const RefPtr<LazyForEachNode> & lazyForEachNode,const RefPtr<LazyForEachActuator> & mockLazyForEachActuator)82 static void UpdateItems(
83 const RefPtr<LazyForEachNode>& lazyForEachNode, const RefPtr<LazyForEachActuator>& mockLazyForEachActuator)
84 {
85 /**
86 * @tc.steps: step1. Add child found in generatedItem_.
87 */
88 auto ids = LAZY_FOR_EACH_NODE_IDS;
89 auto builder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
90 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
91 builder->GetChildByIndex(iter.value_or(0), true);
92 }
93 }
94
CreateLazyForEachNode()95 static RefPtr<LazyForEachNode> CreateLazyForEachNode()
96 {
97 /**
98 * @tc.steps: step1. Create Text and push it to view stack processor.
99 * @tc.expected: Make Text as LazyForEach parent.
100 */
101 auto pattern = AceType::MakeRefPtr<Pattern>();
102 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::TEXT_ETS_TAG, -1, pattern);
103 pattern->AttachToFrameNode(frameNode);
104 ViewStackProcessor::GetInstance()->Push(frameNode);
105
106 /**
107 * @tc.steps: step2. Invoke lazyForEach Create function.
108 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
109 */
110 LazyForEachModelNG lazyForEach;
111 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
112 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
113 lazyForEach.Create(mockLazyForEachActuator);
114 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
115 /**
116 * @tc.steps: step3. Add children items to lazyForEachNode.
117 */
118 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
119 return lazyForEachNode;
120 }
121 };
122
SetUp()123 void LazyForEachSyntaxTestNg::SetUp()
124 {
125 MockPipelineContext::SetUp();
126 }
127
TearDown()128 void LazyForEachSyntaxTestNg::TearDown()
129 {
130 MockPipelineContext::TearDown();
131 }
132
CreateNode(const std::string & tag)133 RefPtr<FrameNode> LazyForEachSyntaxTestNg::CreateNode(const std::string& tag)
134 {
135 auto pattern = AceType::MakeRefPtr<Pattern>();
136 auto frameNode = AceType::MakeRefPtr<FrameNode>(tag, -1, pattern);
137 pattern->AttachToFrameNode(frameNode);
138 ViewStackProcessor::GetInstance()->Push(frameNode);
139 return frameNode;
140 }
141
142 /**
143 * @tc.name: LazyForEachSyntaxCreateTest001
144 * @tc.desc: Create LazyForEach.
145 * @tc.type: FUNC
146 */
147 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxCreateTest001, TestSize.Level1)
148 {
149 /**
150 * @tc.steps: step1. Create Text and push it to view stack processor.
151 * @tc.expected: Make Text as LazyForEach parent.
152 */
153 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
154
155 /**
156 * @tc.steps: step2. Invoke lazyForEach Create function.
157 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
158 */
159 LazyForEachModelNG lazyForEach;
160 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
161 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
162 lazyForEach.Create(mockLazyForEachActuator);
163 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
164 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
165
166 EXPECT_EQ(lazyForEachNode->IsAtomicNode(), IS_ATOMIC_NODE);
167 EXPECT_EQ(lazyForEachNode->FrameCount(), 0);
168 }
169
170 /**
171 * @tc.name: ForEachSyntaxCreateTest002
172 * @tc.desc: Create LazyForEach and its parent node is Tabs.
173 * @tc.type: FUNC
174 */
175 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxCreateTest002, TestSize.Level1)
176 {
177 /**
178 * @tc.steps: step1. Create Tabs and push it to view stack processor.
179 * @tc.expected: Make Tabs as LazyForEach parent.
180 */
181 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
182
183 /**
184 * @tc.steps: step2. Invoke lazyForEach Create function.
185 * @tc.expected: LazyForEachNode will not be created when its parent is Tabs.
186 */
187 LazyForEachModelNG lazyForEach;
188 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
189 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
190 lazyForEach.Create(mockLazyForEachActuator);
191 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
192 EXPECT_NE(lazyForEachNode, nullptr);
193 }
194
195 /**
196 * @tc.name: ForEachSyntaxUpdateTest003
197 * @tc.desc: Create LazyForEach and its Update its Items.
198 * @tc.type: FUNC
199 */
200 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxUpdateTest003, TestSize.Level1)
201 {
202 /**
203 * @tc.steps: step1. Create Text and push it to view stack processor.
204 * @tc.expected: Make Text as LazyForEach parent.
205 */
206 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
207
208 /**
209 * @tc.steps: step2. Invoke lazyForEach Create function.
210 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
211 */
212 LazyForEachModelNG lazyForEach;
213 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
214 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
215 lazyForEach.Create(mockLazyForEachActuator);
216 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
217 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
218 }
219
220 /**
221 * @tc.name: ForEachSyntaxAddDataFunctionTest004
222 * @tc.desc: Create LazyForEach, update its Items and invoke OnDataAdded function.
223 * @tc.type: FUNC
224 */
225 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxFunctionTest004, TestSize.Level1)
226 {
227 /**
228 * @tc.steps: step1. Create Text and push it to view stack processor.
229 * @tc.expected: Make Text as LazyForEach parent.
230 */
231 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
232
233 /**
234 * @tc.steps: step2. Invoke lazyForEach Create function.
235 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
236 */
237 LazyForEachModelNG lazyForEach;
238 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
239 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
240 lazyForEach.Create(mockLazyForEachActuator);
241 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
242 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
243
244 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
245
246 /**
247 * @tc.steps: step3. Add index which is less than start index.
248 * @tc.expected: LazyForEachNode ids_ will not be added.
249 */
250 lazyForEachNode->OnDataAdded(INDEX_LESS_THAN_START_INDEX);
251 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
252
253 /**
254 * @tc.steps: step4. Add index which is greater than end index.
255 * @tc.expected: LazyForEachNode ids_ will not be added.
256 */
257 lazyForEachNode->OnDataAdded(INDEX_GREATER_THAN_END_INDEX);
258 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
259
260 /**
261 * @tc.steps: step5. Add index which is equal with start index.
262 * @tc.expected: LazyForEachNode ids_ will be added the item.
263 */
264 lazyForEachNode->OnDataAdded(INDEX_EQUAL_WITH_START_INDEX);
265 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
266
267 /**
268 * @tc.steps: step6. builder_ is null.
269 * @tc.expected: LazyForEachNode ids_ will be added the item.
270 */
271 lazyForEachNode->builder_ = nullptr;
272 lazyForEachNode->OnDataAdded(INDEX_EQUAL_WITH_START_INDEX);
273 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
274 }
275
276 /**
277 * @tc.name: ForEachSyntaxReloadDataFunctionTest005
278 * @tc.desc: Create LazyForEach, update its Items and invoke OnDataReloaded function.
279 * @tc.type: FUNC
280 */
281 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxReloadDataFunctionTest005, TestSize.Level1)
282 {
283 /**
284 * @tc.steps: step1. Create Text and push it to view stack processor.
285 * @tc.expected: Make Text as LazyForEach parent.
286 */
287 auto frameNode = CreateNode(V2::LIST_ETS_TAG);
288
289 /**
290 * @tc.steps: step2. Invoke lazyForEach Create function.
291 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
292 */
293 LazyForEachModelNG lazyForEach;
294 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
295 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
296 lazyForEach.Create(mockLazyForEachActuator);
297 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
298 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
299
300 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
301
302 /**
303 * @tc.steps: step3. Invoke OnDataReloaded.
304 * @tc.expected: LazyForEachNode ids_ will be cleared.
305 */
306 lazyForEachNode->OnDataReloaded();
307 EXPECT_TRUE(lazyForEachNode->ids_.empty());
308
309 /**
310 * @tc.steps: step4. builder_ is null.
311 * @tc.expected: LazyForEachNode ids_ will be cleared.
312 */
313 lazyForEachNode->builder_ = nullptr;
314 lazyForEachNode->OnDataReloaded();
315 EXPECT_TRUE(lazyForEachNode->ids_.empty());
316 }
317
318 /**
319 * @tc.name: ForEachSyntaxDeleteDataFunctionTest006
320 * @tc.desc: Create LazyForEach, update its Items and invoke OnDataDeleted function.
321 * @tc.type: FUNC
322 */
323 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxDeleteDataFunctionTest006, TestSize.Level1)
324 {
325 /**
326 * @tc.steps: step1. Create Text and push it to view stack processor.
327 * @tc.expected: Make Text as LazyForEach parent.
328 */
329 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
330
331 /**
332 * @tc.steps: step2. Invoke lazyForEach Create function.
333 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
334 */
335 LazyForEachModelNG lazyForEach;
336 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
337 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
338 lazyForEach.Create(mockLazyForEachActuator);
339 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
340 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
341
342 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
343
344 /**
345 * @tc.steps: step3. Delete index which is greater than end index.
346 * @tc.expected: LazyForEachNode ids_ will not be deleted.
347 */
348 lazyForEachNode->OnDataDeleted(INDEX_GREATER_THAN_END_INDEX);
349 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
350
351 /**
352 * @tc.steps: step4. Delete index which is less than start index.
353 * @tc.expected: LazyForEachNode ids_ will not be deleted.
354 */
355 lazyForEachNode->OnDataDeleted(INDEX_LESS_THAN_START_INDEX);
356 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
357
358 /**
359 * @tc.steps: step5. Delete index which is equal with start index.
360 * @tc.expected: LazyForEachNode ids_ will be deleted the item.
361 */
362 lazyForEachNode->OnDataDeleted(INDEX_1);
363 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
364
365 /**
366 * @tc.steps: step6. builder_ is null.
367 * @tc.expected: LazyForEachNode ids_ will be deleted the item.
368 */
369 lazyForEachNode->builder_ = nullptr;
370 lazyForEachNode->OnDataDeleted(INDEX_EQUAL_WITH_START_INDEX_DELETED);
371 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
372 }
373
374 /**
375 * @tc.name: ForEachSyntaxChangeDataFunctionTest007
376 * @tc.desc: Create LazyForEach, update its Items and invoke OnDataChanged function.
377 * @tc.type: FUNC
378 */
379 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxChangeDataFunctionTest007, TestSize.Level1)
380 {
381 /**
382 * @tc.steps: step1. Create Text and push it to view stack processor.
383 * @tc.expected: Make Text as LazyForEach parent.
384 */
385 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
386
387 /**
388 * @tc.steps: step2. Invoke lazyForEach Create function.
389 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
390 */
391 LazyForEachModelNG lazyForEach;
392 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
393 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
394 lazyForEach.Create(mockLazyForEachActuator);
395 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
396 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
397
398 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
399
400 /**
401 * @tc.steps: step3. Change index which is less than start index.
402 * @tc.expected: changeIndex is out of range, ignored.
403 */
404 lazyForEachNode->OnDataChanged(INDEX_LESS_THAN_START_INDEX);
405 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
406
407 /**
408 * @tc.steps: step4. Change index which is greater than end index.
409 * @tc.expected: changeIndex is out of range, ignored.
410 */
411 lazyForEachNode->OnDataChanged(INDEX_GREATER_THAN_END_INDEX);
412 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
413
414 /**
415 * @tc.steps: step5. Change index which is in the middle with start and end.
416 * @tc.expected: changeIndex is not out of range, change the index data.
417 */
418 lazyForEachNode->OnDataChanged(INDEX_MIDDLE);
419 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
420
421 /**
422 * @tc.steps: step6. builder_ is null.
423 * @tc.expected: changeIndex is not out of range, change the index data.
424 */
425 lazyForEachNode->builder_ = nullptr;
426 lazyForEachNode->OnDataChanged(INDEX_MIDDLE);
427 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
428 }
429
430 /**
431 * @tc.name: ForEachSyntaxSetOnMoveFunctionTest001
432 * @tc.desc: Create LazyForEach, update its Items and invoke SetOnMove function.
433 * @tc.type: FUNC
434 */
435 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxSetOnMoveFunctionTest001, TestSize.Level1)
436 {
437 /**
438 * @tc.steps: step1. Create Text and push it to view stack processor.
439 * @tc.expected: Make Text as LazyForEach parent.
440 */
441 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
442
443 /**
444 * @tc.steps: step2. Invoke lazyForEach Create function.
445 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
446 */
447 LazyForEachModelNG lazyForEach;
448 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
449 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
450 lazyForEach.Create(mockLazyForEachActuator);
451 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
452 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
453
454 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
455
__anond0d36a750202(int32_t a, int32_t b) 456 std::function<void(int32_t, int32_t)> lambda = [](int32_t a, int32_t b) {};
457
458 /**
459 * @tc.steps: step3. onMove not null and onMoveEvent_ not null.
460 */
461 lazyForEachNode->SetOnMove(std::move(lambda));
462 lazyForEachNode->onMoveEvent_ = std::move(lambda);
463 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
464
465 /**
466 * @tc.steps: step4. onMove not null and onMoveEvent_ is null.
467 */
468 lazyForEachNode->SetOnMove(std::move(lambda));
469 lazyForEachNode->onMoveEvent_ = nullptr;
470 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
471
472 /**
473 * @tc.steps: step5. onMove is null and onMoveEvent_ not null.
474 */
475 lazyForEachNode->SetOnMove(nullptr);
476 lazyForEachNode->onMoveEvent_ = std::move(lambda);
477 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
478
479 /**
480 * @tc.steps: step6. onMove is null and onMoveEvent_ is null.
481 */
482 lazyForEachNode->SetOnMove(nullptr);
483 lazyForEachNode->onMoveEvent_ = nullptr;
484 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
485 }
486
487 /**
488 * @tc.name: ForEachSyntaxMoveDataFunctionTest001
489 * @tc.desc: Create LazyForEach, update its Items and invoke MoveData function.
490 * @tc.type: FUNC
491 */
492 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxMoveDataFunctionTest001, TestSize.Level1)
493 {
494 /**
495 * @tc.steps: step1. Create Text and push it to view stack processor.
496 * @tc.expected: Make Text as LazyForEach parent.
497 */
498 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
499
500 /**
501 * @tc.steps: step2. Invoke lazyForEach Create function.
502 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
503 */
504 LazyForEachModelNG lazyForEach;
505 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
506 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
507 lazyForEach.Create(mockLazyForEachActuator);
508 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
509 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
510
511 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
512
513
514 lazyForEachNode->MoveData(INDEX_LESS_THAN_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
515 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
516
517 /**
518 * @tc.steps: step4. builder_ is null.
519 */
520 lazyForEachNode->builder_ = nullptr;
521 lazyForEachNode->MoveData(INDEX_LESS_THAN_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
522 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
523 }
524
525 /**
526 * @tc.name: ForEachSyntaxFireOnMoveFunctionTest001
527 * @tc.desc: Create LazyForEach, update its Items and invoke FireOnMove function.
528 * @tc.type: FUNC
529 */
530 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxFireOnMoveFunctionTest001, TestSize.Level1)
531 {
532 /**
533 * @tc.steps: step1. Create Text and push it to view stack processor.
534 * @tc.expected: Make Text as LazyForEach parent.
535 */
536 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
537
538 /**
539 * @tc.steps: step2. Invoke lazyForEach Create function.
540 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
541 */
542 LazyForEachModelNG lazyForEach;
543 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
544 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
545 lazyForEach.Create(mockLazyForEachActuator);
546 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
547 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
548
549 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
550
551 /**
552 * @tc.steps: step3. From index is less than start index, and to index is greater than end index.
553 * @tc.expected: Both out of range, ignored.
554 */
555 lazyForEachNode->FireOnMove(INDEX_LESS_THAN_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
556 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
557
558 /**
559 * @tc.steps: step4. builder_ is null.
560 */
561 lazyForEachNode->builder_ = nullptr;
562 lazyForEachNode->FireOnMove(INDEX_LESS_THAN_START_INDEX, INDEX_MIDDLE);
563 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
564 }
565
566 /**
567 * @tc.name: ForEachSyntaxMoveDataFunctionTest008
568 * @tc.desc: Create LazyForEach, update its Items and invoke OnDataMoved function.
569 * @tc.type: FUNC
570 */
571 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxMoveDataFunctionTest008, TestSize.Level1)
572 {
573 /**
574 * @tc.steps: step1. Create Text and push it to view stack processor.
575 * @tc.expected: Make Text as LazyForEach parent.
576 */
577 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
578
579 /**
580 * @tc.steps: step2. Invoke lazyForEach Create function.
581 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
582 */
583 LazyForEachModelNG lazyForEach;
584 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
585 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
586 lazyForEach.Create(mockLazyForEachActuator);
587 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
588 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
589
590 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
591
592 /**
593 * @tc.steps: step3. From index is less than start index, and to index is greater than end index.
594 * @tc.expected: Both out of range, ignored.
595 */
596 lazyForEachNode->OnDataMoved(INDEX_LESS_THAN_START_INDEX, INDEX_GREATER_THAN_END_INDEX);
597 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
598
599 /**
600 * @tc.steps: step4. From index is in middle of range, and to index is greater than end index..
601 */
602 lazyForEachNode->OnDataMoved(INDEX_MIDDLE, INDEX_GREATER_THAN_END_INDEX);
603 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
604
605 /**
606 * @tc.steps: step5. From index is in middle of range, and to index is in middle of range.
607 */
608 lazyForEachNode->OnDataMoved(INDEX_MIDDLE_2, INDEX_MIDDLE);
609 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
610
611 /**
612 * @tc.steps: step6. From index is less than start index, and to index is in middle of range.
613 */
614 lazyForEachNode->OnDataMoved(INDEX_LESS_THAN_START_INDEX, INDEX_MIDDLE);
615 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
616
617 /**
618 * @tc.steps: step7. builder_ is null.
619 */
620 lazyForEachNode->builder_ = nullptr;
621 lazyForEachNode->OnDataMoved(INDEX_LESS_THAN_START_INDEX, INDEX_MIDDLE);
622 EXPECT_EQ(lazyForEachNode->ids_.size(), DEFAULT_SIZE);
623 }
624
625 /**
626 * @tc.name: ForEachSyntaxWrapperBuilderTest009
627 * @tc.desc: Create LazyForEach, update its Items and update LazyLayoutWrapperBuilder layout range.
628 * @tc.type: FUNC
629 */
630 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxWrapperBuilderTest009, TestSize.Level1)
631 {
632 /**
633 * @tc.steps: step1. Create Text and push it to view stack processor.
634 * @tc.expected: Make Text as LazyForEach parent.
635 */
636 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
637
638 /**
639 * @tc.steps: step2. Invoke lazyForEach Create function.
640 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
641 */
642 LazyForEachModelNG lazyForEach;
643 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
644 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
645 lazyForEach.Create(mockLazyForEachActuator);
646 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
647 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
648
649 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
650
651 /**
652 * @tc.steps: step3. Create Parent LayoutWrapper.
653 */
654 RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
655 EXPECT_FALSE(geometryNode == nullptr);
656 auto parentLayoutWrapper =
657 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
658 /**
659 * @tc.steps: step4. Invoke AdjustLayoutWrapperTree, update lazyLayoutWrapperBuilder index range and its
660 * currentChildCount_.
661 * @tc.expected: lazyLayoutWrapperBuilder preNodeIds_ is equal with lazyForEachNode ids_.
662 */
663 lazyForEachNode->AdjustLayoutWrapperTree(parentLayoutWrapper, false, false);
664 auto lazyLayoutWrapperBuilder =
665 AceType::DynamicCast<LazyLayoutWrapperBuilder>(parentLayoutWrapper->layoutWrapperBuilder_);
666 EXPECT_EQ(parentLayoutWrapper->GetTotalChildCount(), LAZY_FOR_EACH_NODE_IDS.size());
667 EXPECT_EQ(lazyLayoutWrapperBuilder->preNodeIds_, DEFAULT_LAZY_FOR_EACH_NODE_IDS);
668 }
669
670 /**
671 * @tc.name: ForEachSyntaxWrapperBuilderTest010
672 * @tc.desc: Create LazyForEach, update its Items and update LazyLayoutWrapperBuilder layout range.
673 * @tc.type: FUNC
674 */
675 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxWrapperBuilderTest010, TestSize.Level1)
676 {
677 /**
678 * @tc.steps: step1. Create Swiper and push it to view stack processor.
679 * @tc.expected: Make Swiper as LazyForEach parent.
680 */
681 auto frameNode = CreateNode(V2::SWIPER_ETS_TAG);
682
683 /**
684 * @tc.steps: step2. Invoke lazyForEach Create function.
685 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
686 */
687 LazyForEachModelNG lazyForEach;
688 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
689 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
690 lazyForEach.Create(mockLazyForEachActuator);
691 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
692 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
693
694 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
695
696 /**
697 * @tc.steps: step3. Create Parent LayoutWrapper.
698 */
699 RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
700 EXPECT_FALSE(geometryNode == nullptr);
701 auto parentLayoutWrapper =
702 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty());
703 /**
704 * @tc.steps: step4. Invoke AdjustLayoutWrapperTree, update lazyLayoutWrapperBuilder index range and its
705 * currentChildCount_.
706 * @tc.expected: lazyLayoutWrapperBuilder preNodeIds_ is equal with lazyForEachNode ids_.
707 */
708 lazyForEachNode->AdjustLayoutWrapperTree(parentLayoutWrapper, false, false);
709
710 auto lazyLayoutWrapperBuilder =
711 AceType::DynamicCast<LazyLayoutWrapperBuilder>(parentLayoutWrapper->layoutWrapperBuilder_);
712 EXPECT_EQ(parentLayoutWrapper->GetTotalChildCount(), static_cast<int32_t>(LAZY_FOR_EACH_NODE_IDS.size()));
713 EXPECT_EQ(lazyLayoutWrapperBuilder->preNodeIds_, DEFAULT_LAZY_FOR_EACH_NODE_IDS);
714 }
715
716 /**
717 * @tc.name: ForEachSyntaxWrapperBuilderOnExpandChildLayoutWrapperTest001
718 * @tc.desc: Create LazyForEach, and invoke OnExpandChildLayoutWrapper.
719 * @tc.type: FUNC
720 */
721 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxWrapperBuilderOnExpandChildLayoutWrapperTest001, TestSize.Level1)
722 {
723 /**
724 * @tc.steps: step1. Create lazyLayoutWrapperBuilder and invoke OnExpandChildLayoutWrapper when the childWrappers_
725 * is empty.
726 * @tc.expected: Create childWrapper and add it to childWrappers_.
727 */
728 auto lazyForEachNode = CreateLazyForEachNode();
729 auto lazyLayoutWrapperBuilder = AceType::MakeRefPtr<LazyLayoutWrapperBuilder>(
730 lazyForEachNode->builder_, AceType::WeakClaim(AceType::RawPtr(lazyForEachNode)));
731 lazyLayoutWrapperBuilder->OnExpandChildLayoutWrapper();
732 lazyLayoutWrapperBuilder->AdjustGridOffset();
733 EXPECT_EQ(lazyLayoutWrapperBuilder->childWrappers_.size(), LAZY_FOR_EACH_NODE_IDS.size());
734
735 /**
736 * @tc.steps: step2. Invoke OnExpandChildLayoutWrapper when the childWrappers_ is not empty.
737 * @tc.expected: Return childWrappers_ directly.
738 */
739 EXPECT_EQ(lazyLayoutWrapperBuilder->OnExpandChildLayoutWrapper().size(), LAZY_FOR_EACH_NODE_IDS.size());
740 EXPECT_FALSE(lazyLayoutWrapperBuilder->childWrappers_.empty());
741
742 /**
743 * @tc.steps: step3. Invoke OnExpandChildLayoutWrapper when the childWrappers_ size is not equal with total.
744 * @tc.expected: Return childWrappers_ directly after clear it.
745 */
746 RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
747 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::TEXT_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
748 lazyLayoutWrapperBuilder->childWrappers_.push_back(
749 AceType::MakeRefPtr<LayoutWrapperNode>(frameNode, geometryNode, frameNode->GetLayoutProperty()));
750 lazyLayoutWrapperBuilder->OnExpandChildLayoutWrapper();
751 EXPECT_TRUE(lazyLayoutWrapperBuilder->childWrappers_.empty());
752 }
753
754 /**
755 * @tc.name: ForEachSyntaxWrapperBuilderOnGetOrCreateWrapperByIndexTest002
756 * @tc.desc: Create LazyForEach, and invoke OnGetOrCreateWrapperByIndex.
757 * @tc.type: FUNC
758 */
759 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxWrapperBuilderOnExpandChildLayoutWrapperTest002, TestSize.Level1)
760 {
761 /**
762 * @tc.steps: step1. Create lazyLayoutWrapperBuilder and invoke OnExpandChildLayoutWrapper when the childWrappers_
763 * is empty.
764 * @tc.expected: Create childWrapper and add it to childWrappers_.
765 */
766 auto lazyForEachNode = CreateLazyForEachNode();
767 auto lazyLayoutWrapperBuilder = AceType::MakeRefPtr<LazyLayoutWrapperBuilder>(
768 lazyForEachNode->builder_, AceType::WeakClaim(AceType::RawPtr(lazyForEachNode)));
769 lazyLayoutWrapperBuilder->OnExpandChildLayoutWrapper();
770
771 /**
772 * @tc.steps: step2. Invoke OnGetOrCreateWrapperByIndex when the index is invalid or not.
773 * @tc.expected: Return nullptr when index is invalid and return the corresponding wrapper when it is valid.
774 */
775 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INVALID_START_ID_LESS_THAN_0), nullptr);
776 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INVALID_START_ID_GREATER_THAN_TOTAL), nullptr);
777 ASSERT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_2), nullptr);
778
779 /**
780 * @tc.steps: step3. Invoke OnGetOrCreateWrapperByIndex when the startIndex_ is null.
781 */
782 lazyLayoutWrapperBuilder->startIndex_ = std::nullopt;
783 ASSERT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_2), nullptr);
784 EXPECT_EQ(lazyLayoutWrapperBuilder->startIndex_.value_or(DEFAULT_INDEX), INDEX_2);
785 EXPECT_EQ(lazyLayoutWrapperBuilder->endIndex_.value_or(DEFAULT_INDEX), INDEX_2);
786
787 /**
788 * @tc.steps: step4. Invoke OnGetOrCreateWrapperByIndex when the index is not in the range of the starIndex and
789 * endIndex.
790 */
791 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_4), nullptr);
792 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_0), nullptr);
793
794 /**
795 * @tc.steps: step5. Invoke OnGetOrCreateWrapperByIndex when the index is not in the range of the starIndex and
796 * endIndex.
797 */
798 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_4), nullptr);
799 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_0), nullptr);
800
801 /**
802 * @tc.steps: step6. Invoke OnGetOrCreateWrapperByIndex when the index is not in the range of the starIndex and
803 * endIndex.
804 */
805 lazyLayoutWrapperBuilder->UpdateIndexRange(INDEX_2, INDEX_8, LAZY_FOR_EACH_NODE_IDS);
806 lazyLayoutWrapperBuilder->startIndex_ = std::nullopt;
807 ASSERT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_4), nullptr);
808 lazyLayoutWrapperBuilder->UpdateIndexRange(INDEX_2, INDEX_8, LAZY_FOR_EACH_NODE_IDS);
809 lazyLayoutWrapperBuilder->startIndex_ = std::nullopt;
810 ASSERT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_1), nullptr);
811 ASSERT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_0), nullptr);
812 }
813
814 /**
815 * @tc.name: ForEachSyntaxWrapperBuilderSwapDirtyAndUpdateBuildCacheTest003
816 * @tc.desc: Create LazyForEach, and invoke SwapDirtyAndUpdateBuildCache.
817 * @tc.type: FUNC
818 */
819 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxWrapperBuilderSwapDirtyAndUpdateBuildCacheTest003, TestSize.Level1)
820 {
821 /**
822 * @tc.steps: step1. Create lazyLayoutWrapperBuilder and invoke SwapDirtyAndUpdateBuildCache when the childWrappers_
823 * is empty or not.
824 */
825 auto lazyForEachNode = CreateLazyForEachNode();
826 auto lazyLayoutWrapperBuilder = AceType::MakeRefPtr<LazyLayoutWrapperBuilder>(
827 lazyForEachNode->builder_, AceType::WeakClaim(AceType::RawPtr(lazyForEachNode)));
828 EXPECT_EQ(lazyLayoutWrapperBuilder->startIndex_.value_or(DEFAULT_INDEX), NEW_START_ID);
829 EXPECT_EQ(lazyLayoutWrapperBuilder->endIndex_.value_or(DEFAULT_INDEX), NEW_START_ID);
830
831 lazyLayoutWrapperBuilder->OnExpandChildLayoutWrapper();
832 lazyLayoutWrapperBuilder->SwapDirtyAndUpdateBuildCache();
833 EXPECT_EQ(lazyLayoutWrapperBuilder->endIndex_.value_or(DEFAULT_INDEX), NEW_END_ID);
834
835 /**
836 * @tc.steps: step1. Create lazyLayoutWrapperBuilder and invoke SwapDirtyAndUpdateBuildCache when cacheCount is not
837 * 0.
838 */
839 auto lazyForEachNode1 = CreateLazyForEachNode();
840 auto lazyLayoutWrapperBuilder1 = AceType::MakeRefPtr<LazyLayoutWrapperBuilder>(
841 lazyForEachNode1->builder_, AceType::WeakClaim(AceType::RawPtr(lazyForEachNode1)));
842 lazyLayoutWrapperBuilder1->OnExpandChildLayoutWrapper();
843 /**
844 * @tc.steps: step2. Invoke SwapDirtyAndUpdateBuildCache when cacheCount is not empty and frontNodeIds is not empty
845 * but backNodeIds is not empty.
846 */
847 lazyLayoutWrapperBuilder1->SetCacheCount(CACHE_COUNT);
848 lazyLayoutWrapperBuilder1->SwapDirtyAndUpdateBuildCache();
849
850 /**
851 * @tc.steps: step3. Set [3, 5] is active.
852 */
853 auto lazyForEachNode2 = CreateLazyForEachNode();
854 auto lazyLayoutWrapperBuilder2 = AceType::MakeRefPtr<LazyLayoutWrapperBuilder>(
855 lazyForEachNode2->builder_, AceType::WeakClaim(AceType::RawPtr(lazyForEachNode2)));
856 lazyLayoutWrapperBuilder2->OnExpandChildLayoutWrapper();
857 auto childWrapper = lazyLayoutWrapperBuilder2->childWrappers_;
858 auto childWrapperIter = childWrapper.begin();
859 int32_t index = 0;
860 while (childWrapperIter != childWrapper.end()) {
861 if (index >= INDEX_3 && index <= INDEX_5) {
862 (*childWrapperIter)->SetActive(true);
863 }
864 index++;
865 childWrapperIter++;
866 }
867 lazyLayoutWrapperBuilder2->SetCacheCount(CACHE_COUNT);
868 lazyLayoutWrapperBuilder2->SwapDirtyAndUpdateBuildCache();
869 }
870
871 /**
872 * @tc.name: ForEachSyntaxWrapperBuilderOnGetOrCreateWrapperByIndexTest004
873 * @tc.desc: Create LazyForEach, and invoke OnGetOrCreateWrapperByIndex.
874 * @tc.type: FUNC
875 */
876 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxWrapperBuilderOnGetOrCreateWrapperByIndexTest004, TestSize.Level1)
877 {
878 /**
879 * @tc.steps: step1. Create lazyLayoutWrapperBuilder and invoke OnExpandChildLayoutWrapper when the childWrappers_
880 * is empty.
881 * @tc.expected: Create childWrapper and add it to childWrappers_.
882 */
883 auto lazyForEachNode = CreateLazyForEachNode();
884 auto lazyLayoutWrapperBuilder = AceType::MakeRefPtr<LazyLayoutWrapperBuilder>(
885 lazyForEachNode->builder_, AceType::WeakClaim(AceType::RawPtr(lazyForEachNode)));
886 lazyLayoutWrapperBuilder->OnExpandChildLayoutWrapper();
887
888 /**
889 * @tc.steps: step2. Invoke OnGetOrCreateWrapperByIndex when the index is invalid or not.
890 * @tc.expected: Return nullptr when index is invalid and return the corresponding wrapper when it is valid.
891 */
892 lazyLayoutWrapperBuilder->lazySwiper_ = false;
893 lazyLayoutWrapperBuilder->startIndex_ = std::nullopt;
894 EXPECT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_2), nullptr);
895
896 /**
897 * @tc.steps: step3. Invoke OnGetOrCreateWrapperByIndex when the startIndex_ is null.
898 */
899 lazyLayoutWrapperBuilder->startIndex_ = INDEX_2;
900 EXPECT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_2), nullptr);
901 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(DEFAULT_INDEX), nullptr);
902
903 /**
904 * @tc.steps: step4. Invoke OnGetOrCreateWrapperByIndex when the index is not in the range of the starIndex and
905 * endIndex.
906 */
907 lazyLayoutWrapperBuilder->lazySwiper_ = true;
908 lazyLayoutWrapperBuilder->startIndex_ = std::nullopt;
909 EXPECT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_2), nullptr);
910 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_0), nullptr);
911
912 /**
913 * @tc.steps: step5. Invoke OnGetOrCreateWrapperByIndex when the index is not in the range of the starIndex and
914 * endIndex.
915 */
916 lazyLayoutWrapperBuilder->lazySwiper_ = true;
917 lazyLayoutWrapperBuilder->startIndex_ = INDEX_2;
918 EXPECT_NE(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_2), nullptr);
919 EXPECT_EQ(lazyLayoutWrapperBuilder->OnGetOrCreateWrapperByIndex(INDEX_0), nullptr);
920 }
921
922 /**
923 * @tc.name: ForEachSyntaxWrapperBuilderGetKeyByIndexFromPreNodesTest005
924 * @tc.desc: Create LazyForEach, and invoke GetKeyByIndexFromPreNodes.
925 * @tc.type: FUNC
926 */
927 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxWrapperBuilderGetKeyByIndexFromPreNodesTest005, TestSize.Level1)
928 {
929 /**
930 * @tc.steps: step1. Create lazyLayoutWrapperBuilder and invoke SwapDirtyAndUpdateBuildCache when the childWrappers_
931 * is empty or not.
932 */
933 auto lazyForEachNode = CreateLazyForEachNode();
934 auto lazyLayoutWrapperBuilder = AceType::MakeRefPtr<LazyLayoutWrapperBuilder>(
935 lazyForEachNode->builder_, AceType::WeakClaim(AceType::RawPtr(lazyForEachNode)));
936 EXPECT_EQ(lazyLayoutWrapperBuilder->startIndex_.value_or(DEFAULT_INDEX), NEW_START_ID);
937 EXPECT_EQ(lazyLayoutWrapperBuilder->endIndex_.value_or(DEFAULT_INDEX), NEW_START_ID);
938
939 lazyLayoutWrapperBuilder->OnExpandChildLayoutWrapper();
940 lazyLayoutWrapperBuilder->SwapDirtyAndUpdateBuildCache();
941 EXPECT_EQ(lazyLayoutWrapperBuilder->endIndex_.value_or(DEFAULT_INDEX), NEW_END_ID);
942
943 /**
944 * @tc.steps: step1. Create lazyLayoutWrapperBuilder and invoke SwapDirtyAndUpdateBuildCache when cacheCount is not
945 * 0.
946 */
947 lazyLayoutWrapperBuilder->preStartIndex_ = START_ID;
948 lazyLayoutWrapperBuilder->preEndIndex_ = INDEX_5;
949 auto key = lazyLayoutWrapperBuilder->GetKeyByIndexFromPreNodes(NEW_END_ID);
950 EXPECT_EQ(key, std::nullopt);
951
952 key = lazyLayoutWrapperBuilder->GetKeyByIndexFromPreNodes(INDEX_8);
953 EXPECT_EQ(key, std::nullopt);
954
955 lazyLayoutWrapperBuilder->preEndIndex_ = INDEX_8;
956 key = lazyLayoutWrapperBuilder->GetKeyByIndexFromPreNodes(START_ID);
957 key = lazyLayoutWrapperBuilder->GetKeyByIndexFromPreNodes(NEW_END_ID);
958 lazyForEachNode->BuildAllChildren();
959 EXPECT_EQ(key, std::nullopt);
960 }
961
962 /**
963 * @tc.name: LazyForEachSyntaxAbnormalCreateTest001
964 * @tc.desc: Create LazyForEach in abnormal condition.
965 * @tc.type: FUNC
966 */
967 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxAbnormalCreateTest001, TestSize.Level1)
968 {
969 /**
970 * @tc.steps: step1. Create Text and push it to view stack processor.
971 * @tc.expected: Make Text as LazyForEach parent.
972 */
973 const RefPtr<LazyForEachBuilder> mockLazyForEachBuilder =
974 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
975 auto frameNode = LazyForEachNode::GetOrCreateLazyForEachNode(LAZY_FOR_EACH_NODE_ID, mockLazyForEachBuilder);
976 auto firstrFrameNode = LazyForEachNode::GetOrCreateLazyForEachNode(LAZY_FOR_EACH_NODE_ID, mockLazyForEachBuilder);
977 const RefPtr<LazyForEachBuilder> anothermockLazyForEachBuilder =
978 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
979 auto secondFrameNode =
980 LazyForEachNode::GetOrCreateLazyForEachNode(LAZY_FOR_EACH_NODE_ID, anothermockLazyForEachBuilder);
981 auto thirdFrameNode =
982 LazyForEachNode::GetOrCreateLazyForEachNode(LAZY_FOR_EACH_NODE_ID, anothermockLazyForEachBuilder);
983
984 /**
985 * @tc.steps: step2. Invoke lazyForEach Create function.
986 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
987 */
988 EXPECT_TRUE(frameNode == firstrFrameNode);
989 EXPECT_TRUE(frameNode == secondFrameNode);
990 }
991
992 /**
993 * @tc.name: ForEachSyntaxBuildAllChildrenTest001
994 * @tc.desc: Create LazyForEach, update its Items and invoke BuildAllChildren function.
995 * @tc.type: FUNC
996 */
997 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxBuildAllChildrenTest001, TestSize.Level1)
998 {
999 /**
1000 * @tc.steps: step1. Create Text and push it to view stack processor.
1001 * @tc.expected: Make Text as LazyForEach parent.
1002 */
1003 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1004
1005 /**
1006 * @tc.steps: step2. Invoke lazyForEach Create function.
1007 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1008 */
1009 LazyForEachModelNG lazyForEach;
1010 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1011 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1012 lazyForEach.Create(mockLazyForEachActuator);
1013 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1014 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1015
1016 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1017
1018 /**
1019 * @tc.steps: step3. Invoke BuildAllChildren.
1020 * @tc.expected: LazyForEachNode ids_ will be cleared.
1021 */
1022 lazyForEachNode->BuildAllChildren();
1023 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1024 }
1025
1026 /**
1027 * @tc.name: ForEachSyntaxPostIdleTaskTest001
1028 * @tc.desc: Create LazyForEach, update its Items and invoke PostIdleTask function.
1029 * @tc.type: FUNC
1030 */
1031 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxPostIdleTaskTest001, TestSize.Level1)
1032 {
1033 /**
1034 * @tc.steps: step1. Create Text and push it to view stack processor.
1035 * @tc.expected: Make Text as LazyForEach parent.
1036 */
1037 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1038
1039 /**
1040 * @tc.steps: step2. Invoke lazyForEach Create function.
1041 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1042 */
1043 LazyForEachModelNG lazyForEach;
1044 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1045 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1046 lazyForEach.Create(mockLazyForEachActuator);
1047 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1048 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1049
1050 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1051
1052 /**
1053 * @tc.steps: step3. Invoke PostIdleTask.
1054 * @tc.expected: LazyForEachNode ids_ will be cleared.
1055 */
1056 lazyForEachNode->needPredict_ = false;
1057 lazyForEachNode->PostIdleTask();
1058 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1059
1060 /**
1061 * @tc.steps: step3. Invoke PostIdleTask.
1062 * @tc.expected: LazyForEachNode ids_ will be cleared.
1063 */
1064 lazyForEachNode->needPredict_ = true;
1065 lazyForEachNode->PostIdleTask();
1066 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1067 }
1068
1069 /**
1070 * @tc.name: ForEachSyntaxGetFrameChildByIndexTest001
1071 * @tc.desc: Create LazyForEach, update its Items and invoke :GetFrameChildByIndex function.
1072 * @tc.type: FUNC
1073 */
1074 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxGetFrameChildByIndexTest001, TestSize.Level1)
1075 {
1076 /**
1077 * @tc.steps: step1. Create Text and push it to view stack processor.
1078 * @tc.expected: Make Text as LazyForEach parent.
1079 */
1080 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1081
1082 /**
1083 * @tc.steps: step2. Invoke lazyForEach Create function.
1084 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1085 */
1086 LazyForEachModelNG lazyForEach;
1087 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1088 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1089 lazyForEach.Create(mockLazyForEachActuator);
1090 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1091 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1092
1093 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1094
1095 /**
1096 * @tc.steps: step3. Invoke GetFrameChildByIndex.
1097 * @tc.expected: LazyForEachNode ids_ will be cleared.
1098 */
1099 lazyForEachNode->needPredict_ = false;
1100 lazyForEachNode->GetFrameChildByIndex(0, true);
1101 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1102
1103 /**
1104 * @tc.steps: step3. Invoke GetFrameChildByIndex.
1105 * @tc.expected: LazyForEachNode ids_ will be cleared.
1106 */
1107 lazyForEachNode->needPredict_ = true;
1108 lazyForEachNode->GetFrameChildByIndex(0, false);
1109 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1110
1111 /**
1112 * @tc.steps: step3. Invoke GetFrameChildByIndex.
1113 * @tc.expected: LazyForEachNode ids_ will be cleared.
1114 */
1115 lazyForEachNode->GetFrameChildByIndex(INDEX_EQUAL_WITH_START_INDEX_DELETED, true);
1116 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1117 }
1118
1119 /**
1120 * @tc.name: ForEachSyntaxGetIndexByUINodeTest001
1121 * @tc.desc: Create LazyForEach, update its Items and invoke :GetIndexByUINode function.
1122 * @tc.type: FUNC
1123 */
1124 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxGetIndexByUINodeTest001, TestSize.Level1)
1125 {
1126 /**
1127 * @tc.steps: step1. Create Text and push it to view stack processor.
1128 * @tc.expected: Make Text as LazyForEach parent.
1129 */
1130 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1131
1132 /**
1133 * @tc.steps: step2. Invoke lazyForEach Create function.
1134 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1135 */
1136 LazyForEachModelNG lazyForEach;
1137 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1138 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1139 lazyForEach.Create(mockLazyForEachActuator);
1140 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1141 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1142
1143 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1144
1145 /**
1146 * @tc.steps: step3. Invoke GetIndexByUINode.
1147 * @tc.expected: LazyForEachNode ids_ will be cleared.
1148 */
1149 lazyForEachNode->needPredict_ = false;
1150 lazyForEachNode->GetIndexByUINode(frameNode);
1151 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1152
1153 /**
1154 * @tc.steps: step3. Invoke GetIndexByUINode.
1155 * @tc.expected: LazyForEachNode ids_ will be cleared.
1156 */
1157 lazyForEachNode->needPredict_ = true;
1158 lazyForEachNode->GetIndexByUINode(frameNode);
1159 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1160
1161 /**
1162 * @tc.steps: step3. Invoke GetIndexByUINode.
1163 * @tc.expected: LazyForEachNode ids_ will be cleared.
1164 */
1165 lazyForEachNode->builder_ = nullptr;
1166 lazyForEachNode->needPredict_ = true;
1167 lazyForEachNode->GetIndexByUINode(frameNode);
1168 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1169 }
1170
1171 /**
1172 * @tc.name: ForEachSyntaxDoRemoveChildInRenderTreeTest001
1173 * @tc.desc: Create LazyForEach, update its Items and invoke :DoRemoveChildInRenderTree function.
1174 * @tc.type: FUNC
1175 */
1176 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxDoRemoveChildInRenderTreeTest001, TestSize.Level1)
1177 {
1178 /**
1179 * @tc.steps: step1. Create Text and push it to view stack processor.
1180 * @tc.expected: Make Text as LazyForEach parent.
1181 */
1182 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1183
1184 /**
1185 * @tc.steps: step2. Invoke lazyForEach Create function.
1186 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1187 */
1188 LazyForEachModelNG lazyForEach;
1189 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1190 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1191 lazyForEach.Create(mockLazyForEachActuator);
1192 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1193 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1194
1195 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1196
1197 /**
1198 * @tc.steps: step3. Invoke DoRemoveChildInRenderTree.
1199 * @tc.expected: LazyForEachNode ids_ will be cleared.
1200 */
1201 lazyForEachNode->needPredict_ = false;
1202 lazyForEachNode->DoRemoveChildInRenderTree(0, true);
1203 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1204
1205 /**
1206 * @tc.steps: step3. Invoke DoRemoveChildInRenderTree.
1207 * @tc.expected: LazyForEachNode ids_ will be cleared.
1208 */
1209 lazyForEachNode->needPredict_ = true;
1210 lazyForEachNode->DoRemoveChildInRenderTree(0, false);
1211 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1212
1213 /**
1214 * @tc.steps: step3. Invoke DoRemoveChildInRenderTree.
1215 * @tc.expected: LazyForEachNode ids_ will be cleared.
1216 */
1217 lazyForEachNode->needPredict_ = true;
1218 lazyForEachNode->builder_ = nullptr; ///
1219 lazyForEachNode->DoRemoveChildInRenderTree(0, false);
1220 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1221 }
1222
1223 /**
1224 * @tc.name: ForEachSyntaxGetChildrenTest001
1225 * @tc.desc: Create LazyForEach, update its Items and invoke :GetChildren function.
1226 * @tc.type: FUNC
1227 */
1228 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxGetChildrenTest001, TestSize.Level1)
1229 {
1230 /**
1231 * @tc.steps: step1. Create Text and push it to view stack processor.
1232 * @tc.expected: Make Text as LazyForEach parent.
1233 */
1234 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1235
1236 /**
1237 * @tc.steps: step2. Invoke lazyForEach Create function.
1238 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1239 */
1240 LazyForEachModelNG lazyForEach;
1241 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1242 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1243 lazyForEach.Create(mockLazyForEachActuator);
1244 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1245 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1246
1247 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1248
1249 /**
1250 * @tc.steps: step3. Invoke GetChildren.
1251 * @tc.expected: LazyForEachNode ids_ will be cleared.
1252 */
1253 lazyForEachNode->needPredict_ = false;
1254 lazyForEachNode->GetChildren();
1255 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1256
1257 /**
1258 * @tc.steps: step3. Invoke GetChildren.
1259 * @tc.expected: LazyForEachNode ids_ will be cleared.
1260 */
1261 lazyForEachNode->needPredict_ = true;
1262 lazyForEachNode->GetChildren();
1263 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1264
1265 /**
1266 * @tc.steps: step3. Invoke GetChildren.
1267 * @tc.expected: LazyForEachNode ids_ will be cleared.
1268 */
1269 lazyForEachNode->GetChildren(true);
1270 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1271 }
1272
1273 /**
1274 * @tc.name: ForEachSyntaxOnDataBulkAddedTest001
1275 * @tc.desc: Create LazyForEach, update its Items and invoke :OnDataBulkAdded function.
1276 * @tc.type: FUNC
1277 */
1278 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxOnDataBulkAddedTest001, TestSize.Level1)
1279 {
1280 /**
1281 * @tc.steps: step1. Create Text and push it to view stack processor.
1282 * @tc.expected: Make Text as LazyForEach parent.
1283 */
1284 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1285
1286 /**
1287 * @tc.steps: step2. Invoke lazyForEach Create function.
1288 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1289 */
1290 LazyForEachModelNG lazyForEach;
1291 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1292 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1293 lazyForEach.Create(mockLazyForEachActuator);
1294 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1295
1296 /**
1297 * @tc.steps: step3. Invoke OnDataBulkAdded.
1298 * @tc.expected: LazyForEachNode ids_ will be cleared.
1299 */
1300 lazyForEachNode->OnDataBulkAdded(INDEX_0, INDEX_0);
1301 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1302
1303 /**
1304 * @tc.steps: step4. Invoke OnDataBulkAdded.
1305 * @tc.expected: LazyForEachNode ids_ will be cleared.
1306 */
1307 lazyForEachNode->builder_=nullptr;
1308 lazyForEachNode->OnDataBulkAdded(INDEX_0, INDEX_0);
1309 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1310 }
1311
1312 /**
1313 * @tc.name: ForEachSyntaxOnDataBulkDeletedTest001
1314 * @tc.desc: Create LazyForEach, update its Items and invoke :OnDataBulkDeleted function.
1315 * @tc.type: FUNC
1316 */
1317 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxOnDataBulkDeletedTest001, TestSize.Level1)
1318 {
1319 /**
1320 * @tc.steps: step1. Create Text and push it to view stack processor.
1321 * @tc.expected: Make Text as LazyForEach parent.
1322 */
1323 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1324
1325 /**
1326 * @tc.steps: step2. Invoke lazyForEach Create function.
1327 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1328 */
1329 LazyForEachModelNG lazyForEach;
1330 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1331 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1332 lazyForEach.Create(mockLazyForEachActuator);
1333 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1334 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1335
1336
1337 lazyForEachBuilder->OnDataBulkDeleted(INDEX_0, INDEX_0);
1338 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1339 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1340 }
1341 lazyForEachBuilder->OnDataChanged(INDEX_1);
1342 lazyForEachNode->OnDataBulkDeleted(INDEX_0, INDEX_1);
1343
1344 /**
1345 * @tc.steps: step3. Invoke OnDataBulkDeleted.
1346 * @tc.expected: LazyForEachNode ids_ will be cleared.
1347 */
1348 lazyForEachNode->OnDataBulkDeleted(INDEX_0, INDEX_0);
1349 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1350
1351 /**
1352 * @tc.steps: step3. Invoke OnDataBulkDeleted.
1353 * @tc.expected: LazyForEachNode ids_ will be cleared.
1354 */
1355 lazyForEachNode->OnDataBulkDeleted(INDEX_5, INDEX_5);
1356 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1357
1358 /**
1359 * @tc.steps: step3. Invoke OnDataBulkDeleted.
1360 * @tc.expected: LazyForEachNode ids_ will be cleared.
1361 */
1362 lazyForEachNode->builder_=nullptr;
1363 lazyForEachNode->OnDataBulkDeleted(INDEX_0, INDEX_0);
1364 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1365 }
1366
1367 /**
1368 * @tc.name: ForEachSyntaxNotifyDataCountChangedTest001
1369 * @tc.desc: Create LazyForEach, update its Items and invoke :NotifyDataCountChanged function.
1370 * @tc.type: FUNC
1371 */
1372 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxNotifyDataCountChangedTest001, TestSize.Level1)
1373 {
1374 /**
1375 * @tc.steps: step1. Create Text and push it to view stack processor.
1376 * @tc.expected: Make Text as LazyForEach parent.
1377 */
1378 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1379
1380 /**
1381 * @tc.steps: step2. Invoke lazyForEach Create function.
1382 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1383 */
1384 LazyForEachModelNG lazyForEach;
1385 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1386 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1387 lazyForEach.Create(mockLazyForEachActuator);
1388 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1389
1390 /**
1391 * @tc.steps: step3. Invoke NotifyDataCountChanged.
1392 * @tc.expected: LazyForEachNode ids_ will be cleared.
1393 */
1394 lazyForEachNode->NotifyChangeWithCount(INDEX_0, 0, UINode::NotificationType::START_CHANGE_POSITION);
1395 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1396 }
1397
1398 /**
1399 * @tc.name: ForEachSyntaxMarkNeedSyncRenderTreeTest001
1400 * @tc.desc: Create LazyForEach, update its Items and invoke :MarkNeedSyncRenderTree function.
1401 * @tc.type: FUNC
1402 */
1403 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxMarkNeedSyncRenderTreeTest001, TestSize.Level1)
1404 {
1405 /**
1406 * @tc.steps: step1. Create Text and push it to view stack processor.
1407 * @tc.expected: Make Text as LazyForEach parent.
1408 */
1409 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1410
1411 /**
1412 * @tc.steps: step2. Invoke lazyForEach Create function.
1413 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1414 */
1415 LazyForEachModelNG lazyForEach;
1416 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1417 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1418 lazyForEach.Create(mockLazyForEachActuator);
1419 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1420
1421 /**
1422 * @tc.steps: step3. Invoke MarkNeedSyncRenderTree.
1423 * @tc.expected: LazyForEachNode ids_ will be cleared.
1424 */
1425 lazyForEachNode->needMarkParent_ = true;
1426 lazyForEachNode->MarkNeedSyncRenderTree(true);
1427
1428 lazyForEachNode->needMarkParent_ = false;
1429 lazyForEachNode->MarkNeedSyncRenderTree(true);
1430 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1431 }
1432
1433 /**
1434 * @tc.name: ForEachSyntaxRecycleItemsTest001
1435 * @tc.desc: Create LazyForEach, update its Items and invoke :RecycleItems function.
1436 * @tc.type: FUNC
1437 */
1438 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxRecycleItemsTest001, TestSize.Level1)
1439 {
1440 /**
1441 * @tc.steps: step1. Create Text and push it to view stack processor.
1442 * @tc.expected: Make Text as LazyForEach parent.
1443 */
1444 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1445
1446 /**
1447 * @tc.steps: step2. Invoke lazyForEach Create function.
1448 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1449 */
1450 LazyForEachModelNG lazyForEach;
1451 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1452 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1453 lazyForEach.Create(mockLazyForEachActuator);
1454 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1455 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1456
1457 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1458
1459 /**
1460 * @tc.steps: step3. Invoke RecycleItems.
1461 * @tc.expected: LazyForEachNode ids_ will be cleared.
1462 */
1463 lazyForEachNode->startIndex_ = 1;
1464 lazyForEachNode->count_ = 1;
1465 lazyForEachNode->RecycleItems(0, 6);
1466 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1467
1468 /**
1469 * @tc.steps: step3. Invoke RecycleItems.
1470 * @tc.expected: LazyForEachNode ids_ will be cleared.
1471 */
1472 lazyForEachNode->startIndex_ = 7;
1473 lazyForEachNode->count_ = 1;
1474 lazyForEachNode->RecycleItems(0, 6);
1475 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1476
1477 /**
1478 * @tc.steps: step3. Invoke RecycleItems.
1479 * @tc.expected: LazyForEachNode ids_ will be cleared.
1480 */
1481 lazyForEachNode->builder_ = nullptr;
1482 lazyForEachNode->RecycleItems(0, 6);
1483 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1484 }
1485
1486 /**
1487 * @tc.name: ForEachSyntaxDoSetActiveChildRangeTest001
1488 * @tc.desc: Create LazyForEach, update its Items and invoke :DoSetActiveChildRange function.
1489 * @tc.type: FUNC
1490 */
1491 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxDoSetActiveChildRangeTest001, TestSize.Level1)
1492 {
1493 /**
1494 * @tc.steps: step1. Create Text and push it to view stack processor.
1495 * @tc.expected: Make Text as LazyForEach parent.
1496 */
1497 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1498
1499 /**
1500 * @tc.steps: step2. Invoke lazyForEach Create function.
1501 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1502 */
1503 LazyForEachModelNG lazyForEach;
1504 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1505 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1506 lazyForEach.Create(mockLazyForEachActuator);
1507 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1508 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1509
1510 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1511
1512 /**
1513 * @tc.steps: step3. Invoke DoSetActiveChildRange.
1514 * @tc.expected: LazyForEachNode ids_ will be cleared.
1515 */
1516 lazyForEachNode->DoSetActiveChildRange(0, 0, 0, 0);
1517 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1518
1519 /**
1520 * @tc.steps: step3. Invoke DoSetActiveChildRange.
1521 * @tc.expected: LazyForEachNode ids_ will be cleared.
1522 */
1523 lazyForEachNode->builder_ = nullptr;
1524 lazyForEachNode->DoSetActiveChildRange(0, 0, 0, 0);
1525 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1526 }
1527
1528 /**
1529 * @tc.name: ForEachSyntaxOnConfigurationUpdateTest001
1530 * @tc.desc: Create LazyForEach, update its Items and invoke :OnConfigurationUpdate function.
1531 * @tc.type: FUNC
1532 */
1533 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxOnConfigurationUpdateTest001, TestSize.Level1)
1534 {
1535 /**
1536 * @tc.steps: step1. Create Text and push it to view stack processor.
1537 * @tc.expected: Make Text as LazyForEach parent.
1538 */
1539 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1540
1541 /**
1542 * @tc.steps: step2. Invoke lazyForEach Create function.
1543 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1544 */
1545 LazyForEachModelNG lazyForEach;
1546 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1547 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1548 lazyForEach.Create(mockLazyForEachActuator);
1549 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
1550 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
1551 ConfigurationChange configurationChange;
1552
1553 auto lazyForEachBuilder = lazyForEachNode->builder_;
1554
1555 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
1556
1557 /**
1558 * @tc.steps: step3. Invoke configurationChange.IsNeedUpdate() = true and builder_ is not null
1559 */
1560 lazyForEachBuilder->expiringItem_["0"] = LazyForEachCacheChild(0, nullptr);
1561 configurationChange.colorModeUpdate = true;
1562 lazyForEachNode->OnConfigurationUpdate(configurationChange);
1563 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1564
1565
1566 /**
1567 * @tc.steps: step4. configurationChange.IsNeedUpdate() = false and builder_ is not null
1568 */
1569 configurationChange.colorModeUpdate = false;
1570 lazyForEachNode->OnConfigurationUpdate(configurationChange);
1571 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1572
1573 lazyForEachNode->builder_=nullptr;
1574
1575 /**
1576 * @tc.steps: step5. configurationChange.IsNeedUpdate() = true and builder_ is null
1577 */
1578 configurationChange.colorModeUpdate = true;
1579 lazyForEachNode->OnConfigurationUpdate(configurationChange);
1580 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1581
1582 /**
1583 * @tc.steps: step6. configurationChange.IsNeedUpdate() = true and builder_ is null
1584 */
1585 configurationChange.colorModeUpdate = false;
1586 lazyForEachNode->OnConfigurationUpdate(configurationChange);
1587 EXPECT_TRUE(lazyForEachNode->ids_.empty());
1588 }
1589
1590 /**
1591 * @tc.name: LazyForEachSyntaxOnDataReloadedTest001
1592 * @tc.desc: Create LazyForEach.
1593 * @tc.type: FUNC
1594 */
1595 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataReloadedTest001, TestSize.Level1)
1596 {
1597 /**
1598 * @tc.steps: step1. Create Text and push it to view stack processor.
1599 * @tc.expected: Make Text as LazyForEach parent.
1600 */
1601 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1602
1603 /**
1604 * @tc.steps: step2. Invoke lazyForEach Create function.
1605 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1606 */
1607 LazyForEachModelNG lazyForEach;
1608 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1609 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1610 lazyForEach.Create(mockLazyForEachActuator);
1611 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1612
1613 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1614 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1615 }
1616 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1617 lazyForEachBuilder->OnDataReloaded();
1618 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 0);
1619 }
1620
1621 /**
1622 * @tc.name: LazyForEachSyntaxOnDataReloadedTest002
1623 * @tc.desc: Create LazyForEach.
1624 * @tc.type: FUNC
1625 */
1626 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataReloadedTest002, TestSize.Level1)
1627 {
1628 /**
1629 * @tc.steps: step1. Create Text and push it to view stack processor.
1630 * @tc.expected: Make Text as LazyForEach parent.
1631 */
1632 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1633
1634 /**
1635 * @tc.steps: step2. Invoke lazyForEach Create function.
1636 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1637 */
1638 LazyForEachModelNG lazyForEach;
1639 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1640 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1641 lazyForEach.Create(mockLazyForEachActuator);
1642 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1643
1644 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1645 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1646 }
1647 std::list<V2::Operation> DataOperations;
1648 V2::Operation operation1 = {.type = "reload"};
1649 DataOperations.push_back(operation1);
1650 lazyForEachBuilder->OnDatasetChange(DataOperations);
1651 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 0);
1652 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1653 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1654 }
1655 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1656 }
1657
1658 /**
1659 * @tc.name: LazyForEachSyntaxOnDataAddedTest001
1660 * @tc.desc: Create LazyForEach.
1661 * @tc.type: FUNC
1662 */
1663 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataAddedTest001, TestSize.Level1)
1664 {
1665 /**
1666 * @tc.steps: step1. Create Text and push it to view stack processor.
1667 * @tc.expected: Make Text as LazyForEach parent.
1668 */
1669 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1670
1671 /**
1672 * @tc.steps: step2. Invoke lazyForEach Create function.
1673 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1674 */
1675 LazyForEachModelNG lazyForEach;
1676 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1677 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1678 lazyForEach.Create(mockLazyForEachActuator);
1679 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1680
1681 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1682 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1683 }
1684 lazyForEachBuilder->useNewInterface_ = true;
1685 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1686 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true, true);
1687 }
1688 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1689 lazyForEachBuilder->OnDataAdded(INDEX_0);
1690 EXPECT_NE(lazyForEachBuilder->GetChildByIndex(7, false, false).second, nullptr);
1691 }
1692
1693 /**
1694 * @tc.name: LazyForEachSyntaxOnDataAddedTest002
1695 * @tc.desc: Create LazyForEach.
1696 * @tc.type: FUNC
1697 */
1698 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataAddedTest002, TestSize.Level1)
1699 {
1700 /**
1701 * @tc.steps: step1. Create Text and push it to view stack processor.
1702 * @tc.expected: Make Text as LazyForEach parent.
1703 */
1704 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1705
1706 /**
1707 * @tc.steps: step2. Invoke lazyForEach Create function.
1708 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1709 */
1710 LazyForEachModelNG lazyForEach;
1711 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1712 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1713 lazyForEach.Create(mockLazyForEachActuator);
1714 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1715
1716 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1717 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1718 }
1719 std::list<V2::Operation> DataOperations;
1720 V2::Operation operation1 = {.type = "add", .index = INDEX_0, .count = 1};
1721 DataOperations.push_back(operation1);
1722 lazyForEachBuilder->OnDatasetChange(DataOperations);
1723 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1724 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1725 }
1726 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 8);
1727 DataOperations.clear();
1728 V2::Operation operation2 = {.type = "add", .index = INDEX_0, .count = 2};
1729 DataOperations.push_back(operation2);
1730 lazyForEachBuilder->OnDatasetChange(DataOperations);
1731 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1732 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1733 }
1734 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 10);
1735 }
1736
1737 /**
1738 * @tc.name: LazyForEachSyntaxOnDataBulkAddedTest001
1739 * @tc.desc: Create LazyForEach.
1740 * @tc.type: FUNC
1741 */
1742 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataBulkAddedTest001, TestSize.Level1)
1743 {
1744 /**
1745 * @tc.steps: step1. Create Text and push it to view stack processor.
1746 * @tc.expected: Make Text as LazyForEach parent.
1747 */
1748 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1749
1750 /**
1751 * @tc.steps: step2. Invoke lazyForEach Create function.
1752 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1753 */
1754 LazyForEachModelNG lazyForEach;
1755 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1756 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1757 lazyForEach.Create(mockLazyForEachActuator);
1758 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1759
1760 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1761 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1762 }
1763 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1764 lazyForEachBuilder->OnDataBulkAdded(INDEX_0, 2);
1765 EXPECT_NE(lazyForEachBuilder->GetChildByIndex(8, false, false).second, nullptr);
1766 }
1767
1768 /**
1769 * @tc.name: LazyForEachSyntaxOnDataDeletedTest001
1770 * @tc.desc: Create LazyForEach.
1771 * @tc.type: FUNC
1772 */
1773 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataDeletedTest001, TestSize.Level1)
1774 {
1775 /**
1776 * @tc.steps: step1. Create Text and push it to view stack processor.
1777 * @tc.expected: Make Text as LazyForEach parent.
1778 */
1779 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1780
1781 /**
1782 * @tc.steps: step2. Invoke lazyForEach Create function.
1783 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1784 */
1785 LazyForEachModelNG lazyForEach;
1786 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1787 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1788 lazyForEach.Create(mockLazyForEachActuator);
1789 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1790
1791 lazyForEachBuilder->OnDataDeleted(INDEX_0);
1792 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1793 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1794 }
1795 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1796 lazyForEachBuilder->OnDataDeleted(INDEX_0);
1797 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 6);
1798 lazyForEachBuilder->OnDataDeleted(BUILDER_INDEX_ONDATADELETED_END);
1799 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 6);
1800 }
1801
1802 /**
1803 * @tc.name: LazyForEachSyntaxOnDataDeletedTest002
1804 * @tc.desc: Create LazyForEach.
1805 * @tc.type: FUNC
1806 */
1807 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataDeletedTest002, TestSize.Level1)
1808 {
1809 /**
1810 * @tc.steps: step1. Create Text and push it to view stack processor.
1811 * @tc.expected: Make Text as LazyForEach parent.
1812 */
1813 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1814
1815 /**
1816 * @tc.steps: step2. Invoke lazyForEach Create function.
1817 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1818 */
1819 LazyForEachModelNG lazyForEach;
1820 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1821 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1822 lazyForEach.Create(mockLazyForEachActuator);
1823 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1824
1825 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1826 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1827 }
1828 // init historicalTotalCount_
1829 lazyForEachBuilder->UpdateHistoricalTotalCount(lazyForEachBuilder->GetTotalCount());
1830 std::list<V2::Operation> DataOperations;
1831 V2::Operation operation1 = {.type = "delete", .index = INDEX_0, .count = 1};
1832 DataOperations.push_back(operation1);
1833 lazyForEachBuilder->OnDatasetChange(DataOperations);
1834 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 6);
1835 DataOperations.clear();
1836 // update historicalTotalCount_
1837 lazyForEachBuilder->UpdateHistoricalTotalCount(lazyForEachBuilder->GetTotalCount());
1838 V2::Operation operation2 = {.type = "delete", .index = INDEX_0, .count = 2};
1839 DataOperations.push_back(operation2);
1840 lazyForEachBuilder->OnDatasetChange(DataOperations);
1841 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 4);
1842 }
1843
1844 /**
1845 * @tc.name: LazyForEachSyntaxOnDataBulkDeletedTest001
1846 * @tc.desc: Create LazyForEach.
1847 * @tc.type: FUNC
1848 */
1849 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataBulkDeletedTest001, TestSize.Level1)
1850 {
1851 /**
1852 * @tc.steps: step1. Create Text and push it to view stack processor.
1853 * @tc.expected: Make Text as LazyForEach parent.
1854 */
1855 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1856
1857 /**
1858 * @tc.steps: step2. Invoke lazyForEach Create function.
1859 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1860 */
1861 LazyForEachModelNG lazyForEach;
1862 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1863 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1864 lazyForEach.Create(mockLazyForEachActuator);
1865 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1866
1867
1868 lazyForEachBuilder->OnDataBulkDeleted(INDEX_0, INDEX_0);
1869 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1870 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1871 }
1872 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1873 lazyForEachBuilder->OnDataBulkDeleted(INDEX_0, 2);
1874 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 5);
1875 }
1876
1877 /**
1878 * @tc.name: LazyForEachSyntaxOnDataChangedTest001
1879 * @tc.desc: Create LazyForEach.
1880 * @tc.type: FUNC
1881 */
1882 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataChangedTest001, TestSize.Level1)
1883 {
1884 /**
1885 * @tc.steps: step1. Create Text and push it to view stack processor.
1886 * @tc.expected: Make Text as LazyForEach parent.
1887 */
1888 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1889
1890 /**
1891 * @tc.steps: step2. Invoke lazyForEach Create function.
1892 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1893 */
1894 LazyForEachModelNG lazyForEach;
1895 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1896 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1897 lazyForEach.Create(mockLazyForEachActuator);
1898 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1899
1900 lazyForEachBuilder->OnDataChanged(INDEX_0);
1901 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1902 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1903 }
1904 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1905 lazyForEachBuilder->OnDataChanged(INDEX_1);
1906 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 6);
1907 lazyForEachBuilder->OnDataChanged(INDEX_7);
1908 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 6);
1909 }
1910
1911 /**
1912 * @tc.name: LazyForEachSyntaxOnDataChangedTest002
1913 * @tc.desc: Create LazyForEach.
1914 * @tc.type: FUNC
1915 */
1916 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataChangedTest002, TestSize.Level1)
1917 {
1918 /**
1919 * @tc.steps: step1. Create Text and push it to view stack processor.
1920 * @tc.expected: Make Text as LazyForEach parent.
1921 */
1922 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1923
1924 /**
1925 * @tc.steps: step2. Invoke lazyForEach Create function.
1926 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1927 */
1928 LazyForEachModelNG lazyForEach;
1929 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1930 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1931 lazyForEach.Create(mockLazyForEachActuator);
1932 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1933 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1934 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1935 }
1936 std::list<V2::Operation> DataOperations;
1937 V2::Operation operation1 = {.type = "change", .index = INDEX_0};
1938 DataOperations.push_back(operation1);
1939 lazyForEachBuilder->OnDatasetChange(DataOperations);
1940 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1941 }
1942
1943 /**
1944 * @tc.name: LazyForEachSyntaxOnDataMovedTest001
1945 * @tc.desc: Create LazyForEach.
1946 * @tc.type: FUNC
1947 */
1948 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataMovedTest001, TestSize.Level1)
1949 {
1950 /**
1951 * @tc.steps: step1. Create Text and push it to view stack processor.
1952 * @tc.expected: Make Text as LazyForEach parent.
1953 */
1954 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1955
1956 /**
1957 * @tc.steps: step2. Invoke lazyForEach Create function.
1958 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1959 */
1960 LazyForEachModelNG lazyForEach;
1961 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
1962 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
1963 lazyForEach.Create(mockLazyForEachActuator);
1964 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
1965
1966 lazyForEachBuilder->OnDataMoved(INDEX_0, INDEX_0);
1967 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
1968 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
1969 }
1970 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1971 lazyForEachBuilder->OnDataMoved(INDEX_0, INDEX_1);
1972 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
1973 lazyForEachBuilder->OnDataMoved(INDEX_0, INDEX_7);
1974 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 6);
1975 lazyForEachBuilder->OnDataMoved(INDEX_7, INDEX_1);
1976 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 5);
1977 lazyForEachBuilder->OnDataMoved(INDEX_7, INDEX_EQUAL_WITH_START_INDEX_DELETED);
1978 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 5);
1979 }
1980
1981 /**
1982 * @tc.name: LazyForEachSyntaxOnDataMovedTest002
1983 * @tc.desc: Create LazyForEach.
1984 * @tc.type: FUNC
1985 */
1986 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataMovedTest002, TestSize.Level1)
1987 {
1988 /**
1989 * @tc.steps: step1. Create Text and push it to view stack processor.
1990 * @tc.expected: Make Text as LazyForEach parent.
1991 */
1992 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
1993
1994 /**
1995 * @tc.steps: step2. Invoke lazyForEach Create function.
1996 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
1997 */
1998 LazyForEachModelNG lazyForEach;
1999 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
2000 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
2001 lazyForEach.Create(mockLazyForEachActuator);
2002 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
2003 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
2004 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
2005 }
2006 std::list<V2::Operation> DataOperations;
2007 V2::Operation operation1 = {.type = "move", .coupleIndex = std::pair(0, 2)};
2008 DataOperations.push_back(operation1);
2009 lazyForEachBuilder->OnDatasetChange(DataOperations);
2010 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
2011 }
2012
2013 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxOnDataExchangeTest001, TestSize.Level1)
2014 {
2015 /**
2016 * @tc.steps: step1. Create Text and push it to view stack processor.
2017 * @tc.expected: Make Text as LazyForEach parent.
2018 */
2019 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
2020
2021 /**
2022 * @tc.steps: step2. Invoke lazyForEach Create function.
2023 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
2024 */
2025 LazyForEachModelNG lazyForEach;
2026 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
2027 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
2028 lazyForEach.Create(mockLazyForEachActuator);
2029 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
2030 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
2031 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
2032 }
2033 std::list<V2::Operation> DataOperations;
2034 V2::Operation operation1 = {.type = "exchange", .coupleIndex = std::pair(1, 3)};
2035 DataOperations.push_back(operation1);
2036 lazyForEachBuilder->OnDatasetChange(DataOperations);
2037 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
2038 }
2039
2040 /**
2041 * @tc.name: LazyForEachSyntaxRecycleChildByIndexTest001
2042 * @tc.desc: Create LazyForEach.
2043 * @tc.type: FUNC
2044 */
2045 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachSyntaxRecycleChildByIndexTest001, TestSize.Level1)
2046 {
2047 /**
2048 * @tc.steps: step1. Create Text and push it to view stack processor.
2049 * @tc.expected: Make Text as LazyForEach parent.
2050 */
2051 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
2052
2053 /**
2054 * @tc.steps: step2. Invoke lazyForEach Create function.
2055 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
2056 */
2057 LazyForEachModelNG lazyForEach;
2058 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
2059 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
2060 lazyForEach.Create(mockLazyForEachActuator);
2061 auto lazyForEachBuilder = AceType::DynamicCast<LazyForEachBuilder>(mockLazyForEachActuator);
2062
2063 lazyForEachBuilder->RecycleChildByIndex(INDEX_0);
2064 for (auto iter : LAZY_FOR_EACH_NODE_IDS_INT) {
2065 lazyForEachBuilder->GetChildByIndex(iter.value_or(0), true);
2066 }
2067 EXPECT_EQ(lazyForEachBuilder->OnGetTotalCount(), 7);
2068 lazyForEachBuilder->RecycleChildByIndex(INDEX_1);
2069 }
2070
2071 /**
2072 * @tc.name: ForEachSyntaxInitDragManagerTest001
2073 * @tc.desc: Create LazyForEach, update its Items and invoke InitDragManager function.
2074 * @tc.type: FUNC
2075 */
2076 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxInitDragManagerTest001, TestSize.Level1)
2077 {
2078 /**
2079 * @tc.steps: step1. Create Text and push it to view stack processor.
2080 * @tc.expected: Make Text as LazyForEach parent.
2081 */
2082 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
2083
2084 /**
2085 * @tc.steps: step2. Invoke lazyForEach Create function.
2086 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
2087 */
2088 LazyForEachModelNG lazyForEach;
2089 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
2090 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
2091 lazyForEach.Create(mockLazyForEachActuator);
2092 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
2093 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
2094
2095 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
2096
2097 /**
2098 * @tc.steps: step3. Invoke NotifyCountChange.
2099 * @tc.expected: LazyForEachNode ids_ will be cleared.
2100 */
2101 auto frameChild = AceType::DynamicCast<FrameNode>(lazyForEachNode->GetFrameChildByIndex(0, true));
2102 lazyForEachNode->InitDragManager(frameChild);
2103 EXPECT_TRUE(lazyForEachNode->ids_.empty());
2104 }
2105
2106 /**
2107 * @tc.name: ForEachSyntaxGetFrameNodeIndexTest001
2108 * @tc.desc: Create LazyForEach, update its Items and invoke GetFrameNodeIndex function.
2109 * @tc.type: FUNC
2110 */
2111 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxGetFrameNodeIndexTest001, TestSize.Level1)
2112 {
2113 /**
2114 * @tc.steps: step1. Create Text and push it to view stack processor.
2115 * @tc.expected: Make Text as LazyForEach parent.
2116 */
2117 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
2118
2119 /**
2120 * @tc.steps: step2. Invoke lazyForEach Create function.
2121 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
2122 */
2123 LazyForEachModelNG lazyForEach;
2124 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
2125 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
2126 lazyForEach.Create(mockLazyForEachActuator);
2127 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
2128 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
2129
2130 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
2131
2132 /**
2133 * @tc.steps: step3. Invoke NotifyCountChange.
2134 * @tc.expected: LazyForEachNode ids_ will be cleared.
2135 */
2136 auto frameChild = AceType::DynamicCast<FrameNode>(lazyForEachNode->GetFrameChildByIndex(0, true));
2137 lazyForEachNode->GetFrameNodeIndex(frameChild, true);
2138 lazyForEachNode->GetFrameNodeIndex(frameChild, false);
2139 EXPECT_TRUE(lazyForEachNode->ids_.empty());
2140 }
2141
2142 /**
2143 * @tc.name: ForEachSyntaxNotifyCountChangeTest001
2144 * @tc.desc: Create LazyForEach, update its Items and invoke NotifyCountChange function.
2145 * @tc.type: FUNC
2146 */
2147 HWTEST_F(LazyForEachSyntaxTestNg, ForEachSyntaxNotifyCountChangeTest001, TestSize.Level1)
2148 {
2149 /**
2150 * @tc.steps: step1. Create Text and push it to view stack processor.
2151 * @tc.expected: Make Text as LazyForEach parent.
2152 */
2153 auto frameNode = CreateNode(V2::TEXT_ETS_TAG);
2154
2155 /**
2156 * @tc.steps: step2. Invoke lazyForEach Create function.
2157 * @tc.expected: Create LazyForEachNode and can be pop from ViewStackProcessor.
2158 */
2159 LazyForEachModelNG lazyForEach;
2160 const RefPtr<LazyForEachActuator> mockLazyForEachActuator =
2161 AceType::MakeRefPtr<OHOS::Ace::Framework::MockLazyForEachBuilder>();
2162 lazyForEach.Create(mockLazyForEachActuator);
2163 auto lazyForEachNode = AceType::DynamicCast<LazyForEachNode>(ViewStackProcessor::GetInstance()->Finish());
2164 EXPECT_TRUE(lazyForEachNode != nullptr && lazyForEachNode->GetTag() == V2::JS_LAZY_FOR_EACH_ETS_TAG);
2165
2166 UpdateItems(lazyForEachNode, mockLazyForEachActuator);
2167
2168 /**
2169 * @tc.steps: step3. Invoke NotifyCountChange.
2170 * @tc.expected: LazyForEachNode ids_ will be cleared.
2171 */
2172 lazyForEachNode->NotifyChangeWithCount(0, 0, UINode::NotificationType::END_CHANGE_POSITION);
2173 EXPECT_TRUE(lazyForEachNode->ids_.empty());
2174 }
2175
2176 /**
2177 * @tc.name: LazyForEachNode OnDelete
2178 * @tc.desc: LazyForEachNode OnDelete
2179 * @tc.type: FUNC
2180 */
2181 HWTEST_F(LazyForEachSyntaxTestNg, LazyForEachNode_OnDelete, TestSize.Level1)
2182 {
2183 auto lazyForEachNode = CreateLazyForEachNode();
2184 lazyForEachNode->OnDelete();
2185 EXPECT_FALSE(lazyForEachNode->isRegisterListener_);
2186 lazyForEachNode->builder_ = nullptr;
2187 lazyForEachNode->OnDelete();
2188 EXPECT_FALSE(lazyForEachNode->isRegisterListener_);
2189 }
2190
2191 } // namespace OHOS::Ace::NG
2192