• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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