• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "repeat_virtual_2_test_ng.h"
17 
18 using namespace testing;
19 using namespace testing::ext;
20 
21 namespace OHOS::Ace::NG {
22 
23 using CacheItem = RepeatVirtualScroll2Caches::CacheItem;
24 using OptCacheItem = RepeatVirtualScroll2Caches::OptCacheItem;
25 using GetFrameChildResult = RepeatVirtualScroll2Caches::GetFrameChildResult;
26 
CreateNode(const std::string & tag)27 RefPtr<FrameNode> RepeatVirtual2TestNg::CreateNode(const std::string& tag)
28 {
29     auto pattern = AceType::MakeRefPtr<Pattern>();
30     auto frameNode = AceType::MakeRefPtr<FrameNode>(tag, elmtId_, pattern);
31     pattern->AttachToFrameNode(frameNode);
32     ViewStackProcessor::GetInstance()->Push(frameNode);
33     return frameNode;
34 }
35 
CreateRepeatVirtualNode(uint32_t totalCount)36 RefPtr<RepeatVirtualScroll2Node> RepeatVirtual2TestNg::CreateRepeatVirtualNode(uint32_t totalCount)
37 {
38     l1Rid4Index_ = {
39         {0, 1},
40         {1, 2},
41         {2, 3},
42         {3, 4},
43         {4, 5},
44         {5, 6}
45     };
46     onGetRid4Index_ = [&](IndexType index) -> std::pair<RIDType, uint32_t> {
47         auto it = l1Rid4Index_.find(0);
48         if (it != l1Rid4Index_.end()) {
49             return {index, 2};
50         }
51         return {index, 1};
52     };
53     onRecycleItems_ = [](IndexType fromIndex, IndexType toIndex) -> void {
54         return;
55     };
56     onActiveRange_ = [](int32_t fromIndex, int32_t toIndex, int32_t vStart, int32_t vEnd, bool isLoop,
57         bool forceUpdate) -> void {
58         return;
59     };
60     onMoveFromTo_ = [](IndexType, IndexType) -> void {
61         return;
62     };
63     onPurge_ = []() -> void {
64         return;
65     };
66     return RepeatVirtualScroll2Node::GetOrCreateRepeatNode(
67         GetElmtId(), totalCount, totalCount, onGetRid4Index_, onRecycleItems_, onActiveRange_, onMoveFromTo_, onPurge_);
68 }
69 
CreateListItemNode()70 RefPtr<FrameNode> RepeatVirtual2TestNg::CreateListItemNode()
71 {
72     auto tag = "TEXT_ETS_TAG";
73     auto* stack = ViewStackProcessor::GetInstance();
74     auto listItemFrameNode = FrameNode::GetOrCreateFrameNode(V2::LIST_ITEM_ETS_TAG, GetElmtId(), []() {
75         return AceType::MakeRefPtr<ListItemPattern>(nullptr, V2::ListItemStyle::NONE);
76     });
77 
78     auto textNode = CreateNode(V2::TEXT_ETS_TAG);
79 
80     auto pattern = AceType::MakeRefPtr<Pattern>();
81     auto textFrameNode = AceType::MakeRefPtr<FrameNode>(tag, GetElmtId(), pattern);
82     pattern->AttachToFrameNode(textFrameNode);
83     listItemFrameNode->AddChild(textFrameNode);
84 
85     pattern = AceType::MakeRefPtr<Pattern>();
86     textFrameNode = AceType::MakeRefPtr<FrameNode>(tag, GetElmtId(), pattern);
87     pattern->AttachToFrameNode(textFrameNode);
88     listItemFrameNode->AddChild(textFrameNode);
89     stack->Push(listItemFrameNode);
90     return listItemFrameNode;
91 }
92 
93 /**
94  * @tc.name: CreateRepeat001
95  * @tc.desc: Test creation of GetOrCreateRepeatNode
96  * @tc.type: FUNC
97  */
98 HWTEST_F(RepeatVirtual2TestNg, CreateRepeat001, TestSize.Level1)
99 {
100     auto* stack = ViewStackProcessor::GetInstance();
101     auto nodeId = stack->ClaimNodeId();
102     /**
103      * @tc.steps: step1. Create node object
104      * @tc.expected: Object is not nullptr.
105      */
106     auto repeatNode = RepeatVirtualScroll2Node::GetOrCreateRepeatNode(
107         nodeId, 10, 10, onGetRid4Index_, onRecycleItems_, onActiveRange_, onMoveFromTo_, onPurge_);
108 
109     EXPECT_NE(repeatNode, nullptr);
110 }
111 
112 /**
113  * @tc.name: FrameCount001
114  * @tc.desc: Test node.FrameCount
115  * @tc.type: FUNC
116  */
117 HWTEST_F(RepeatVirtual2TestNg, FrameCount001, TestSize.Level1)
118 {
119     auto repeatNode = CreateRepeatVirtualNode(10);
120 
121     /**
122      * @tc.steps: step2. Get frame count
123      * @tc.expected: frame count should be 10
124      */
125     auto frameCount = repeatNode->FrameCount();
126     EXPECT_EQ(frameCount, 10);
127 
128     /**
129      * @tc.steps: step2. Update totalCount to 2
130      * @tc.expected: frame count should be 2
131      */
132     repeatNode->UpdateTotalCount(2);
133     frameCount = repeatNode->FrameCount();
134     EXPECT_EQ(frameCount, 2);
135 }
136 
137 /**
138  * @tc.name: GetChildren001
139  * @tc.desc: Test node.GetChildren
140  * @tc.type: FUNC
141  */
142 HWTEST_F(RepeatVirtual2TestNg, GetChildren001, TestSize.Level1)
143 {
144     /**
145      * @tc.steps: step1. Test node.GetChildren when repeat is empty
146      * @tc.expected: children size shoule be 0
147      */
148     auto repeatNode = CreateRepeatVirtualNode(10);
149     auto children = repeatNode->GetChildren();
150     EXPECT_EQ(children.size(), 0);
151 
152     /**
153      * @tc.steps: step2. Test node.GetChildren when repeat has 1 item
154      * @tc.expected: children size shoule be 0
155      */
156     repeatNode->caches_.l1Rid4Index_ = {
157         {0, 1}
158     };
159     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2002, AceType::MakeRefPtr<Pattern>());
160     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
161     std::map<RIDType, CacheItem> cacheItem4Rid_ = {{ 0, cacheItem }};
162     repeatNode->children_ = { uiNode };
163     children = repeatNode->GetChildren();
164     EXPECT_EQ(children.size(), 1);
165 }
166 
167 /**
168  * @tc.name: GetFrameChild001
169  * @tc.desc: Test caches.GetFrameChild
170  * @tc.type: FUNC
171  */
172 HWTEST_F(RepeatVirtual2TestNg, GetFrameChild001, TestSize.Level1)
173 {
174     RepeatVirtualScroll2Caches caches(onGetRid4Index_);
175 
176     /**
177      * @tc.steps: step1. give l1 cache items include item (rid == 1)
178      * @tc.expected: return rid
179      */
180     GetFrameChildResult result = caches.GetFrameChild(1, false);
181     EXPECT_EQ(result.second, 0);
182 
183     /**
184      * @tc.steps: step2. give l1 cache items include item (rid == 10)
185      * @tc.expected: return nullptr
186      */
187     result = caches.GetFrameChild(10, false);
188     EXPECT_EQ(result.second, nullptr);
189 }
190 
191 /**
192  * @tc.name: RemoveNode001
193  * @tc.desc: Test caches.RemoveNode
194  * @tc.type: FUNC
195  */
196 HWTEST_F(RepeatVirtual2TestNg, RemoveNode001, TestSize.Level1)
197 {
198     auto repeatNode = CreateRepeatVirtualNode(10);
199     repeatNode->caches_.l1Rid4Index_ = {
200         {0, 1}, {1, 2}, {2, 3}, {3, 4}
201     };
202     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2004, AceType::MakeRefPtr<Pattern>());
203     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
204     repeatNode->caches_.cacheItem4Rid_ = {
205         { 1, cacheItem }, { 2, cacheItem }, { 3, cacheItem }, { 4, cacheItem }
206     };
207 
208     /**
209      * @tc.steps: step1. remove 1 item from L1
210      * @tc.expected: repeat has 3 children left
211      */
212     EXPECT_EQ(repeatNode->GetChildren().size(), 4);
213     repeatNode->caches_.RemoveNode(2);
214     repeatNode->children_.clear();
215     EXPECT_EQ(repeatNode->GetChildren().size(), 3);
216 }
217 
218 /**
219  * @tc.name: CheckActiveRange001
220  * @tc.desc: Test node.CheckActiveRange for List/Swiper-no-Loop scenario
221  * @tc.type: FUNC
222  */
223 HWTEST_F(RepeatVirtual2TestNg, CheckActiveRange001, TestSize.Level1)
224 {
225     auto repeatNode = CreateRepeatVirtualNode(10);
226     ActiveRangeType activeRange;
227 
228     /**
229      * @tc.steps: step1. check active range: [0 1 2] 3 4 5..
230      * @tc.expected: active range is {0,4}
231      */
232     activeRange = repeatNode->CheckActiveRange(0, 2, 0, 2);
233     std::pair<IndexType, IndexType> expect_result1(0, 4);
234     EXPECT_EQ(activeRange, expect_result1);
235 
236     /**
237      * @tc.steps: step2. check active range: ..1 2 [3 4 5] 6 7..
238      * @tc.expected: active range is {1,7}
239      */
240     activeRange = repeatNode->CheckActiveRange(3, 5, 2, 2);
241     std::pair<IndexType, IndexType> expect_result2(1, 7);
242     EXPECT_EQ(activeRange, expect_result2);
243 
244     /**
245      * @tc.steps: step3. check active range: ..5 6 [7 8 9]
246      * @tc.expected: active range is {5,9}
247      */
248     activeRange = repeatNode->CheckActiveRange(7, 9, 2, 0);
249     std::pair<IndexType, IndexType> expect_result3(5, 9);
250     EXPECT_EQ(activeRange, expect_result3);
251 }
252 
253 /**
254  * @tc.name: CheckActiveRange002
255  * @tc.desc: Test node.CheckActiveRange for Grid/WaterFlow scenario
256  * @tc.type: FUNC
257  */
258 HWTEST_F(RepeatVirtual2TestNg, CheckActiveRange002, TestSize.Level1)
259 {
260     auto repeatNode = CreateRepeatVirtualNode(10);
261     ActiveRangeType activeRange;
262 
263     /**
264      * @tc.steps: step1. check active range for: [0 1 2] 3 4 5..
265      * @tc.expected: active range is {0,4}
266      */
267     activeRange = repeatNode->CheckActiveRange(0, 2, 2, 2);
268     std::pair<IndexType, IndexType> expect_result1(0, 4);
269     EXPECT_EQ(activeRange, expect_result1);
270 
271     /**
272      * @tc.steps: step2. check active range for: ..1 2 [3 4 5] 6 7..
273      * @tc.expected: active range is {1,7}
274      */
275     activeRange = repeatNode->CheckActiveRange(3, 5, 2, 2);
276     std::pair<IndexType, IndexType> expect_result2(1, 7);
277     EXPECT_EQ(activeRange, expect_result2);
278 
279     /**
280      * @tc.steps: step3. check active range for: ..5 6 [7 8 9]
281      * @tc.expected: active range is {5,9}
282      */
283     activeRange = repeatNode->CheckActiveRange(7, 9, 2, 2);
284     std::pair<IndexType, IndexType> expect_result3(5, 9);
285     EXPECT_EQ(activeRange, expect_result3);
286 }
287 
288 /**
289  * @tc.name: CheckActiveRange003
290  * @tc.desc: Test node.CheckActiveRange for Swiper-Loop scenario
291  * @tc.type: FUNC
292  */
293 HWTEST_F(RepeatVirtual2TestNg, CheckActiveRange003, TestSize.Level1)
294 {
295     auto repeatNode = CreateRepeatVirtualNode(10);
296     repeatNode->SetIsLoop(true);
297     ActiveRangeType activeRange;
298 
299     /**
300      * @tc.steps: step1. check active range for: ..8 9 [0 1 2] 3 4..
301      * @tc.expected: active range is {-2,4}
302      */
303     activeRange = repeatNode->CheckActiveRange(0, 2, 2, 2);
304     std::pair<IndexType, IndexType> expect_result1(-2, 4);
305     EXPECT_EQ(activeRange, expect_result1);
306 
307     /**
308      * @tc.steps: step2. check active range for: ..7 8 [9 0 1] 2 3..
309      * @tc.expected: active range is {7,3}
310      */
311     activeRange = repeatNode->CheckActiveRange(9, 1, 2, 2);
312     std::pair<IndexType, IndexType> expect_result2(7, 3);
313     EXPECT_EQ(activeRange, expect_result2);
314 
315     /**
316      * @tc.steps: step3. check active range for: ..5 6 [7 8 9] 0 1..
317      * @tc.expected: active range is {5,11}
318      */
319     activeRange = repeatNode->CheckActiveRange(7, 9, 2, 2);
320     std::pair<IndexType, IndexType> expect_result3(5, 11);
321     EXPECT_EQ(activeRange, expect_result3);
322 
323     /**
324      * @tc.steps: step4. check active range for: 2 [3 0] 1
325      * @tc.expected: active range is {3,2} (overlapped)
326      */
327     auto repeatNode2 = CreateRepeatVirtualNode(4);
328     repeatNode2->SetIsLoop(true);
329     activeRange = repeatNode2->CheckActiveRange(3, 0, 2, 2);
330     std::pair<IndexType, IndexType> expect_result4(3, 2);
331     EXPECT_EQ(activeRange, expect_result4);
332 
333     /**
334      * @tc.steps: step5. check active range for: [0 1] 2 3..
335      * @tc.expected: active range is {-2,3}
336      */
337     auto repeatNode3 = CreateRepeatVirtualNode(10);
338     repeatNode3->SetIsLoop(true);
339     activeRange = repeatNode3->CheckActiveRange(0, 1, 2, 2);
340     std::pair<IndexType, IndexType> expect_result5(-2, 3);
341     EXPECT_EQ(activeRange, expect_result5);
342 }
343 
344 /**
345  * @tc.name: CheckActiveRange004
346  * @tc.desc: Test node.CheckActiveRange for List/Grid/WaterFlow/Swiper-no-Loop scenario (multiple components)
347  *   X indicates a non-repeat child
348  * @tc.type: FUNC
349  */
350 HWTEST_F(RepeatVirtual2TestNg, CheckActiveRange004, TestSize.Level1)
351 {
352     auto repeatNode = CreateRepeatVirtualNode(10);
353     ActiveRangeType activeRange;
354 
355     /**
356      * @tc.steps: step1. check active range for: ..[X X 0 1 2] 3 4..
357      * @tc.expected: active range is {0,4}
358      */
359     activeRange = repeatNode->CheckActiveRange(-2, 2, 2, 2);
360     std::pair<IndexType, IndexType> expect_result1(0, 4);
361     EXPECT_EQ(activeRange, expect_result1);
362 
363     /**
364      * @tc.steps: step2. check active range for: ..[X X X] 0 1 2..
365      * @tc.expected: active range is {0,1}
366      */
367     activeRange = repeatNode->CheckActiveRange(-5, -1, 2, 2);
368     std::pair<IndexType, IndexType> expect_result2(0, 1);
369     EXPECT_EQ(activeRange, expect_result2);
370 
371     /**
372      * @tc.steps: step3. check active range for: ..[X X X] X X 0 1..
373      * @tc.expected: active range is {INT32_MAX,INT32_MAX}
374      */
375     activeRange = repeatNode->CheckActiveRange(-5, -3, 2, 2);
376     std::pair<IndexType, IndexType> expect_result3(INT32_MAX, INT32_MAX);
377     EXPECT_EQ(activeRange, expect_result3);
378 
379     /**
380      * @tc.steps: step4. check active range for: ..5 6 [7 8 9 X X]..
381      * @tc.expected: active range is {5,9}
382      */
383     activeRange = repeatNode->CheckActiveRange(7, 11, 2, 2);
384     std::pair<IndexType, IndexType> expect_result4(5, 9);
385     EXPECT_EQ(activeRange, expect_result4);
386 
387     /**
388      * @tc.steps: step5. check active range for: ..8 9 [X X X]..
389      * @tc.expected: active range is {8,9}
390      */
391     activeRange = repeatNode->CheckActiveRange(10, 12, 2, 2);
392     std::pair<IndexType, IndexType> expect_result5(8, 9);
393     EXPECT_EQ(activeRange, expect_result5);
394 
395     /**
396      * @tc.steps: step6. check active range for: ..8 9 X X [X X X]..
397      * @tc.expected: active range is {INT32_MAX,INT32_MAX}
398      */
399     activeRange = repeatNode->CheckActiveRange(12, 14, 2, 2);
400     std::pair<IndexType, IndexType> expect_result6(INT32_MAX, INT32_MAX);
401     EXPECT_EQ(activeRange, expect_result6);
402 }
403 
404 /**
405  * @tc.name: CheckNodeInL1001
406  * @tc.desc: Test node.CheckNode4IndexInL1
407  * @tc.type: FUNC
408  */
409 HWTEST_F(RepeatVirtual2TestNg, CheckNodeInL1001, TestSize.Level1)
410 {
411     auto repeatNode = CreateRepeatVirtualNode(10);
412     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2009, AceType::MakeRefPtr<Pattern>());
413     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
414     bool remainInL1;
415 
416     /**
417      * @tc.steps: step1. check normal active range
418      * @tc.expected: node in L1 cache, return true
419      */
420     remainInL1 = repeatNode->CheckNode4IndexInL1(1, 0, 9, cacheItem);
421     EXPECT_EQ(remainInL1, true);
422     remainInL1 = repeatNode->CheckNode4IndexInL1(5, 6, 9, cacheItem);
423     EXPECT_EQ(remainInL1, false);
424     remainInL1 = repeatNode->CheckNode4IndexInL1(10, 6, 9, cacheItem);
425     EXPECT_EQ(remainInL1, false);
426 
427     /**
428      * @tc.steps: step2. check swiper-loop range
429      * @tc.expected: node in L1 cache, return true
430      */
431     repeatNode->SetIsLoop(true);
432     remainInL1 = repeatNode->CheckNode4IndexInL1(5, 0, 9, cacheItem);
433     EXPECT_EQ(remainInL1, true);
434     remainInL1 = repeatNode->CheckNode4IndexInL1(3, 2, 1, cacheItem);
435     EXPECT_EQ(remainInL1, true);
436 }
437 
438 /**
439  * @tc.name: SetActiveRange001
440  * @tc.desc: Test node.DoSetActiveChildRange
441  * @tc.type: FUNC
442  */
443 HWTEST_F(RepeatVirtual2TestNg, SetActiveRange001, TestSize.Level1)
444 {
445     auto repeatNode = CreateRepeatVirtualNode(10);
446 
447     /**
448      * @tc.steps: step1. check normal active range
449      * @tc.expected: repeat has 8 items
450      */
451     repeatNode->children_.clear();
452     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2010, AceType::MakeRefPtr<Pattern>());
453     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
454     for (int i = 0; i < 10; ++i) {
455         repeatNode->caches_.l1Rid4Index_.insert({i, i + 1});
456         repeatNode->caches_.cacheItem4Rid_.insert({i + 1, cacheItem});
457     }
458     repeatNode->DoSetActiveChildRange(0, 5, 2, 2);
459     EXPECT_EQ(repeatNode->GetChildren().size(), 8);
460 
461     /**
462      * @tc.steps: step2. check swiper-loop range
463      * @tc.expected: repeat has 6 items
464      */
465     repeatNode->children_.clear();
466     repeatNode->caches_.l1Rid4Index_.clear();
467     for (int i = 0; i < 10; ++i) {
468         repeatNode->caches_.l1Rid4Index_.insert({i, i + 1});
469         repeatNode->caches_.cacheItem4Rid_.insert({i + 1, cacheItem});
470     }
471     repeatNode->SetIsLoop(true);
472     repeatNode->DoSetActiveChildRange(8, 1, 1, 1);
473     EXPECT_EQ(repeatNode->GetChildren().size(), 6);
474 }
475 
476 /**
477  * @tc.name: GetL1Nodes001
478  * @tc.desc: Test caches.GetL1Index4Node
479  * @tc.type: FUNC
480  */
481 HWTEST_F(RepeatVirtual2TestNg, GetL1Nodes001, TestSize.Level1)
482 {
483     auto repeatNode = CreateRepeatVirtualNode(10);
484     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2011, AceType::MakeRefPtr<Pattern>());
485     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
486     repeatNode->caches_.l1Rid4Index_ = {
487         {0, 1}
488     };
489     repeatNode->caches_.cacheItem4Rid_ = {
490         {1, cacheItem}
491     };
492 
493     /**
494      * @tc.steps: step1.
495      * @tc.expected: GetL1Index4Node return 1
496      */
497     std::optional<IndexType> result = repeatNode->caches_.GetL1Index4Node(AceType::DynamicCast<FrameNode>(uiNode));
498     EXPECT_EQ(result.value(), 0);
499 }
500 
501 /**
502  * @tc.name: GetAllNodes001
503  * @tc.desc: Test caches.GetCacheItem4RID
504  * @tc.type: FUNC
505  */
506 HWTEST_F(RepeatVirtual2TestNg, GetAllNodes001, TestSize.Level1)
507 {
508     auto repeatNode = CreateRepeatVirtualNode(10);
509     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2012, AceType::MakeRefPtr<Pattern>());
510     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
511 
512     /**
513      * @tc.steps: step1.
514      * @tc.expected: should return cacheItem
515      */
516     repeatNode->caches_.l1Rid4Index_ = {
517         {0, 1}
518     };
519     repeatNode->caches_.cacheItem4Rid_ = {
520         {1, cacheItem}
521     };
522     OptCacheItem optCacheItem = repeatNode->caches_.GetCacheItem4RID(1);
523     EXPECT_EQ(optCacheItem.has_value(), true);
524 }
525 
526 /**
527  * @tc.name: GetRID4Index001
528  * @tc.desc: Test caches.GetRID4Index
529  * @tc.type: FUNC
530  */
531 HWTEST_F(RepeatVirtual2TestNg, GetRID4Index001, TestSize.Level1)
532 {
533     auto repeatNode = CreateRepeatVirtualNode(10);
534     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2013, AceType::MakeRefPtr<Pattern>());
535     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
536 
537     /**
538      * @tc.steps: step1.
539      * @tc.expected: should return rid=1
540      */
541     repeatNode->caches_.l1Rid4Index_ = {
542         {0, 1}
543     };
544     repeatNode->caches_.cacheItem4Rid_ = {
545         {1, cacheItem}
546     };
547     std::optional<RIDType> rid = repeatNode->caches_.GetRID4Index(0);
548     EXPECT_EQ(rid.value(), 1);
549 }
550 
551 /**
552  * @tc.name: CallOnGetRid4Index001
553  * @tc.desc: Test caches.CallOnGetRid4Index
554  * @tc.type: FUNC
555  */
556 HWTEST_F(RepeatVirtual2TestNg, CallOnGetRid4Index001, TestSize.Level1)
557 {
558     auto repeatNode = CreateRepeatVirtualNode(10);
559 
__anon31d030f10702(IndexType index)560     repeatNode->caches_.onGetRid4Index_ = [](IndexType index)->std::pair<RIDType, uint32_t> {
561         return {1, OnGetRid4IndexResult::CREATED_NEW_NODE}; };
562     auto item0 = repeatNode->caches_.CallOnGetRid4Index(0).value();
563     EXPECT_EQ(item0, nullptr);
564 
__anon31d030f10802(IndexType index)565     repeatNode->caches_.onGetRid4Index_ = [&](IndexType index)->std::pair<RIDType, uint32_t> {
566         CreateListItemNode(); return {1, OnGetRid4IndexResult::CREATED_NEW_NODE}; };
567     auto item1 = repeatNode->caches_.CallOnGetRid4Index(0).value();
568     EXPECT_EQ(item1->node_->GetId(), 10002);
569 
__anon31d030f10902(IndexType index)570     repeatNode->caches_.onGetRid4Index_ = [&](IndexType index)->std::pair<RIDType, uint32_t> {
571         CreateListItemNode(); return {0, OnGetRid4IndexResult::CREATED_NEW_NODE}; };
572     auto item2 = repeatNode->caches_.CallOnGetRid4Index(0);
573     EXPECT_EQ(item2, std::nullopt);
574 
__anon31d030f10a02(IndexType index)575     repeatNode->caches_.onGetRid4Index_ = [](IndexType index)->std::pair<RIDType, uint32_t> {
576         return {1, OnGetRid4IndexResult::UPDATED_NODE}; };
577     auto item3 = repeatNode->caches_.CallOnGetRid4Index(0).value();
578     EXPECT_EQ(item3->node_->GetId(), 10002);
579 
__anon31d030f10b02(IndexType index)580     repeatNode->caches_.onGetRid4Index_ = [](IndexType index)->std::pair<RIDType, uint32_t> {
581         return {2, OnGetRid4IndexResult::UPDATED_NODE}; };
582     auto item4 = repeatNode->caches_.CallOnGetRid4Index(0);
583     EXPECT_EQ(item4, std::nullopt);
584 
__anon31d030f10c02(IndexType index)585     repeatNode->caches_.onGetRid4Index_ = [](IndexType index)->std::pair<RIDType, uint32_t> {
586         return {1, OnGetRid4IndexResult::UPDATED_NODE}; };
587     repeatNode->caches_.GetCacheItem4RID(1).value()->node_ = nullptr;
588     auto item5 = repeatNode->caches_.CallOnGetRid4Index(0);
589     EXPECT_EQ(item5, std::nullopt);
590 
__anon31d030f10d02(IndexType index)591     repeatNode->caches_.onGetRid4Index_ = [](IndexType index)->std::pair<RIDType, uint32_t> {
592         return {0, OnGetRid4IndexResult::UPDATED_NODE}; };
593     auto item6 = repeatNode->caches_.CallOnGetRid4Index(0);
594     EXPECT_EQ(item6, std::nullopt);
595 
__anon31d030f10e02(IndexType index)596     repeatNode->caches_.onGetRid4Index_ = [](IndexType index)->std::pair<RIDType, uint32_t> {
597         return {1, OnGetRid4IndexResult::NO_NODE}; };
598     auto item7 = repeatNode->caches_.CallOnGetRid4Index(0);
599     EXPECT_EQ(item7, std::nullopt);
600 }
601 
602 /**
603  * @tc.name: ConvertFromToIndex001
604  * @tc.desc: Test caches.ConvertFromToIndex
605  * @tc.type: FUNC
606  */
607 HWTEST_F(RepeatVirtual2TestNg, ConvertFromToIndex001, TestSize.Level1)
608 {
609     auto repeatNode = CreateRepeatVirtualNode(6);
610     repeatNode->MoveData(0, 1);
611     repeatNode->MoveData(1, 2);
612     repeatNode->MoveData(2, 3);
613 
614     /**
615      * @tc.steps: step1.
616      * @tc.expected: index is 0, mappedIndex should be 1.
617      */
618     IndexType mappedIndex = repeatNode->caches_.ConvertFromToIndex(0);
619     EXPECT_EQ(mappedIndex, 1);
620 
621     /**
622      * @tc.steps: step2.
623      * @tc.expected: index is 1, mappedIndex should be 2.
624      */
625     mappedIndex = repeatNode->caches_.ConvertFromToIndex(1);
626     EXPECT_EQ(mappedIndex, 2);
627 
628     /**
629      * @tc.steps: step3.
630      * @tc.expected: index is 2, mappedIndex should be 3.
631      */
632     mappedIndex = repeatNode->caches_.ConvertFromToIndex(2);
633     EXPECT_EQ(mappedIndex, 3);
634 
635     /**
636      * @tc.steps: step4.
637      * @tc.expected: index is 3, mappedIndex should be 0.
638      */
639     mappedIndex = repeatNode->caches_.ConvertFromToIndex(3);
640     EXPECT_EQ(mappedIndex, 0);
641 
642     /**
643      * @tc.steps: step5.
644      * @tc.expected: index is 4, 5, 6, mappedIndex should be same with index.
645      */
646     mappedIndex = repeatNode->caches_.ConvertFromToIndex(4);
647     EXPECT_EQ(mappedIndex, 4);
648     mappedIndex = repeatNode->caches_.ConvertFromToIndex(5);
649     EXPECT_EQ(mappedIndex, 5);
650     mappedIndex = repeatNode->caches_.ConvertFromToIndex(6);
651     EXPECT_EQ(mappedIndex, 6);
652 }
653 
654 /**
655  * @tc.name: ConvertFromToIndex002
656  * @tc.desc: Test caches.ConvertFromToIndexRevert
657  * @tc.type: FUNC
658  */
659 HWTEST_F(RepeatVirtual2TestNg, ConvertFromToIndex002, TestSize.Level1)
660 {
661     auto repeatNode = CreateRepeatVirtualNode(6);
662     repeatNode->MoveData(0, 1);
663     repeatNode->MoveData(1, 2);
664     repeatNode->MoveData(2, 3);
665 
666     /**
667      * @tc.steps: step1.
668      * @tc.expected: index is 0, mappedIndex should be 3.
669      */
670     IndexType mappedIndex = repeatNode->caches_.ConvertFromToIndexRevert(0);
671     EXPECT_EQ(mappedIndex, 3);
672 
673     /**
674      * @tc.steps: step2.
675      * @tc.expected: index is 1, mappedIndex should be 0.
676      */
677     mappedIndex = repeatNode->caches_.ConvertFromToIndexRevert(1);
678     EXPECT_EQ(mappedIndex, 0);
679 
680     /**
681      * @tc.steps: step3.
682      * @tc.expected: index is 2, mappedIndex should be 1.
683      */
684     mappedIndex = repeatNode->caches_.ConvertFromToIndexRevert(2);
685     EXPECT_EQ(mappedIndex, 1);
686 
687     /**
688      * @tc.steps: step4.
689      * @tc.expected: index is 3, mappedIndex should be 2.
690      */
691     mappedIndex = repeatNode->caches_.ConvertFromToIndexRevert(3);
692     EXPECT_EQ(mappedIndex, 2);
693 
694     /**
695      * @tc.steps: step5.
696      * @tc.expected: index is 4, 5, 6, mappedIndex should be same with index.
697      */
698     mappedIndex = repeatNode->caches_.ConvertFromToIndexRevert(4);
699     EXPECT_EQ(mappedIndex, 4);
700     mappedIndex = repeatNode->caches_.ConvertFromToIndexRevert(5);
701     EXPECT_EQ(mappedIndex, 5);
702     mappedIndex = repeatNode->caches_.ConvertFromToIndexRevert(6);
703     EXPECT_EQ(mappedIndex, 6);
704 }
705 
706 /**
707  * @tc.name: UpdateFrameChildIndexRecord001
708  * @tc.desc: Test node.updateFrameChildIndexRecord
709  * @tc.type: FUNC
710  */
711 HWTEST_F(RepeatVirtual2TestNg, UpdateFrameChildIndexRecord001, TestSize.Level1)
712 {
713     auto repeatNode = CreateRepeatVirtualNode(6);
714     repeatNode->minFrameChildIndex_ = 0;
715     repeatNode->maxFrameChildIndex_ = 0;
716     repeatNode->needRecordFirstFrameChild_ = true;
717 
718     /**
719      * @tc.steps: step1.
720      * @tc.expected: minFrameChildIndex_ is 2, maxFrameChildIndex_ is 2, needRecordFirstFrameChild_ is false.
721      */
722     repeatNode->updateFrameChildIndexRecord(2);
723     EXPECT_EQ(repeatNode->minFrameChildIndex_, 2);
724     EXPECT_EQ(repeatNode->maxFrameChildIndex_, 2);
725     EXPECT_EQ(repeatNode->needRecordFirstFrameChild_, false);
726 
727     /**
728      * @tc.steps: step2.
729      * @tc.expected: minFrameChildIndex_ is 1, maxFrameChildIndex_ is 3
730      */
731     repeatNode->updateFrameChildIndexRecord(1);
732     repeatNode->updateFrameChildIndexRecord(3);
733     EXPECT_EQ(repeatNode->minFrameChildIndex_, 1);
734     EXPECT_EQ(repeatNode->maxFrameChildIndex_, 3);
735 }
736 
737 /**
738  * @tc.name: NotifyColorModeChange001
739  * @tc.desc: Test caches.NotifyColorModeChange
740  * @tc.type: FUNC
741  */
742 HWTEST_F(RepeatVirtual2TestNg, NotifyColorModeChange001, TestSize.Level1)
743 {
744     auto repeatNode = CreateRepeatVirtualNode(10);
745     repeatNode->caches_.l1Rid4Index_ = {
746         {0, 1}, {1, 2}, {2, 3}, {3, 4}
747     };
748     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2016, AceType::MakeRefPtr<Pattern>());
749     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
750     repeatNode->caches_.cacheItem4Rid_ = {
751         { 1, cacheItem }, { 2, cacheItem }, { 3, cacheItem }, { 4, cacheItem }
752     };
753     repeatNode->NotifyColorModeChange(1);
754     EXPECT_TRUE(cacheItem->node_->measureAnyWay_);
755 }
756 
757 /**
758  * @tc.name: NotifyColorModeChange002
759  * @tc.desc: Test caches.NotifyColorModeChange
760  * @tc.type: FUNC
761  */
762 HWTEST_F(RepeatVirtual2TestNg, NotifyColorModeChange002, TestSize.Level1)
763 {
764     auto repeatNode = CreateRepeatVirtualNode(10);
765     repeatNode->caches_.l1Rid4Index_ = {
766         {0, 1}
767     };
768     RefPtr<UINode> uiNode = AceType::MakeRefPtr<CustomNode>(2016, "node");
769     RefPtr<UINode> childNode = AceType::MakeRefPtr<CustomNode>(2016, "childNode");
770     uiNode->children_ = { childNode };
771     uiNode->SetDarkMode(true);
772     CacheItem cacheItem = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
773     repeatNode->caches_.cacheItem4Rid_ = {
774         { 1, cacheItem }
775     };
776     EXPECT_FALSE(childNode->CheckIsDarkMode());
777     repeatNode->NotifyColorModeChange(1);
778     EXPECT_TRUE(childNode->CheckIsDarkMode());
779 }
780 
781 /**
782  * @tc.name: UpdateIsL1001
783  * @tc.desc: Test caches.UpdateIsL1
784  * @tc.type: FUNC
785  */
786 HWTEST_F(RepeatVirtual2TestNg, UpdateIsL1001, TestSize.Level1)
787 {
788     auto repeatNode = CreateRepeatVirtualNode(10);
789     RefPtr<UINode> uiNode = AceType::MakeRefPtr<FrameNode>("node", 2017, AceType::MakeRefPtr<Pattern>());
790     CacheItem cacheItem0 = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
791     CacheItem cacheItem1 = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode, true);
792     cacheItem0->node_ = nullptr;
793     repeatNode->caches_.UpdateIsL1(cacheItem0, false);
794     EXPECT_EQ(cacheItem0->isL1_, false);
795     EXPECT_EQ(repeatNode->caches_.recycledNodeIds_.size(), 0);
796     repeatNode->caches_.UpdateIsL1(cacheItem1, false);
797     EXPECT_EQ(cacheItem1->isL1_, false);
798     EXPECT_EQ(repeatNode->caches_.recycledNodeIds_.size(), 1);
799     repeatNode->caches_.UpdateIsL1(cacheItem0, true);
800     EXPECT_EQ(cacheItem0->isL1_, true);
801     EXPECT_EQ(repeatNode->caches_.recycledNodeIds_.size(), 1);
802     repeatNode->caches_.UpdateIsL1(cacheItem1, true);
803     EXPECT_EQ(cacheItem1->isL1_, true);
804     EXPECT_EQ(repeatNode->caches_.recycledNodeIds_.size(), 0);
805     repeatNode->caches_.UpdateIsL1(cacheItem1, false, false);
806     EXPECT_EQ(cacheItem1->isL1_, false);
807     EXPECT_EQ(repeatNode->caches_.recycledNodeIds_.size(), 0);
808 }
809 
810 /**
811  * @tc.name: UpdateL1Rid4Index001
812  * @tc.desc: Test caches.UpdateL1Rid4Index
813  * @tc.type: FUNC
814  */
815 HWTEST_F(RepeatVirtual2TestNg, UpdateL1Rid4Index001, TestSize.Level1)
816 {
817     auto repeatNode = CreateRepeatVirtualNode(10);
818     RefPtr<UINode> uiNode0 = AceType::MakeRefPtr<FrameNode>("node", 2018, AceType::MakeRefPtr<Pattern>());
819     RefPtr<UINode> uiNode1 = AceType::MakeRefPtr<FrameNode>("node", 2019, AceType::MakeRefPtr<Pattern>());
820     RefPtr<UINode> uiNode2 = AceType::MakeRefPtr<FrameNode>("node", 2020, AceType::MakeRefPtr<Pattern>());
821     CacheItem cacheItem0 = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode0, true);
822     CacheItem cacheItem1 = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode1, true);
823     CacheItem cacheItem2 = RepeatVirtualScroll2CacheItem::MakeCacheItem(uiNode2, false);
824     repeatNode->caches_.cacheItem4Rid_ = {
825         { 1, cacheItem0 }, { 2, cacheItem1 }, { 3, cacheItem2 }
826     };
827     repeatNode->caches_.UpdateL1Rid4Index({ { 1, 2 }, { 2, 3 } }, { 2 });
828     EXPECT_EQ(cacheItem0->isL1_, false);
829     EXPECT_EQ(cacheItem1->isL1_, true);
830     EXPECT_EQ(cacheItem2->isL1_, true);
831 }
832 
833 } // namespace OHOS::Ace::NG