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 "test/mock/core/pipeline/mock_pipeline_context.h"
27
28 #include "core/components_ng/base/frame_node.h"
29 #include "core/components_ng/base/view_stack_processor.h"
30 #include "core/components_ng/syntax/repeat_node.h"
31 #include "core/components_ng/syntax/repeat_model_ng.h"
32 #include "core/components_ng/syntax/repeat_virtual_scroll_caches.h"
33 #include "core/components_ng/syntax/repeat_virtual_scroll_node.h"
34 #include "core/components_ng/pattern/list/list_item_event_hub.h"
35 #include "core/components_ng/pattern/list/list_item_layout_property.h"
36 #include "core/components_ng/pattern/list/list_item_pattern.h"
37 #include "core/components_ng/pattern/list/list_pattern.h"
38 #include "core/components_ng/pattern/scrollable/scrollable_item.h"
39 #include "core/components_ng/pattern/scrollable/scrollable_item_pool.h"
40 #include "core/components_v2/inspector/inspector_constants.h"
41 #undef private
42 #undef protected
43
44 using namespace testing;
45 using namespace testing::ext;
46
47 namespace OHOS::Ace::NG {
48 namespace {
49 const std::string NODE_TAG = "node";
50 const std::list<std::string> FOR_REPEAT_IDS = { "0", "1", "2", "3", "4", "5" };
51 constexpr int32_t NODE_ID = 1;
52 constexpr int32_t COUNT_1 = 1;
53 constexpr int32_t COUNT_3 = 3;
54 } // namespace
55
56 class RepeatNodeCacheSyntaxTest : public testing::Test {
57 public:
58
SetUp()59 void SetUp() override
60 {
61 MockPipelineContext::SetUp();
62 }
63
TearDown()64 void TearDown() override
65 {
66 MockPipelineContext::TearDown();
67 }
68
69 RefPtr<RepeatVirtualScrollNode> GetOrCreateRepeatNode(bool createItems);
70
CreateNode(const std::string & tag,int32_t elmtId)71 RefPtr<FrameNode> CreateNode(const std::string& tag, int32_t elmtId)
72 {
73 auto pattern = AceType::MakeRefPtr<Pattern>();
74 auto frameNode = AceType::MakeRefPtr<FrameNode>(tag, elmtId, pattern);
75 pattern->AttachToFrameNode(frameNode);
76 ViewStackProcessor::GetInstance()->Push(frameNode);
77 return frameNode;
78 }
79
80 // create ListItemNode with 2 Text Node inside
CreateListItemNode(int32_t elmtId)81 RefPtr<FrameNode> CreateListItemNode(int32_t elmtId)
82 {
83 auto tag = "TEXT_ETS_TAG";
84
85 auto* stack = ViewStackProcessor::GetInstance();
86 auto liFrameNode = FrameNode::GetOrCreateFrameNode(V2::LIST_ITEM_ETS_TAG, elmtId,
87 []() { return AceType::MakeRefPtr<ListItemPattern>(nullptr, V2::ListItemStyle::NONE); });
88
89 auto textNode = CreateNode(V2::TEXT_ETS_TAG, 100*elmtId);
90
91 auto pattern = AceType::MakeRefPtr<Pattern>();
92 const uint32_t uniqNumMultiplier1 = 200;
93 auto textFrameNode = AceType::MakeRefPtr<FrameNode>(tag, uniqNumMultiplier1*elmtId, pattern);
94 pattern->AttachToFrameNode(textFrameNode);
95 liFrameNode->AddChild(textFrameNode);
96
97 pattern = AceType::MakeRefPtr<Pattern>();
98 const uint32_t uniqNumMultiplier2 = 100;
99 textFrameNode = AceType::MakeRefPtr<FrameNode>(tag, uniqNumMultiplier2*elmtId, pattern);
100 pattern->AttachToFrameNode(textFrameNode);
101 liFrameNode->AddChild(textFrameNode);
102 stack->Push(liFrameNode);
103 return liFrameNode;
104 }
105
__anon14a184a20302(uint32_t forIndex) 106 const std::function<void(uint32_t)> onCreateNode = [this](uint32_t forIndex) {
107 CreateListItemNode(forIndex);
108 };
109 };
110 /**
111 * Function needed by RepeatVirtualScrollCaches constructor
112 */
__anon14a184a20402(uint32_t forIndex) 113 auto g_onCreateNode = [](uint32_t forIndex) {
114 };
115
116 /**
117 * Function needed by RepeatVirtualScrollCaches constructor
118 */
__anon14a184a20502(const std::string& fromKey, uint32_t forIndex) 119 auto g_onUpdateNode = [](const std::string& fromKey, uint32_t forIndex) {
120 };
121
122 /**
123 * Function needed by RepeatVirtualScrollCaches constructor
124 */
__anon14a184a20602(uint32_t from, uint32_t to) 125 auto g_onGetKeys4Range = [](uint32_t from, uint32_t to) -> std::list<std::string> {
126 std::list<std::string> keys;
127 for (uint32_t i = from; i <= to; ++i) {
128 keys.push_back("Key" + std::to_string(i));
129 }
130 return keys;
131 };
132
133 /**
134 * Function needed by RepeatVirtualScrollCaches constructor is special test case
135 */
__anon14a184a20702(uint32_t from, uint32_t to) 136 auto g_onGetKeys4RangeMaxTo5 = [](uint32_t from, uint32_t to) -> std::list<std::string> {
137 std::list<std::string> keys;
138 for (uint32_t i = from; i <= to && i<=5; ++i) {
139 keys.push_back("Key" + std::to_string(i));
140 }
141 return keys;
142 };
143
144 /**
145 * Function needed by RepeatVirtualScrollCaches constructor
146 */
__anon14a184a20802(uint32_t from, uint32_t to) 147 auto g_onGetTypes4Range = [](uint32_t from, uint32_t to) -> std::list<std::string> {
148 std::list<std::string> types;
149 for (uint32_t i = from; i <= to; ++i) {
150 types.push_back("Type" + std::to_string(i));
151 }
152
153 return types;
154 };
155 /**
156 * Function needed by RepeatVirtualScrollNode constructor
157 */
__anon14a184a20902(int32_t from, int32_t to) 158 auto g_onSetActiveRange = [](int32_t from, int32_t to) {
159 };
160
161 /**
162 * Map needed by RepeatVirtualScrollCaches constructor
163 */
164 const std::map<std::string, std::pair<bool, uint32_t>> cacheCountL24ttype = {
165 {"element1", { true, 1 }},
166 {"element2", { true, 2 } },
167 {"element3", { true, 3 }},
168 {"element4", { true, 4 }},
169 {"element5", { true, 5 }}
170 };
171
172 /**
173 * Map needed by RepeatVirtualScrollNode constructor
174 */
175 const std::map<std::string, std::pair<bool, uint32_t>> templateCachedCountMap = {
176 // { template, { cachedCountSpecified, cacheCount } }
177 {"elmt1", { true, 1} },
178 {"elmt2", { true, 2} }
179 };
180
GetOrCreateRepeatNode(bool createItems)181 RefPtr<RepeatVirtualScrollNode> RepeatNodeCacheSyntaxTest::GetOrCreateRepeatNode(bool createItems)
182 {
183 RefPtr<RepeatVirtualScrollNode> node;
184 if (createItems) {
185 node = RepeatVirtualScrollNode::GetOrCreateRepeatNode(NODE_ID, COUNT_3, templateCachedCountMap, onCreateNode,
186 g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range, g_onSetActiveRange);
187 } else {
188 node = RepeatVirtualScrollNode::GetOrCreateRepeatNode(NODE_ID, COUNT_1, templateCachedCountMap, g_onCreateNode,
189 g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range, g_onSetActiveRange);
190 }
191 return node;
192 }
193
194 /**
195 * @tc.name: RepeatNodeCacheTest001
196 * @tc.desc: Test GetKey4Index without fetch.
197 * @tc.type: FUNC
198 */
199 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest001, TestSize.Level1)
200 {
201 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
202 g_onCreateNode,
203 g_onUpdateNode,
204 g_onGetKeys4Range,
205 g_onGetTypes4Range);
206
207 /**
208 * @tc.steps: step1. Try to get key for index 2.
209 * @tc.expected: Because second parameter is false
210 * FetchMoreKeysTTypes will not be called and std::nullopt is returned
211 */
212 std::optional<std::string> key = caches.GetKey4Index(2, false);
213 EXPECT_EQ(key, std::nullopt);
214 }
215
216 /**
217 * @tc.name: RepeatNodeCacheTest002
218 * @tc.desc: Test GetKey4Index with fetch.
219 * @tc.type: FUNC
220 */
221 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest002, TestSize.Level1)
222 {
223 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
224 g_onCreateNode,
225 g_onUpdateNode,
226 g_onGetKeys4Range,
227 g_onGetTypes4Range);
228
229 /**
230 * @tc.steps: step1. Try to get key for index 2.
231 * @tc.expected: Because second parameter is true FetchMoreKeysTTypes will be called and Key2 string is returned
232 */
233 std::optional<std::string> key = caches.GetKey4Index(2, true);
234
235 /**
236 * @tc.steps: step2. Try to create node for index 2.
237 * @tc.expected: Because viewStack->Finish() will eventually return nullptr node will also be nullptr
238 */
239 RefPtr<UINode> node = caches.CreateNewNode(2);
240 EXPECT_EQ(node, nullptr);
241 EXPECT_EQ(key, "Key2");
242 }
243
244 /**
245 * @tc.name: RepeatNodeCacheTest003
246 * @tc.desc: Test UpdateFromL2
247 * @tc.type: FUNC
248 */
249 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest003, TestSize.Level1)
250 {
251 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
252 g_onCreateNode,
253 g_onUpdateNode,
254 g_onGetKeys4Range,
255 g_onGetTypes4Range);
256
257 /**
258 * @tc.steps: step1. Try to get UINode from index 2
259 * @tc.expected: Because there are no items in L2 nullptr is expected
260 */
261 RefPtr<UINode> node = caches.UpdateFromL2(2);
262 EXPECT_EQ(node, nullptr);
263 }
264
265 /**
266 * @tc.name: RepeatNodeCacheTest004
267 * @tc.desc: Test GetDistanceFromRange
268 * @tc.type: FUNC
269 */
270 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest004, TestSize.Level1)
271 {
272 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
273 g_onCreateNode,
274 g_onUpdateNode,
275 g_onGetKeys4Range,
276 g_onGetTypes4Range);
277
278 /**
279 * @tc.steps: step1. Get distance from active range of index 2
280 * @tc.expected: Because active range index is 0 it expected that number 2 is returned.
281 */
282 int32_t dist = caches.GetDistanceFromRange(2);
283 EXPECT_EQ(dist, 2);
284 }
285
286 /**
287 * @tc.name: RepeatNodeCacheTest005
288 * @tc.desc: Test creation of GetOrCreateRepeatNode
289 * @tc.type: FUNC
290 */
291 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest005, TestSize.Level1)
292 {
293 auto* stack = ViewStackProcessor::GetInstance();
294 auto nodeId = stack->ClaimNodeId();
295 /**
296 * @tc.steps: step1. Create node object
297 * @tc.expected: Object is not nullptr.
298 */
299 auto repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
300 nodeId,
301 1,
302 templateCachedCountMap,
303 g_onCreateNode,
304 g_onUpdateNode,
305 g_onGetKeys4Range,
306 g_onGetTypes4Range,
307 g_onSetActiveRange);
308
309 EXPECT_NE(repeatNode, nullptr);
310 }
311
312 /**
313 * @tc.name: RepeatNodeCacheTest006
314 * @tc.desc: Test FrameCount
315 * @tc.type: FUNC
316 */
317 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest006, TestSize.Level1)
318 {
319 auto repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
320 1,
321 1,
322 templateCachedCountMap,
323 g_onCreateNode,
324 g_onUpdateNode,
325 g_onGetKeys4Range,
326 g_onGetTypes4Range,
327 g_onSetActiveRange);
328
329 /**
330 * @tc.steps: step2. Update total count to 2
331 * @tc.expected: Object internal frame count is increased to 2
332 */
333 repeatNode->UpdateTotalCount(2);
334
335 /**
336 * @tc.steps: step3. Get frame count
337 * @tc.expected: Object internal frame count should be 2
338 */
339 uint32_t frameCount = repeatNode->FrameCount();
340 EXPECT_EQ(frameCount, 2);
341 }
342
343 /**
344 * @tc.name: RepeatNodeCacheTest007
345 * @tc.desc: Test GetChildren
346 * @tc.type: FUNC
347 */
348 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest007, TestSize.Level1)
349 {
350 auto repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
351 1,
352 1,
353 templateCachedCountMap,
354 g_onCreateNode,
355 g_onUpdateNode,
356 g_onGetKeys4Range,
357 g_onGetTypes4Range,
358 g_onSetActiveRange);
359
360 /**
361 * @tc.steps: step2. Get children count
362 * @tc.expected: Returns number of children. Should be 0
363 */
364 std::list<RefPtr<UINode>> nodes = repeatNode->GetChildren();
365 EXPECT_EQ(nodes.size(), 0);
366 }
367
368 /**
369 * @tc.name: RepeatNodeCacheTest008
370 * @tc.desc: Test Multiple functions when onCreate lambda really creates node.
371 * @tc.type: FUNC
372 */
373 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest008, TestSize.Level1)
374 {
375 RepeatVirtualScrollCaches caches(cacheCountL24ttype, onCreateNode,
376 g_onUpdateNode, g_onGetKeys4Range,
377 g_onGetTypes4Range);
378
379 std::optional<std::string> key1 = caches.GetKey4Index(1, true);
380 EXPECT_EQ(key1, "Key1");
381 std::optional<std::string> key2 = caches.GetKey4Index(2, true);
382 EXPECT_EQ(key2, "Key2");
383 std::optional<std::string> key3 = caches.GetKey4Index(3, true);
384 EXPECT_EQ(key3, "Key3");
385
386 RefPtr<UINode> node1 = caches.CreateNewNode(1);
387 EXPECT_NE(node1, nullptr);
388 RefPtr<UINode> node2 = caches.CreateNewNode(2);
389 EXPECT_NE(node2, nullptr);
390 RefPtr<UINode> node3 = caches.CreateNewNode(3);
391 EXPECT_NE(node3, nullptr);
392
393 auto repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
394 1, 3, templateCachedCountMap, onCreateNode,
395 g_onUpdateNode, g_onGetKeys4Range,
396 g_onGetTypes4Range, g_onSetActiveRange);
397
398 repeatNode->caches_ = caches;
399 /**
400 * @tc.steps: step1. Add keys to cache
401 * @tc.expected: Items in cache size should be 3
402 */
403 repeatNode->caches_.FetchMoreKeysTTypes(1, 3);
404 repeatNode->caches_.AddKeyToL1("Key1");
405 repeatNode->caches_.AddKeyToL1("Key2");
406 repeatNode->caches_.AddKeyToL1("Key3");
407 EXPECT_EQ(repeatNode->caches_.activeNodeKeysInL1_.size(), 3);
408
409 /**
410 * @tc.steps: step2. Dump information
411 * @tc.expected: Dumping output string should have ListItem(3) substring
412 */
413 std::string l1Dump = repeatNode->caches_.DumpL1();
414 const std::string expectedSubStringL1And4TType = "ListItem";
415 EXPECT_NE(l1Dump.find(expectedSubStringL1And4TType), std::string::npos);
416 std::string dmp4KeyType = repeatNode->caches_.DumpUINode4Key4TType();
417 EXPECT_NE(dmp4KeyType.find(expectedSubStringL1And4TType), std::string::npos);
418
419 /**
420 * @tc.steps: step3. Find unused keys
421 * @tc.expected: Number of unused keys should be 0
422 */
423 std::set<std::pair<bool, std::string>> keys;
424 caches.FindUnusedKeys(keys);
425 EXPECT_EQ(keys.size(), 0);
426
427 caches.UINodeHasBeenUpdated("Type1", "Key1", "Key2");
428 repeatNode->DoSetActiveChildRange(1, 3, 1, 2);
429 repeatNode->caches_.index4Key_.clear();
430 repeatNode->DropFromL1("Key1");
431 repeatNode->caches_.GetL1KeyToUpdate("Key1");
432 repeatNode->caches_.InvalidateKeyAndTTypeCaches();
433 repeatNode->UpdateRenderState(true);
434 repeatNode->UpdateRenderState(false);
435 repeatNode->RecycleItems(0, 100);
436
437 /**
438 * @tc.steps: step4. Get GetFrameNode
439 * @tc.expected: Returns valid frame node
440 */
441 auto frameNode = repeatNode->GetFrameNode(1);
442 EXPECT_NE(frameNode, nullptr);
443 }
444
445 /**
446 * @tc.name: RepeatNodeCacheTest009
447 * @tc.desc: Test FrameCount
448 * @tc.type: FUNC
449 */
450 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest009, TestSize.Level1)
451 {
452 const uint32_t totalCount = 10;
453 const uint32_t updatedCount = 5;
454 /**
455 * @tc.steps: step1. Create node object with totalCount = 10
456 * @tc.expected: Object is not nullptr.
457 */
458 auto repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
459 1,
460 totalCount,
461 templateCachedCountMap,
462 g_onCreateNode,
463 g_onUpdateNode,
464 g_onGetKeys4Range,
465 g_onGetTypes4Range,
466 g_onSetActiveRange);
467
468 /**
469 * @tc.steps: step2. Ask frame count
470 * @tc.expected: Should be totalCount
471 */
472 uint32_t frameCount = repeatNode->FrameCount();
473 EXPECT_EQ(frameCount, totalCount);
474
475 /**
476 * @tc.steps: step3. Update total count to the new value
477 * @tc.expected: Should be updatedCount
478 */
479 repeatNode->UpdateTotalCount(updatedCount);
480 frameCount = repeatNode->FrameCount();
481 EXPECT_EQ(frameCount, updatedCount);
482 }
483
484 /**
485 * @tc.name: RepeatNodeCacheTest010
486 * @tc.desc: Test GetL1KeyToUpdate
487 * @tc.type: FUNC
488 */
489 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest010, TestSize.Level1)
490 {
491 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
492 g_onCreateNode,
493 g_onUpdateNode,
494 g_onGetKeys4Range,
495 g_onGetTypes4Range);
496
497 caches.FetchMoreKeysTTypes(1, 3);
498 /**
499 * @tc.steps: step1. Try to get L1 key to update
500 * @tc.expected: Because there are no L1 key for Type1
501 * std::nullopt is returned
502 */
503 std::optional<std::string> key = caches.GetL1KeyToUpdate("Type1");
504 EXPECT_EQ(key, std::nullopt);
505 }
506
507 /**
508 * @tc.name: RepeatNodeCacheTest011
509 * @tc.desc: Test UiNodeHasBeenUpdated
510 * @tc.type: FUNC
511 */
512 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest011, TestSize.Level1)
513 {
514 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
515 g_onCreateNode,
516 g_onUpdateNode,
517 g_onGetKeys4Range,
518 g_onGetTypes4Range);
519
520 /**
521 * @tc.steps: step1. Try to get UI node by calling UINodeHasBeenUpdated
522 * @tc.expected: Because there are no nodes nullptr is returned
523 */
524 RefPtr<UINode> node = caches.UINodeHasBeenUpdated("Type1", "Key0", "Key1");
525 EXPECT_EQ(node, nullptr);
526 }
527
528 /**
529 * @tc.name: RepeatNodeCacheTest012
530 * @tc.desc: Test FindUnusedKeys
531 * @tc.type: FUNC
532 */
533 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest012, TestSize.Level1)
534 {
535 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
536 g_onCreateNode,
537 g_onUpdateNode,
538 g_onGetKeys4Range,
539 g_onGetTypes4Range);
540
541 /**
542 * @tc.steps: step1. Try to get set of unused keys
543 * @tc.expected: Because there are no keys 0 is returned
544 */
545 std::set<std::pair<bool, std::string>> keys;
546 caches.FindUnusedKeys(keys);
547 EXPECT_EQ(keys.size(), 0);
548 }
549
550 /**
551 * @tc.name: RepeatNodeCacheTest013
552 * @tc.desc: Test DumpL1
553 * @tc.type: FUNC
554 */
555 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest013, TestSize.Level1)
556 {
557 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
558 g_onCreateNode,
559 g_onUpdateNode,
560 g_onGetKeys4Range,
561 g_onGetTypes4Range);
562
563 /**
564 * @tc.steps: step1. Try to call DumpL1
565 * @tc.expected: Because there are no items. Its expected that there is
566 * total number=0 substring in return value
567 */
568 std::string l1Dump = caches.DumpL1();
569 const std::string expectedSubString = "total number=0";
570 EXPECT_NE(l1Dump.find(expectedSubString), std::string::npos);
571 }
572
573 /**
574 * @tc.name: RepeatNodeCacheTest014
575 * @tc.desc: Test DumpL2
576 * @tc.type: FUNC
577 */
578 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest014, TestSize.Level1)
579 {
580 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
581 g_onCreateNode,
582 g_onUpdateNode,
583 g_onGetKeys4Range,
584 g_onGetTypes4Range);
585
586 /**
587 * @tc.steps: step1. Try to call DumpL2
588 * @tc.expected: Because there are no items. Its expected that there is size=0 substring in return value
589 */
590 std::string l2Dump = caches.DumpL2();
591 const std::string expectedSubString = "size=0";
592 EXPECT_NE(l2Dump.find(expectedSubString), std::string::npos);
593 }
594
595 /**
596 * @tc.name: RepeatNodeCacheTest015
597 * @tc.desc: Test DumpKey4Index
598 * @tc.type: FUNC
599 */
600 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest015, TestSize.Level1)
601 {
602 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
603 g_onCreateNode,
604 g_onUpdateNode,
605 g_onGetKeys4Range,
606 g_onGetTypes4Range);
607
608 /**
609 * @tc.steps: step1. Try to call DumpKey4Index
610 * @tc.expected: Because there are no items. Its expected that there is size=0 substring in return value
611 */
612 std::string key4IndexDump = caches.DumpKey4Index();
613 const std::string expectedSubString = "size=0";
614 EXPECT_NE(key4IndexDump.find(expectedSubString), std::string::npos);
615 }
616
617 /**
618 * @tc.name: RepeatNodeCacheTest016
619 * @tc.desc: Test DumpTType4Index
620 * @tc.type: FUNC
621 */
622 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest016, TestSize.Level1)
623 {
624 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
625 g_onCreateNode,
626 g_onUpdateNode,
627 g_onGetKeys4Range,
628 g_onGetTypes4Range);
629
630 /**
631 * @tc.steps: step1. Try to call DumpTType4Index
632 * @tc.expected: Because there are no items. Its expected that there is size=0 substring in return value
633 */
634 std::string tTypeIndex = caches.DumpTType4Index();
635 const std::string expectedSubString = "size=0";
636 EXPECT_NE(tTypeIndex.find(expectedSubString), std::string::npos);
637 }
638
639 /**
640 * @tc.name: RepeatNodeCacheTest017
641 * @tc.desc: Test DumpUINode4Key
642 * @tc.type: FUNC
643 */
644 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest017, TestSize.Level1)
645 {
646 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
647 g_onCreateNode,
648 g_onUpdateNode,
649 g_onGetKeys4Range,
650 g_onGetTypes4Range);
651
652 /**
653 * @tc.steps: step1. Try to call DumpUINode4Key
654 * @tc.expected: Because there are no items. Its expected that there is size=0 substring in return value
655 */
656 std::string uiNode4Key = caches.DumpUINode4Key();
657 const std::string expectedSubString = "size=0";
658 EXPECT_NE(uiNode4Key.find(expectedSubString), std::string::npos);
659 }
660
661 /**
662 * @tc.name: RepeatNodeCacheTest018
663 * @tc.desc: Test DumpUINode4Key4TType
664 * @tc.type: FUNC
665 */
666 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest018, TestSize.Level1)
667 {
668 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
669 g_onCreateNode,
670 g_onUpdateNode,
671 g_onGetKeys4Range,
672 g_onGetTypes4Range);
673
674
675 /**
676 * @tc.steps: step1. Try to call DumpUINode4Key4TType
677 * @tc.expected: Because there are no items. Its expected that there is size=0 substring in return value
678 */
679 std::string uiNode4Key4TType = caches.DumpUINode4Key4TType();
680 const std::string expectedSubString = "size=0";
681 EXPECT_NE(uiNode4Key4TType.find(expectedSubString), std::string::npos);
682 }
683
684 /**
685 * @tc.name: RepeatNodeCacheTest019
686 * @tc.desc: Test DumpUINodeWithKey
687 * @tc.type: FUNC
688 */
689 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest019, TestSize.Level1)
690 {
691 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
692 g_onCreateNode,
693 g_onUpdateNode,
694 g_onGetKeys4Range,
695 g_onGetTypes4Range);
696
697 /**
698 * @tc.steps: step1. Try to call DumpUINodeWithKey
699 * @tc.expected: Because there are no items. Its expected that there is "no UINode" substring in return value
700 */
701 std::string uiNodeWithKey = caches.DumpUINodeWithKey("Key1");
702 const std::string expectedSubString = "no UINode";
703 EXPECT_NE(uiNodeWithKey.find(expectedSubString), std::string::npos);
704 }
705
706 /**
707 * @tc.name: RepeatNodeCacheTest020
708 * @tc.desc: Test DumpUINode
709 * @tc.type: FUNC
710 */
711 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest020, TestSize.Level1)
712 {
713 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
714 g_onCreateNode,
715 g_onUpdateNode,
716 g_onGetKeys4Range,
717 g_onGetTypes4Range);
718
719 /**
720 * @tc.steps: step1. Try to call DumpUINode
721 * @tc.expected: Because input argument is nullptr its expected that there is nullptr in return value
722 */
723 std::string uiNode = caches.DumpUINode(nullptr);
724 const std::string expectedSubString = "nullptr";
725 EXPECT_NE(uiNode.find(expectedSubString), std::string::npos);
726 }
727
728 /**
729 * @tc.name: RepeatNodeCacheTest021
730 * @tc.desc: Test OnConfigurationUpdate function
731 * @tc.type: FUNC
732 */
733 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest021, TestSize.Level1)
734 {
735 auto repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
736 1,
737 1,
738 templateCachedCountMap,
739 g_onCreateNode,
740 g_onUpdateNode,
741 g_onGetKeys4Range,
742 g_onGetTypes4Range,
743 g_onSetActiveRange);
744
745 ConfigurationChange cfgChange;
746 cfgChange.colorModeUpdate = true;
747 /**
748 * @tc.steps: step1. Try to call GetOrCreateRepeatNode.
749 * @tc.expected: Instead of creating current node is returned,
750 */
751 auto repeatNode2 = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
752 1,
753 1,
754 templateCachedCountMap,
755 g_onCreateNode,
756 g_onUpdateNode,
757 g_onGetKeys4Range,
758 g_onGetTypes4Range,
759 g_onSetActiveRange);
760
761 EXPECT_EQ(repeatNode, repeatNode2);
762 /**
763 * @tc.steps: step3. Try to call OnConfigurationChange.
764 * @tc.expected: No code crash happens
765 */
766 repeatNode->OnConfigurationUpdate(cfgChange);
767 }
768
769 /**
770 * @tc.name: RepeatNodeCacheTest022
771 * @tc.desc: Test FetchMoreKeysTTypes with invalid values.
772 * @tc.type: FUNC
773 */
774 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest022, TestSize.Level1)
775 {
776 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
777 g_onCreateNode,
778 g_onUpdateNode,
779 g_onGetKeys4Range,
780 g_onGetTypes4Range);
781
782 /**
783 * @tc.steps: step1. Try to call FetchMoreKeysTTypes so that "from" is bigger than "to"
784 * @tc.expected: False is expected to be returned
785 */
786 bool status = caches.FetchMoreKeysTTypes(2, 1);
787 EXPECT_EQ(status, false);
788 }
789
790 /**
791 * @tc.name: RepeatNodeCacheTest023
792 * @tc.desc: Test FetchMoreKeysTTypes with special MaxTo5 lambda.
793 * @tc.type: FUNC
794 */
795 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest023, TestSize.Level1)
796 {
797 /**
798 * @tc.steps: step1. Create caches object with Keys function that limits keys to 5 (for unit testing)
799 * @tc.expected: Object is created correctly
800 */
801 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
802 g_onCreateNode,
803 g_onUpdateNode,
804 g_onGetKeys4RangeMaxTo5,
805 g_onGetTypes4Range);
806
807 /**
808 * @tc.steps: step2. Try to call FetchMoreKeysTTypes so that internally "keys"
809 * *are smaller than "types" due to g_onGetKeys4RangeMaxTo5
810 * @tc.expected: False is expected to be returned
811 */
812 bool status = caches.FetchMoreKeysTTypes(1, 10);
813 EXPECT_EQ(status, false);
814 }
815
816 /**
817 * @tc.name: RepeatNodeCacheTest024
818 * @tc.desc: Test GetKey4Index with fetch and creating new node.
819 * @tc.type: FUNC
820 */
821 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest024, TestSize.Level1)
822 {
823 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
824 onCreateNode,
825 g_onUpdateNode,
826 g_onGetKeys4Range,
827 g_onGetTypes4Range);
828
829 /**
830 * @tc.steps: step1. Try to get key for index 2.
831 * @tc.expected: Because second parameter is true FetchMoreKeysTTypes will be internally
832 * called and Key2 string is returned
833 */
834 std::optional<std::string> key = caches.GetKey4Index(2, true);
835 EXPECT_EQ(key, "Key2");
836 /**
837 * @tc.steps: step2. Try to create node for index 2.
838 * @tc.expected: Because onCreateNode lambda used that really creates node 1 is expected.
839 */
840 RefPtr<UINode> node = caches.CreateNewNode(2);
841 EXPECT_NE(node, nullptr);
842
843 RefPtr<UINode> uinode = caches.DropFromL1("Key2");
844 EXPECT_NE(uinode, nullptr);
845 }
846
847 /**
848 * @tc.name: RepeatNodeCacheTest025
849 * @tc.desc: Test GetDistanceFromRange
850 * @tc.type: FUNC
851 */
852 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest025, TestSize.Level1)
853 {
854 RepeatVirtualScrollCaches caches(
855 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
856
857 int32_t dist = caches.GetDistanceFromRange(UINT32_MAX);
858 EXPECT_EQ(dist, UINT32_MAX);
859
860 caches.lastActiveRanges_[0].first = 10;
861 caches.lastActiveRanges_[0].second = 30;
862 caches.lastActiveRanges_[1].first = 20;
863 dist = caches.GetDistanceFromRange(9);
864 EXPECT_EQ(dist, 0);
865
866 dist = caches.GetDistanceFromRange(11);
867 EXPECT_EQ(dist, 0);
868
869 caches.lastActiveRanges_[0].first = 10;
870 caches.lastActiveRanges_[0].second = 30;
871 caches.lastActiveRanges_[1].second = 20;
872 dist = caches.GetDistanceFromRange(29);
873 EXPECT_EQ(dist, 0);
874
875 dist = caches.GetDistanceFromRange(31);
876 EXPECT_EQ(dist, 0);
877 }
878
879 /**
880 * @tc.name: RepeatNodeCacheTest026
881 * @tc.desc: Test GetCachedNode4Key4Ttype
882 * @tc.type: FUNC
883 */
884 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest026, TestSize.Level1)
885 {
886 /**
887 * @tc.steps: step1. Create cached object with Keys function that limits keys to 5 (for unit testing)
888 * @tc.expected: Object is created correctly
889 */
890 RepeatVirtualScrollCaches caches(
891 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4RangeMaxTo5, g_onGetTypes4Range);
892
893 auto ret = caches.GetCachedNode4Key4Ttype(std::nullopt, std::nullopt);
894 EXPECT_EQ(ret, nullptr);
895 ret = caches.GetCachedNode4Key4Ttype(std::string("a"), std::nullopt);
896 EXPECT_EQ(ret, nullptr);
897 ret = caches.GetCachedNode4Key4Ttype(std::nullopt, std::string("a"));
898 EXPECT_EQ(ret, nullptr);
899 ret = caches.GetCachedNode4Key4Ttype(std::string("a"), std::string("a"));
900 EXPECT_EQ(ret, nullptr);
901
902 // std::unordered_map<std::string, std::unordered_map<std::string, RefPtr<UINode>>> node4key4ttype_;
903 caches.node4key4ttype_.insert({ std::string("a"), { { std::string("a"), nullptr } } });
904 ret = caches.GetCachedNode4Key4Ttype(std::string("a"), std::string("a"));
905 EXPECT_EQ(ret, nullptr);
906 ret = caches.GetCachedNode4Key4Ttype(std::string("b"), std::string("a"));
907 EXPECT_EQ(ret, nullptr);
908 }
909
910 /**
911 * @tc.name: RepeatNodeCacheTest027
912 * @tc.desc: Test GetCachedNode4Key
913 * @tc.type: FUNC
914 */
915 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest027, TestSize.Level1)
916 {
917 /**
918 * @tc.steps: step1. Create cached object with Keys function that limits keys to 5 (for unit testing)
919 * @tc.expected: Object is created correctly
920 */
921 RepeatVirtualScrollCaches caches(
922 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4RangeMaxTo5, g_onGetTypes4Range);
923
924 auto ret = caches.GetCachedNode4Key(std::nullopt);
925 EXPECT_FALSE(ret.has_value());
926 }
927
928 /**
929 * @tc.name: RepeatNodeCacheTest028
930 * @tc.desc: Test GetTType4Index
931 * @tc.type: FUNC
932 */
933 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest028, TestSize.Level1)
934 {
935 /**
936 * @tc.steps: step1. Create cached object with Keys function that limits keys to 5 (for unit testing)
937 * @tc.expected: Object is created correctly
938 */
939 RepeatVirtualScrollCaches caches(
940 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4RangeMaxTo5, g_onGetTypes4Range);
941 std::string val("0");
942 caches.ttype4index_.insert({ 0, val });
943 auto ret = caches.GetTType4Index(0);
944 EXPECT_TRUE(ret.has_value());
945 }
946
947 /**
948 * @tc.name: RepeatNodeCacheTest029
949 * @tc.desc: Test GetIndex4Key
950 * @tc.type: FUNC
951 */
952 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest029, TestSize.Level1)
953 {
954 /**
955 * @tc.steps: step1. Create cached object with Keys function that limits keys to 5 (for unit testing)
956 * @tc.expected: Object is created correctly
957 */
958 RepeatVirtualScrollCaches caches(
959 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4RangeMaxTo5, g_onGetTypes4Range);
960
961 std::string key("key");
962 caches.index4Key_.insert({ key, 0 });
963 auto ret = caches.GetIndex4Key(key);
964 EXPECT_EQ(ret, 0);
965 }
966
967 /**
968 * @tc.name: RepeatNodeCacheTest030
969 * @tc.desc: Test FindUnusedKeys
970 * @tc.type: FUNC
971 */
972 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest030, TestSize.Level1)
973 {
974 /**
975 * @tc.steps: step1. Create cached object with Keys function that limits keys to 5 (for unit testing)
976 * @tc.expected: Object is created correctly
977 */
978 RepeatVirtualScrollCaches caches(
979 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4RangeMaxTo5, g_onGetTypes4Range);
980
981 std::string key("key");
982 caches.node4key_.insert({ key, CacheItem() });
983 std::set<std::pair<bool, std::string>> result;
984 caches.FindUnusedKeys(result);
985 EXPECT_EQ(result.size(), 1);
986
987 result.clear();
988 caches.index4Key_.insert({ key, 0 });
989 caches.FindUnusedKeys(result);
990 EXPECT_EQ(result.size(), 0);
991 }
992
993 /**
994 * @tc.name: RepeatNodeCacheTest031
995 * @tc.desc: Test UINodeHasBeenUpdated
996 * @tc.type: FUNC
997 */
998 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest031, TestSize.Level1)
999 {
1000 /**
1001 * @tc.steps: step1. Create cached object with Keys function that limits keys to 5 (for unit testing)
1002 * @tc.expected: Object is created correctly
1003 */
1004 RepeatVirtualScrollCaches caches(
1005 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4RangeMaxTo5, g_onGetTypes4Range);
1006
1007 std::string key("key");
1008 std::string key2("key2");
1009 caches.node4key4ttype_.insert({ key, { { key2, nullptr } } });
1010 auto ret = caches.UINodeHasBeenUpdated(key, std::string("a"), std::string("a"));
1011 EXPECT_EQ(ret, nullptr);
1012 ret = caches.UINodeHasBeenUpdated(key, key2, std::string("a"));
1013 EXPECT_EQ(ret, nullptr);
1014
1015 caches.node4key_.insert({ key2, CacheItem() });
1016 ret = caches.UINodeHasBeenUpdated(key, key2, std::string("a"));
1017 EXPECT_EQ(ret, nullptr);
1018 }
1019
1020 /**
1021 * @tc.name: RepeatNodeCacheTest032
1022 * @tc.desc: Test GetL1KeyToUpdate
1023 * @tc.type: FUNC
1024 */
1025 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest032, TestSize.Level1)
1026 {
1027 RepeatVirtualScrollCaches caches(
1028 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1029
1030 std::string key("key");
1031 std::string key1("key1");
1032 caches.activeNodeKeysInL1_.insert(key);
1033 std::optional<std::string> ret = caches.GetL1KeyToUpdate(key1);
1034 EXPECT_EQ(ret, std::nullopt);
1035
1036 caches.index4Key_.insert({ key, 0 });
1037 ret = caches.GetL1KeyToUpdate(key1);
1038 EXPECT_EQ(ret, std::nullopt);
1039
1040 caches.index4Key_.clear();
1041 caches.node4key4ttype_.insert({ key1, {} });
1042 ret = caches.GetL1KeyToUpdate(key1);
1043 EXPECT_EQ(ret, std::nullopt);
1044
1045 caches.node4key4ttype_.clear();
1046 caches.node4key4ttype_.insert({ key1, { { key, nullptr } } });
1047 ret = caches.GetL1KeyToUpdate(key1);
1048 EXPECT_NE(ret, std::nullopt);
1049 }
1050
1051 /**
1052 * @tc.name: RepeatNodeCacheTest033
1053 * @tc.desc: Test GetL2KeyToUpdate
1054 * @tc.type: FUNC
1055 */
1056 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest033, TestSize.Level1)
1057 {
1058 RepeatVirtualScrollCaches caches(
1059 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1060
1061 auto ret = caches.GetL2KeyToUpdate(std::nullopt);
1062 EXPECT_EQ(ret, std::nullopt);
1063
1064 std::string key("key");
1065 ret = caches.GetL2KeyToUpdate(key);
1066 EXPECT_EQ(ret, std::nullopt);
1067
1068 caches.node4key4ttype_.insert({ key, { { key, nullptr } } });
1069 ret = caches.GetL2KeyToUpdate(key);
1070 EXPECT_NE(ret, std::nullopt);
1071
1072 caches.node4key4ttype_.clear();
1073 caches.node4key4ttype_.insert({ key, { { key, nullptr } } });
1074 ret = caches.GetL2KeyToUpdate(key);
1075 EXPECT_NE(ret, std::nullopt);
1076
1077 std::unordered_map<std::string, RefPtr<UINode>> nodeKey;
1078 caches.node4key4ttype_ = { { "template1", nodeKey } };
1079 ret = caches.GetL2KeyToUpdate(key);
1080 EXPECT_EQ(ret, std::nullopt);
1081 }
1082
1083 /**
1084 * @tc.name: RepeatNodeCacheTest034
1085 * @tc.desc: Test GetFrameNodeIndex
1086 * @tc.type: FUNC
1087 */
1088 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest034, TestSize.Level1)
1089 {
1090 RepeatVirtualScrollCaches caches(
1091 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1092
1093 auto ret = caches.GetFrameNodeIndex(nullptr);
1094 EXPECT_EQ(ret, -1);
1095
1096 std::string key("key");
1097 caches.activeNodeKeysInL1_.insert(key);
1098 ret = caches.GetFrameNodeIndex(nullptr);
1099 EXPECT_EQ(ret, -1);
1100
1101 caches.node4key_.insert({ key, CacheItem() });
1102 caches.activeNodeKeysInL1_.insert(key);
1103 ret = caches.GetFrameNodeIndex(nullptr);
1104 EXPECT_EQ(ret, -1);
1105
1106 caches.activeNodeKeysInL1_ = { "Key1", "Key2" };
1107 caches.key4index_ = { { 0, "Key1" }, { 1, "Key2" } };
1108 caches.ttype4index_ = { { 0, "template1" }, { 1, "template2" } };
1109 caches.index4ttype_ = { { "template1", 0 }, { "template2", 1 } };
1110
1111 CacheItem cacheItem;
1112 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1113 cacheItem.item = node;
1114 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { {"Key1", node} };
1115 caches.node4key_ = { {"Key1", cacheItem} };
1116 caches.node4key4ttype_ = { {"template1", nodeKey} };
1117 ret = caches.GetFrameNodeIndex(node);
1118 EXPECT_EQ(ret, -1);
1119
1120 caches.index4Key_ = { {"Key1", 2} };
1121 ret = caches.GetFrameNodeIndex(node);
1122 EXPECT_EQ(ret, 2);
1123 }
1124
1125 /**
1126 * @tc.name: RepeatNodeCacheTest035
1127 * @tc.desc: Test Multiple functions
1128 * @tc.type: FUNC
1129 */
1130 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest035, TestSize.Level1)
1131 {
1132 RepeatVirtualScrollCaches caches(cacheCountL24ttype,
1133 onCreateNode,
1134 g_onUpdateNode,
1135 g_onGetKeys4Range,
1136 g_onGetTypes4Range);
1137
1138 std::optional<std::string> key1 = caches.GetKey4Index(1, true);
1139 EXPECT_EQ(key1, "Key1");
1140 std::optional<std::string> key2 = caches.GetKey4Index(2, true);
1141 EXPECT_EQ(key2, "Key2");
1142 std::optional<std::string> key3 = caches.GetKey4Index(3, true);
1143 EXPECT_EQ(key3, "Key3");
1144 RefPtr<UINode> node1 = caches.CreateNewNode(1);
1145 EXPECT_NE(node1, nullptr);
1146 RefPtr<UINode> node2 = caches.CreateNewNode(2);
1147 EXPECT_NE(node2, nullptr);
1148 RefPtr<UINode> node3 = caches.CreateNewNode(3);
1149 EXPECT_NE(node3, nullptr);
1150
1151 auto repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
1152 1,
1153 3,
1154 templateCachedCountMap,
1155 onCreateNode,
1156 g_onUpdateNode,
1157 g_onGetKeys4Range,
1158 g_onGetTypes4Range,
1159 g_onSetActiveRange);
1160
1161 // Set caches to repeat.
1162 repeatNode->caches_ = caches;
1163 repeatNode->caches_.FetchMoreKeysTTypes(1, 3);
1164 repeatNode->caches_.AddKeyToL1("Key1");
1165 repeatNode->caches_.AddKeyToL1("Key2");
1166 repeatNode->caches_.AddKeyToL1("Key3");
1167
1168 std::set<int32_t> activeItems;
1169 const int largeValue = 100;
1170 for (int i = 0; i < largeValue; i++) {
1171 activeItems.insert(i);
1172 }
1173 std::set<int32_t> cachedItems;
1174 cachedItems.insert(1);
1175
1176 /**
1177 * @tc.steps: step2. Perform two DoSetActiveChildRange calls
1178 * First with valid value 1 and second too large value
1179 * @tc.expected: Functions do not return any value
1180 */
1181 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, 1);
1182 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, largeValue+1);
1183 }
1184
1185 /**
1186 * @tc.name: RepeatNodeCacheTest036
1187 * @tc.desc: Call functions that are currently empty implementations
1188 * @tc.type: FUNC
1189 */
1190 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest036, TestSize.Level1)
1191 {
1192 auto repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
1193 1,
1194 3,
1195 templateCachedCountMap,
1196 onCreateNode,
1197 g_onUpdateNode,
1198 g_onGetKeys4Range,
1199 g_onGetTypes4Range,
1200 g_onSetActiveRange);
1201
1202 EXPECT_NE(repeatNode, nullptr);
1203
__anon14a184a20a02(int32_t start, int32_t end) 1204 auto onMoveLambda = [](int32_t start, int32_t end) {
1205 };
1206 /**
1207 * @tc.steps: step1. Call functions with no implementation yet in repeat_virtual_scroll_node.cpp
1208 * @tc.expected: Not crash happens
1209 */
1210 repeatNode->SetOnMove(std::move(onMoveLambda));
1211 repeatNode->MoveData(0, 100);
1212 auto frameNode = repeatNode->GetFrameNode(1);
1213 repeatNode->InitDragManager(frameNode);
1214 repeatNode->InitAllChildrenDragManager(true);
1215 }
1216
1217 /**
1218 * @tc.name: RepeatNodeCacheTest037
1219 * @tc.desc: Test CheckNode4IndexInL1 function
1220 * @tc.type: FUNC
1221 */
1222 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest037, TestSize.Level1)
1223 {
1224 auto repeatNode = GetOrCreateRepeatNode(true);
1225 ASSERT_NE(repeatNode, nullptr);
1226 auto frameNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1227 auto ret = repeatNode->CheckNode4IndexInL1(3, 2, 4, 1, 1, frameNode);
1228 EXPECT_TRUE(frameNode->isActive_);
1229 EXPECT_TRUE(ret);
1230
1231 repeatNode->SetIsLoop(true);
1232 ret = repeatNode->CheckNode4IndexInL1(3, 5, 2, 1, 1, frameNode);
1233 EXPECT_FALSE(frameNode->isActive_);
1234 EXPECT_TRUE(ret);
1235
1236 repeatNode->SetIsLoop(false);
1237 ret = repeatNode->CheckNode4IndexInL1(3, 5, 2, 1, 1, frameNode);
1238 EXPECT_FALSE(frameNode->isActive_);
1239 EXPECT_FALSE(ret);
1240 }
1241
1242 /**
1243 * @tc.name: RepeatNodeCacheTest038
1244 * @tc.desc: Test for DropFromL1
1245 * @tc.type: FUNC
1246 */
1247 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest038, TestSize.Level1)
1248 {
1249 auto repeatNode = GetOrCreateRepeatNode(false);
1250 ASSERT_NE(repeatNode, nullptr);
1251
1252 auto childNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1253 repeatNode->children_.clear();
1254 repeatNode->children_.push_back(childNode);
1255 EXPECT_EQ(repeatNode->children_.size(), 1);
1256 repeatNode->DropFromL1("Key038");
1257 EXPECT_EQ(repeatNode->children_.size(), 1);
1258 }
1259
1260 /**
1261 * @tc.name: RepeatNodeCacheTest039
1262 * @tc.desc: Test for UpdateRenderState
1263 * @tc.type: FUNC
1264 */
1265 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest039, TestSize.Level1)
1266 {
1267 auto repeatNode = GetOrCreateRepeatNode(false);
1268 ASSERT_NE(repeatNode, nullptr);
1269 auto childNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1270 repeatNode->children_.clear();
1271 repeatNode->children_.push_back(childNode);
1272 EXPECT_EQ(repeatNode->children_.size(), 1);
1273
1274 auto frameNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1275 repeatNode->SetParent(frameNode);
1276 repeatNode->UpdateRenderState(true);
1277 EXPECT_EQ(repeatNode->children_.size(), 0);
1278
1279 repeatNode->children_.push_back(childNode);
1280 repeatNode->UpdateRenderState(false);
1281 EXPECT_EQ(repeatNode->children_.size(), 1);
1282 }
1283
1284 /**
1285 * @tc.name: RepeatNodeCacheTest040
1286 * @tc.desc: Test for GetFrameChildByIndex
1287 * @tc.type: FUNC
1288 */
1289 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest040, TestSize.Level1)
1290 {
1291 auto repeatNode = GetOrCreateRepeatNode(false);
1292 ASSERT_NE(repeatNode, nullptr);
1293 auto childNode = repeatNode->GetFrameChildByIndex(0, false, false, false);
1294 EXPECT_EQ(childNode, nullptr);
1295
1296 RepeatVirtualScrollCaches caches(
1297 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1298 caches.key4index_.insert(pair<int, string>(0, "Key1"));
1299 CacheItem cacheItem;
1300 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
1301 auto node = AceType::MakeRefPtr<FrameNode>("node", nodeId, AceType::MakeRefPtr<Pattern>());
1302 cacheItem.item = node;
1303
1304 RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1305 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key1", uiNode } };
1306 caches.node4key_ = { { "Key1", cacheItem } };
1307 caches.node4key4ttype_ = { { "template1", nodeKey } };
1308 repeatNode->caches_ = caches;
1309
1310 childNode = repeatNode->GetFrameChildByIndex(1, false, false, false);
1311 EXPECT_EQ(childNode, nullptr);
1312
1313 childNode = repeatNode->GetFrameChildByIndex(1, true, false, false);
1314 EXPECT_EQ(childNode, nullptr);
1315
1316 childNode = repeatNode->GetFrameChildByIndex(0, true, false, false);
1317 repeatNode->isActive_ = true;
1318 EXPECT_EQ(childNode, nullptr);
1319
1320 nodeKey = { { "Key1", node } };
1321 caches.index4ttype_ = { { "template1", 0 } };
1322 caches.ttype4index_ = { { 0, "template1" } };
1323 caches.node4key4ttype_ = { { "template1", nodeKey } };
1324 caches.activeNodeKeysInL1_ = { "Key1" };
1325 repeatNode->caches_ = caches;
1326 childNode = repeatNode->GetFrameChildByIndex(0, false, false, true);
1327 ASSERT_NE(childNode, nullptr);
1328 EXPECT_EQ(childNode->GetId(), nodeId);
1329 }
1330
1331 /**
1332 * @tc.name: RepeatNodeCacheTest041
1333 * @tc.desc: Test for GetFrameChildByIndex
1334 * @tc.type: FUNC
1335 */
1336 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest041, TestSize.Level1)
1337 {
1338 auto repeatNode = GetOrCreateRepeatNode(false);
1339 ASSERT_NE(repeatNode, nullptr);
1340 auto childNode = repeatNode->GetFrameChildByIndex(0, false, false, false);
1341 EXPECT_EQ(childNode, nullptr);
1342
1343 RepeatVirtualScrollCaches caches(
1344 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1345 caches.key4index_.insert(pair<int, string>(0, "Key041"));
1346 CacheItem cacheItem;
1347 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
1348 auto node = AceType::MakeRefPtr<FrameNode>("node", nodeId, AceType::MakeRefPtr<Pattern>());
1349 cacheItem.item = node;
1350 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key041", node } };
1351 caches.node4key_ = { { "Key041", cacheItem } };
1352
1353 auto ttype = g_onGetTypes4Range(0, 0).front();
1354 caches.node4key4ttype_ = { { ttype, nodeKey } };
1355 caches.ttype4index_ = { { 0, ttype } };
1356 caches.index4ttype_ = { { ttype, 0 } };
1357 repeatNode->caches_ = caches;
1358 repeatNode->onMainTree_ = true;
1359
__anon14a184a20b02(int32_t a, int32_t b) 1360 std::function<void(int32_t, int32_t)> onMoveEvent_ = [](int32_t a, int32_t b) {};
1361 repeatNode->onMoveEvent_ = onMoveEvent_;
1362 childNode = repeatNode->GetFrameChildByIndex(0, false, false, true);
1363 ASSERT_NE(childNode, nullptr);
1364 EXPECT_EQ(childNode->GetId(), nodeId);
1365 }
1366
1367 /**
1368 * @tc.name: RepeatNodeCacheTest042
1369 * @tc.desc: Test for GetChildren
1370 * @tc.type: FUNC
1371 */
1372 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest042, TestSize.Level1)
1373 {
1374 auto repeatNode = GetOrCreateRepeatNode(false);
1375 ASSERT_NE(repeatNode, nullptr);
1376 repeatNode->caches_.activeNodeKeysInL1_ = { { "Key042", "Key2", "Key3" } };
1377
1378 CacheItem cacheItem;
1379 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1380 cacheItem.item = node;
1381 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key042", node } };
1382 repeatNode->caches_.index4Key_ = { { "Key042", 0 } };
1383 repeatNode->caches_.node4key_ = { { "Key042", cacheItem } };
1384 auto children = repeatNode->GetChildren();
1385 EXPECT_EQ(children.size(), 1);
1386
1387 repeatNode->children_ = { node };
1388 children = repeatNode->GetChildren();
1389 EXPECT_EQ(children.size(), 1);
1390 }
1391
1392 /**
1393 * @tc.name: RepeatNodeCacheTest043
1394 * @tc.desc: Test UpdateChildrenFreezeState function
1395 * @tc.type: FUNC
1396 */
1397 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest043, TestSize.Level1)
1398 {
1399 auto repeatNode = GetOrCreateRepeatNode(false);
1400 ASSERT_NE(repeatNode, nullptr);
1401 repeatNode->caches_.activeNodeKeysInL1_ = { { "Key043", "Key2", "Key3" } };
1402
1403 CacheItem cacheItem;
1404 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1405 cacheItem.item = node;
1406 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key043", node } };
1407 repeatNode->caches_.node4key_ = { { "Key043", cacheItem } };
1408 auto context = MockPipelineContext::GetCurrent();
1409 ASSERT_NE(context, nullptr);
1410 context->SetOpenInvisibleFreeze(true);
1411 repeatNode->UpdateChildrenFreezeState(true);
1412 for (auto iter = repeatNode->caches_.node4key_.begin(); iter != repeatNode->caches_.node4key_.end(); ++iter) {
1413 auto item = iter->second.item;
1414 ASSERT_NE(item, nullptr);
1415 EXPECT_TRUE(item->isFreeze_);
1416 }
1417
1418 repeatNode->UpdateChildrenFreezeState(false);
1419 for (auto iter = repeatNode->caches_.node4key_.begin(); iter != repeatNode->caches_.node4key_.end(); ++iter) {
1420 auto item = iter->second.item;
1421 ASSERT_NE(item, nullptr);
1422 EXPECT_FALSE(item->isFreeze_);
1423 }
1424 }
1425
1426 /**
1427 * @tc.name: RepeatNodeCacheTest044
1428 * @tc.desc: Test OnConfigurationUpdate function
1429 * @tc.type: FUNC
1430 */
1431 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest044, TestSize.Level1)
1432 {
1433 auto repeatNode = GetOrCreateRepeatNode(false);
1434
1435 CacheItem cacheItem;
1436 auto frameNode = FrameNode::CreateFrameNode("frameNode", 1, AceType::MakeRefPtr<Pattern>(), true);
1437 ASSERT_NE(frameNode, nullptr);
1438 ASSERT_NE(frameNode->pattern_, nullptr);
1439
1440 cacheItem.item = frameNode;
1441 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key044", frameNode } };
1442 repeatNode->caches_.node4key_ = { { "Key044", cacheItem } };
1443
1444 ConfigurationChange cfgChange;
1445 cfgChange.colorModeUpdate = true;
1446 repeatNode->OnConfigurationUpdate(cfgChange);
1447 }
1448
1449 /**
1450 * @tc.name: RepeatNodeCacheTest045
1451 * @tc.desc: Test HasOverlapWithLastActiveRange function
1452 * @tc.type: FUNC
1453 */
1454 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest045, TestSize.Level1)
1455 {
1456 RepeatVirtualScrollCaches caches(
1457 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1458
1459 caches.lastActiveRanges_[0].first = 10;
1460 caches.lastActiveRanges_[0].second = 30;
1461 auto ret = caches.HasOverlapWithLastActiveRange(10, 20);
1462 EXPECT_TRUE(ret);
1463
1464 caches.lastActiveRanges_[0].first = 20;
1465 caches.lastActiveRanges_[0].second = 10;
1466 ret = caches.HasOverlapWithLastActiveRange(10, 20);
1467 EXPECT_TRUE(ret);
1468 }
1469
1470 /**
1471 * @tc.name: RepeatNodeCacheTest046
1472 * @tc.desc: Test AddKeyToL1 function
1473 * @tc.type: FUNC
1474 */
1475 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest046, TestSize.Level1)
1476 {
1477 RepeatVirtualScrollCaches caches(
1478 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1479
1480 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
1481 CacheItem cacheItem;
1482 auto node = AceType::MakeRefPtr<FrameNode>("node", nodeId, AceType::MakeRefPtr<Pattern>());
1483 cacheItem.item = node;
1484 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key046", node } };
1485 caches.node4key_ = { { "Key046", cacheItem } };
1486 caches.node4key4ttype_ = { { "template046", nodeKey } };
1487 caches.ttype4index_ = { { 0, "template046" } };
1488 caches.index4ttype_ = { { "template046", 0 } };
1489 caches.reusedNodeIds_.clear();
1490 caches.AddKeyToL1("Key046", true);
1491 EXPECT_EQ(caches.reusedNodeIds_.size(), 1);
1492 auto id = caches.reusedNodeIds_.begin();
1493 EXPECT_EQ(*id, node->GetId());
1494
1495 caches.AddKeyToL1("Key046", true);
1496 EXPECT_EQ(caches.reusedNodeIds_.size(), 1);
1497 EXPECT_EQ(*id, node->GetId());
1498 }
1499
1500 /**
1501 * @tc.name: RepeatNodeCacheTest047
1502 * @tc.desc: Test UpdateFromL2 function
1503 * @tc.type: FUNC
1504 */
1505 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest047, TestSize.Level1)
1506 {
1507 RepeatVirtualScrollCaches caches(
1508 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1509 caches.ttype4index_.clear();
1510 auto retNode = caches.UpdateFromL2(0);
1511 ASSERT_EQ(retNode, nullptr);
1512
1513 caches.ttype4index_ = { { 0, "template047" } };
1514 retNode = caches.UpdateFromL2(0);
1515 ASSERT_EQ(retNode, nullptr);
1516
1517 retNode = caches.UpdateFromL2(0);
1518 ASSERT_EQ(retNode, nullptr);
1519
1520 caches.key4index_ = { { 0, "Key047" } };
1521 retNode = caches.UpdateFromL2(0);
1522 ASSERT_EQ(retNode, nullptr);
1523
1524 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1525 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key047", node } };
1526 CacheItem cacheItem;
1527 cacheItem.item = node;
1528 caches.node4key_ = { { "Key047", cacheItem } };
1529 caches.node4key4ttype_ = { { "template047", nodeKey } };
1530 retNode = caches.UpdateFromL2(0);
1531 ASSERT_NE(retNode, nullptr);
1532 }
1533
1534 /**
1535 * @tc.name: RepeatNodeCacheTest048
1536 * @tc.desc: Test CreateNewNode function
1537 * @tc.type: FUNC
1538 */
1539 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest048, TestSize.Level1)
1540 {
1541 RepeatVirtualScrollCaches caches(
1542 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1543 auto retNode = caches.CreateNewNode(0);
1544 ASSERT_EQ(retNode, nullptr);
1545 caches.key4index_ = { { 0, "Key048" } };
1546 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1547 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key048", node } };
1548 CacheItem cacheItem;
1549 cacheItem.item = node;
1550 caches.node4key_ = { { "Key048", cacheItem } };
1551 retNode = caches.CreateNewNode(0);
1552 ASSERT_NE(retNode, nullptr);
1553 caches.node4key_.clear();
1554 retNode = caches.CreateNewNode(0);
1555 ASSERT_EQ(retNode, nullptr);
1556
1557 caches.ttype4index_ = { { 0, "template048" } };
1558 retNode = caches.CreateNewNode(0);
1559 ASSERT_EQ(retNode, nullptr);
1560 }
1561
1562 /**
1563 * @tc.name: RepeatNodeCacheTest049
1564 * @tc.desc: Test RecycleItemsByIndex function
1565 * @tc.type: FUNC
1566 */
1567 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest049, TestSize.Level1)
1568 {
1569 RepeatVirtualScrollCaches caches(
1570 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1571
1572 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
1573 CacheItem cacheItem;
1574 auto node = AceType::MakeRefPtr<FrameNode>("node", nodeId, AceType::MakeRefPtr<Pattern>());
1575 cacheItem.item = node;
1576 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key049", node } };
1577 caches.key4index_ = { { nodeId, "Key049" } };
1578 caches.node4key_ = { { "Key049", cacheItem } };
1579 caches.reusedNodeIds_.clear();
1580 caches.AddKeyToL1("Key049", true);
1581 EXPECT_EQ(caches.reusedNodeIds_.size(), 1);
1582 auto id = caches.reusedNodeIds_.begin();
1583 EXPECT_EQ(*id, node->GetId());
1584 caches.RecycleItemsByIndex(nodeId);
1585 EXPECT_EQ(caches.reusedNodeIds_.size(), 1);
1586 }
1587
1588 /**
1589 * @tc.name: RepeatNodeCacheTest050
1590 * @tc.desc: Test RebuildL1 function
1591 * @tc.type: FUNC
1592 */
1593 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest050, TestSize.Level1)
1594 {
1595 RepeatVirtualScrollCaches caches(
1596 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1597 caches.activeNodeKeysInL1_ = { "Key0" };
1598
__anon14a184a20c02(int32_t a, const RefPtr<UINode>& b) 1599 std::function<bool(int32_t, const RefPtr<UINode>&)> callback = [](int32_t a, const RefPtr<UINode>& b) {
1600 return true;
1601 };
1602 auto ret = caches.RebuildL1(callback);
1603 EXPECT_FALSE(ret);
1604
1605 caches.activeNodeKeysInL1_ = { "Key050" };
1606 caches.index4Key_ = { { "Key050", 0 } };
1607 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
1608 CacheItem cacheItem;
1609 auto node = AceType::MakeRefPtr<FrameNode>("node", nodeId, AceType::MakeRefPtr<Pattern>());
1610 cacheItem.item = node;
1611 caches.node4key_ = { { "Key050", cacheItem } };
1612 ret = caches.RebuildL1(callback);
1613 EXPECT_FALSE(ret);
1614 EXPECT_EQ(caches.activeNodeKeysInL1_.size(), 1);
1615
__anon14a184a20d02(int32_t a, const RefPtr<UINode>& b) 1616 std::function<bool(int32_t, const RefPtr<UINode>&)> callback2 = [](int32_t a, const RefPtr<UINode>& b) {
1617 return false;
1618 };
1619 ret = caches.RebuildL1(callback2);
1620 EXPECT_TRUE(ret);
1621 EXPECT_EQ(caches.activeNodeKeysInL1_.size(), 0);
1622 }
1623
1624 /**
1625 * @tc.name: RepeatNodeCacheTest051
1626 * @tc.desc: Test SetLastActiveRange function
1627 * @tc.type: FUNC
1628 */
1629 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest051, TestSize.Level1)
1630 {
1631 RepeatVirtualScrollCaches caches(
1632 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1633 std::pair<uint32_t, uint32_t> range = { 10, 30 };
1634 caches.lastActiveRanges_[0] = range;
1635 EXPECT_EQ(caches.lastActiveRanges_[0], range);
1636 caches.cacheCountL24ttype_ = { { "Key051", { true, 0 } } };
1637 caches.SetLastActiveRange(20, 25);
1638 EXPECT_EQ(caches.lastActiveRanges_[1], range);
1639 std::pair<uint32_t, uint32_t> range2 = { 20, 25 };
1640 EXPECT_EQ(caches.lastActiveRanges_[0], range2);
1641
1642 caches.cacheCountL24ttype_ = { { "Key051", { false, 0 } } };
1643 caches.SetLastActiveRange(20, 25);
1644 std::map<std::string, std::pair<bool, uint32_t>> cacheCout = { { "Key051", { false, 6 } } };
1645 EXPECT_EQ(caches.cacheCountL24ttype_, cacheCout);
1646 }
1647
1648 /**
1649 * @tc.name: RepeatNodeCacheTest052
1650 * @tc.desc: Test SetLastActiveRange function
1651 * @tc.type: FUNC
1652 */
1653 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest052, TestSize.Level1)
1654 {
1655 RepeatVirtualScrollCaches caches(
1656 cacheCountL24ttype, g_onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1657
1658 auto ret = caches.Purge();
1659 EXPECT_FALSE(ret);
1660 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1661 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key052", node } };
1662 caches.node4key4ttype_ = { { "template052", nodeKey } };
1663 ret = caches.Purge();
1664 EXPECT_TRUE(ret);
1665 }
1666
1667 /**
1668 * @tc.name: RepeatNodeCacheTest053
1669 * @tc.desc: Test DoSetActiveChildRange function
1670 * @tc.type: FUNC
1671 */
1672 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest053, TestSize.Level1)
1673 {
1674 auto repeatNode = GetOrCreateRepeatNode(true);
1675
1676 RepeatVirtualScrollCaches caches(
1677 cacheCountL24ttype, onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1678
1679 auto childNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1680 repeatNode->children_.clear();
1681 repeatNode->children_.push_back(childNode);
1682 EXPECT_EQ(repeatNode->children_.size(), 1);
1683
1684 caches.index4Key_ = { { "Key053", 0 } };
1685 caches.activeNodeKeysInL1_ = { "Key053" };
1686 repeatNode->caches_ = caches;
1687 repeatNode->DoSetActiveChildRange(0, 1, 0, 0);
1688 EXPECT_EQ(repeatNode->children_.size(), 0);
1689
1690 CacheItem cacheItem;
1691 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1692 cacheItem.item = node;
1693 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key053", node } };
1694 caches.node4key_ = { { "Key053", cacheItem } };
1695 repeatNode->caches_ = caches;
1696 repeatNode->DoSetActiveChildRange(0, 1, 0, 0);
1697 EXPECT_EQ(repeatNode->children_.size(), 0);
1698
1699 repeatNode->children_.clear();
1700 repeatNode->children_.push_back(childNode);
1701 repeatNode->SetIsLoop(false);
1702 repeatNode->DoSetActiveChildRange(3, 5, 2, 1);
1703 EXPECT_EQ(repeatNode->children_.size(), 0);
1704 }
1705
1706 /**
1707 * @tc.name: RepeatNodeCacheTest054
1708 * @tc.desc: Test DoSetActiveChildRange function
1709 * @tc.type: FUNC
1710 */
1711 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest054, TestSize.Level1)
1712 {
1713 auto repeatNode = GetOrCreateRepeatNode(true);
1714
1715 RepeatVirtualScrollCaches caches(
1716 cacheCountL24ttype, onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1717
1718 repeatNode->caches_ = caches;
1719 repeatNode->caches_.AddKeyToL1("Key054");
1720 repeatNode->caches_.AddKeyToL1("Key2");
1721 repeatNode->caches_.AddKeyToL1("Key3");
1722 std::set<int32_t> activeItems;
1723
1724 const int largeValue = 100;
1725 for (int i = 0; i < largeValue; i++) {
1726 activeItems.insert(i);
1727 }
1728 std::set<int32_t> cachedItems;
1729 cachedItems.insert(1);
1730 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, 1);
1731
1732 repeatNode->caches_.index4Key_ = { { "Key054", 0 } };
1733 repeatNode->caches_.activeNodeKeysInL1_ = { "Key054" };
1734 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, 0);
1735
1736 repeatNode->caches_.activeNodeKeysInL1_ = { "Key054" };
1737 auto childNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1738 repeatNode->children_ = { childNode };
1739 EXPECT_EQ(repeatNode->children_.size(), 1);
1740 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, 0);
1741 EXPECT_EQ(repeatNode->children_.size(), 0);
1742 }
1743
1744 /**
1745 * @tc.name: RepeatNodeCacheTest055
1746 * @tc.desc: Test DoSetActiveChildRange function
1747 * @tc.type: FUNC
1748 */
1749 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest055, TestSize.Level1)
1750 {
1751 auto repeatNode = GetOrCreateRepeatNode(true);
1752
1753 RepeatVirtualScrollCaches caches(
1754 cacheCountL24ttype, onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1755
1756 CacheItem cacheItem;
1757 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1758 cacheItem.item = node;
1759 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key055", node } };
1760 caches.node4key_ = { { "Key055", cacheItem } };
1761 caches.index4Key_ = { { "Key055", 0 } };
1762 caches.activeNodeKeysInL1_ = { "Key055" };
1763 repeatNode->caches_ = caches;
1764 repeatNode->children_ = { node };
1765 auto childNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1766 node->children_ = { childNode };
1767
1768 std::set<int32_t> activeItems;
1769 const int largeValue = 100;
1770 for (int i = 3; i < largeValue; i++) {
1771 activeItems.insert(i);
1772 }
1773
1774 std::set<int32_t> cachedItems;
1775 cachedItems.insert(1);
1776
1777 EXPECT_EQ(repeatNode->children_.size(), 1);
1778 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, 1);
1779 EXPECT_EQ(repeatNode->children_.size(), 1);
1780
1781 EXPECT_EQ(repeatNode->children_.size(), 1);
1782 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, 1);
1783 EXPECT_EQ(repeatNode->children_.size(), 1);
1784 }
1785
1786 /**
1787 * @tc.name: RepeatNodeCacheTest056
1788 * @tc.desc: Test DoSetActiveChildRange function
1789 * @tc.type: FUNC
1790 */
1791 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest056, TestSize.Level1)
1792 {
1793 auto repeatNode = GetOrCreateRepeatNode(true);
1794
1795 RepeatVirtualScrollCaches caches(
1796 cacheCountL24ttype, onCreateNode, g_onUpdateNode, g_onGetKeys4Range, g_onGetTypes4Range);
1797
1798 CacheItem cacheItem;
1799 auto node = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1800 cacheItem.item = node;
1801 std::unordered_map<std::string, RefPtr<UINode>> nodeKey = { { "Key056", node } };
1802 caches.node4key_ = { { "Key056", cacheItem } };
1803 caches.index4Key_ = { { "Key056", 0 } };
1804 caches.activeNodeKeysInL1_ = { "Key056" };
1805 repeatNode->caches_ = caches;
1806 repeatNode->children_ = { node };
1807 auto childNode = AceType::MakeRefPtr<FrameNode>("node", -1, AceType::MakeRefPtr<Pattern>());
1808 node->children_ = { childNode };
1809
1810 std::set<int32_t> activeItems;
1811 const int largeValue = 100;
1812 for (int i = 0; i < largeValue; i++) {
1813 activeItems.insert(i);
1814 }
1815
1816 std::set<int32_t> cachedItems = { 1 };
1817
1818 EXPECT_EQ(repeatNode->children_.size(), 1);
1819 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, 1);
1820 EXPECT_EQ(repeatNode->children_.size(), 1);
1821
1822 activeItems.clear();
1823 for (int i = 3; i < largeValue; i++) {
1824 activeItems.insert(i);
1825 }
1826
1827 EXPECT_EQ(repeatNode->children_.size(), 1);
1828 repeatNode->DoSetActiveChildRange(activeItems, cachedItems, 0);
1829 EXPECT_EQ(repeatNode->children_.size(), 0);
1830 }
1831
1832 /**
1833 * @tc.name: RepeatNodeCacheTest057
1834 * @tc.desc: Test for GetOrCreateRepeatNode
1835 * @tc.type: FUNC
1836 */
1837 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest057, TestSize.Level1)
1838 {
1839 RepeatModelNG repeatModel;
1840 repeatModel.StartRender();
1841
1842 auto repeatNode = AceType::DynamicCast<RepeatNode>(ViewStackProcessor::GetInstance()->Finish());
1843 ASSERT_NE(repeatNode, nullptr);
1844 EXPECT_EQ(repeatNode->GetTag(), V2::JS_REPEAT_ETS_TAG);
1845
1846 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
1847 auto node = repeatNode->GetOrCreateRepeatNode(nodeId);
1848 ASSERT_NE(node, nullptr);
1849
1850 auto existNode = repeatNode->GetOrCreateRepeatNode(nodeId);
1851 ASSERT_NE(existNode, nullptr);
1852 EXPECT_EQ(existNode->GetId(), nodeId);
1853 }
1854
1855 /**
1856 * @tc.name: RepeatNodeCacheTest058
1857 * @tc.desc: Test for FinishRepeatRender
1858 * @tc.type: FUNC
1859 */
1860 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest058, TestSize.Level1)
1861 {
1862 RepeatModelNG repeatModel;
1863 repeatModel.StartRender();
1864
1865 auto repeatNode = AceType::DynamicCast<RepeatNode>(ViewStackProcessor::GetInstance()->Finish());
1866 ASSERT_NE(repeatNode, nullptr);
1867 EXPECT_EQ(repeatNode->GetTag(), V2::JS_REPEAT_ETS_TAG);
1868
1869 auto childNode = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
1870 repeatNode->children_ = { childNode };
1871 EXPECT_GT(repeatNode->children_.size(), 0);
1872
1873 std::list<std::string> ids2 = FOR_REPEAT_IDS;
1874 repeatNode->SetIds(std::move(ids2));
1875 repeatNode->CreateTempItems();
1876 EXPECT_GT(repeatNode->tempChildrenOfRepeat_.size(), 0);
1877
1878 std::list<int32_t> arr;
1879 arr.push_back(0);
1880 repeatNode->FinishRepeatRender(arr);
1881 EXPECT_EQ(repeatNode->tempChildren_.size(), 0);
1882 EXPECT_EQ(repeatNode->tempChildrenOfRepeat_.size(), 0);
1883 }
1884
1885 /**
1886 * @tc.name: RepeatNodeCacheTest059
1887 * @tc.desc: Test for FinishRepeatRender
1888 * @tc.type: FUNC
1889 */
1890 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest059, TestSize.Level1)
1891 {
1892 RepeatModelNG repeatModel;
1893 repeatModel.StartRender();
1894
1895 auto repeatNode = AceType::DynamicCast<RepeatNode>(ViewStackProcessor::GetInstance()->Finish());
1896 ASSERT_NE(repeatNode, nullptr);
1897 EXPECT_EQ(repeatNode->GetTag(), V2::JS_REPEAT_ETS_TAG);
1898
1899 auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
1900 repeatNode->SetParent(node);
1901 auto childNode = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
1902 repeatNode->children_ = { childNode };
1903 EXPECT_GT(repeatNode->children_.size(), 0);
1904
1905 std::list<std::string> ids2 = FOR_REPEAT_IDS;
1906 repeatNode->SetIds(std::move(ids2));
1907 repeatNode->CreateTempItems();
1908 EXPECT_GT(repeatNode->tempChildrenOfRepeat_.size(), 0);
1909
1910 std::list<int32_t> arr;
1911 arr.push_back(0);
1912 repeatNode->FinishRepeatRender(arr);
1913 EXPECT_EQ(repeatNode->tempChildren_.size(), 0);
1914 EXPECT_EQ(repeatNode->tempChildrenOfRepeat_.size(), 0);
1915 }
1916
1917 /**
1918 * @tc.name: RepeatNodeCacheTest060
1919 * @tc.desc: Test for MoveChild
1920 * @tc.type: FUNC
1921 */
1922 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest060, TestSize.Level1)
1923 {
1924 RepeatModelNG repeatModel;
1925 repeatModel.StartRender();
1926 auto repeatNode = AceType::DynamicCast<RepeatNode>(ViewStackProcessor::GetInstance()->Finish());
1927 ASSERT_NE(repeatNode, nullptr);
1928 EXPECT_EQ(repeatNode->GetTag(), V2::JS_REPEAT_ETS_TAG);
1929
1930 auto node = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
1931 repeatNode->SetParent(node);
1932 auto childNode = AceType::MakeRefPtr<FrameNode>(NODE_TAG, -1, AceType::MakeRefPtr<Pattern>());
1933 repeatNode->children_ = { childNode };
1934 EXPECT_GT(repeatNode->children_.size(), 0);
1935 EXPECT_EQ(repeatNode->tempChildrenOfRepeat_.size(), 0);
1936
1937 std::list<std::string> ids2 = FOR_REPEAT_IDS;
1938 repeatNode->SetIds(std::move(ids2));
1939 repeatNode->CreateTempItems();
1940 EXPECT_GT(repeatNode->tempChildrenOfRepeat_.size(), 0);
1941
1942 repeatNode->MoveChild(0);
1943 }
1944
1945 /**
1946 * @tc.name: RepeatNodeCacheTest061
1947 * @tc.desc: Test for GetFrameChildByIndex
1948 * @tc.type: FUNC
1949 */
1950 HWTEST_F(RepeatNodeCacheSyntaxTest, RepeatNodeCacheTest061, TestSize.Level1)
1951 {
__anon14a184a20e02(uint32_t from, uint32_t to) 1952 auto onGetTypes4Range = [](uint32_t from, uint32_t to) -> std::list<std::string> {
1953 std::list<std::string> types;
1954 for (uint32_t i = from; i <= to; ++i) {
1955 types.push_back("elmt1");
1956 }
1957 return types;
1958 };
1959 // enable reuse
1960 RefPtr<RepeatVirtualScrollNode> repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
1961 NODE_ID, COUNT_3, templateCachedCountMap, onCreateNode, g_onUpdateNode, g_onGetKeys4Range, onGetTypes4Range,
1962 g_onSetActiveRange, true);
1963 ASSERT_NE(repeatNode, nullptr);
1964 repeatNode->GetFrameChildByIndex(0, true, false, true);
1965 repeatNode->GetFrameChildByIndex(1, true, false, true);
1966 repeatNode->DoSetActiveChildRange(0, 0, 0, 0);
1967 auto node = repeatNode->GetFrameChildByIndex(2, true, false, true);
1968 ASSERT_NE(node, nullptr);
1969 EXPECT_EQ(node->GetId(), 1);
1970 // diable reuse
1971 repeatNode = RepeatVirtualScrollNode::GetOrCreateRepeatNode(
1972 NODE_ID + 1, COUNT_3, templateCachedCountMap, onCreateNode, g_onUpdateNode, g_onGetKeys4Range, onGetTypes4Range,
1973 g_onSetActiveRange, false);
1974 ASSERT_NE(repeatNode, nullptr);
1975 repeatNode->GetFrameChildByIndex(0, true, false, true);
1976 repeatNode->GetFrameChildByIndex(1, true, false, true);
1977 repeatNode->DoSetActiveChildRange(0, 0, 0, 0);
1978 node = repeatNode->GetFrameChildByIndex(2, true, false, true);
1979 ASSERT_NE(node, nullptr);
1980 EXPECT_EQ(node->GetId(), 2);
1981 }
1982 } // namespace OHOS::Ace::NG
1983