1 /*
2  * Copyright (c) 2022-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 "scroll_test_ng.h"
17 
18 #include "test/mock/base/mock_task_executor.h"
19 #include "test/mock/core/common/mock_container.h"
20 #include "test/mock/core/common/mock_theme_manager.h"
21 #include "test/mock/core/pipeline/mock_pipeline_context.h"
22 
23 #include "core/components/common/layout/grid_system_manager.h"
24 #include "core/components/scroll/scroll_bar_theme.h"
25 #include "core/components_ng/pattern/linear_layout/column_model_ng.h"
26 #include "core/components_ng/pattern/scroll/effect/scroll_fade_effect.h"
27 #include "core/components_ng/pattern/scroll/scroll_spring_effect.h"
28 
29 namespace OHOS::Ace::NG {
SetUpTestSuite()30 void ScrollTestNg::SetUpTestSuite()
31 {
32     TestNG::SetUpTestSuite();
33     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
34     MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
35     auto themeConstants = CreateThemeConstants(THEME_PATTERN_SCROLL_BAR);
36     auto scrollBarTheme = ScrollBarTheme::Builder().Build(themeConstants);
37     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(scrollBarTheme));
38     scrollBarTheme->normalWidth_ = Dimension(NORMAL_WIDTH);
39     scrollBarTheme->padding_ = Edge(0.0);
40     scrollBarTheme->scrollBarMargin_ = Dimension(0.0);
41     scrollBarTheme->touchWidth_ = Dimension(DEFAULT_TOUCH_WIDTH, DimensionUnit::VP);
42     scrollBarTheme->activeWidth_ = Dimension(DEFAULT_ACTIVE_WIDTH, DimensionUnit::VP);
43     scrollBarTheme->normalWidth_ = Dimension(DEFAULT_NORMAL_WIDTH, DimensionUnit::VP);
44     MockPipelineContext::GetCurrentContext()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
45 }
46 
TearDownTestSuite()47 void ScrollTestNg::TearDownTestSuite()
48 {
49     TestNG::TearDownTestSuite();
50 }
51 
SetUp()52 void ScrollTestNg::SetUp() {}
53 
TearDown()54 void ScrollTestNg::TearDown()
55 {
56     frameNode_ = nullptr;
57     pattern_ = nullptr;
58     eventHub_ = nullptr;
59     layoutProperty_ = nullptr;
60     paintProperty_ = nullptr;
61     accessibilityProperty_ = nullptr;
62     scrollBar_ = nullptr;
63     ClearOldNodes();  // Each testcase will create new list at begin
64     AceApplicationInfo::GetInstance().isRightToLeft_ = false;
65 }
66 
GetScroll()67 void ScrollTestNg::GetScroll()
68 {
69     RefPtr<UINode> element = ViewStackProcessor::GetInstance()->GetMainElementNode();
70     frameNode_ = AceType::DynamicCast<FrameNode>(element);
71     pattern_ = frameNode_->GetPattern<ScrollPattern>();
72     eventHub_ = frameNode_->GetEventHub<ScrollEventHub>();
73     layoutProperty_ = frameNode_->GetLayoutProperty<ScrollLayoutProperty>();
74     paintProperty_ = frameNode_->GetPaintProperty<ScrollablePaintProperty>();
75     accessibilityProperty_ = frameNode_->GetAccessibilityProperty<ScrollAccessibilityProperty>();
76 }
77 
CreateScroll()78 ScrollModelNG ScrollTestNg::CreateScroll()
79 {
80     ResetElmtId();
81     ViewStackProcessor::GetInstance()->StartGetAccessRecordingFor(GetElmtId());
82     ScrollModelNG model;
83     model.Create();
84     auto proxy = model.CreateScrollBarProxy();
85     model.SetScrollBarProxy(proxy);
86     ViewAbstract::SetWidth(CalcLength(SCROLL_WIDTH));
87     ViewAbstract::SetHeight(CalcLength(SCROLL_HEIGHT));
88     GetScroll();
89     return model;
90 }
91 
CreateSnapScroll(ScrollSnapAlign scrollSnapAlign,const Dimension & intervalSize,const std::vector<Dimension> & snapPaginations,const std::pair<bool,bool> & enableSnapToSide)92 void ScrollTestNg::CreateSnapScroll(ScrollSnapAlign scrollSnapAlign, const Dimension& intervalSize,
93     const std::vector<Dimension>& snapPaginations, const std::pair<bool, bool>& enableSnapToSide)
94 {
95     ScrollModelNG model = CreateScroll();
96     model.SetScrollSnap(scrollSnapAlign, intervalSize, snapPaginations, enableSnapToSide);
97     CreateContent(SNAP_ITEM_NUMBER);
98     CreateDone(frameNode_);
99 }
100 
CreateContent(int32_t childNumber)101 void ScrollTestNg::CreateContent(int32_t childNumber)
102 {
103     ViewStackProcessor::GetInstance()->StartGetAccessRecordingFor(GetElmtId());
104     if (GetAxis() == Axis::HORIZONTAL) {
105         RowModelNG rowModel;
106         rowModel.Create(Dimension(0), nullptr, "");
107         ViewAbstract::SetWidth(CalcLength(Dimension(childNumber * ITEM_WIDTH)));
108         ViewAbstract::SetHeight(CalcLength(FILL_LENGTH));
109         for (int32_t index = 0; index < childNumber; index++) {
110             ViewStackProcessor::GetInstance()->StartGetAccessRecordingFor(GetElmtId());
111             RowModelNG rowModel;
112             rowModel.Create(Dimension(0), nullptr, "");
113             ViewAbstract::SetWidth(CalcLength(Dimension(ITEM_WIDTH)));
114             ViewAbstract::SetHeight(CalcLength(FILL_LENGTH));
115             ViewStackProcessor::GetInstance()->Pop();
116             ViewStackProcessor::GetInstance()->StopGetAccessRecording();
117         }
118     } else {
119         ColumnModelNG colModel;
120         colModel.Create(Dimension(0), nullptr, "");
121         ViewAbstract::SetWidth(CalcLength(FILL_LENGTH));
122         ViewAbstract::SetHeight(CalcLength(Dimension(childNumber * ITEM_HEIGHT)));
123         for (int32_t index = 0; index < childNumber; index++) {
124             ViewStackProcessor::GetInstance()->StartGetAccessRecordingFor(GetElmtId());
125             ColumnModelNG colModel;
126             colModel.Create(Dimension(0), nullptr, "");
127             ViewAbstract::SetWidth(CalcLength(FILL_LENGTH));
128             ViewAbstract::SetHeight(CalcLength(Dimension(ITEM_HEIGHT)));
129             ViewStackProcessor::GetInstance()->Pop();
130             ViewStackProcessor::GetInstance()->StopGetAccessRecording();
131         }
132     }
133     ViewStackProcessor::GetInstance()->Pop();
134     ViewStackProcessor::GetInstance()->StopGetAccessRecording();
135 }
136 
GetContentChild(int32_t index)137 RefPtr<FrameNode> ScrollTestNg::GetContentChild(int32_t index)
138 {
139     auto content = GetChildFrameNode(frameNode_, 0);
140     auto contentChild = GetChildFrameNode(content, index);
141     return contentChild;
142 }
143 
Touch(TouchType touchType,Offset offset,SourceType sourceType)144 void ScrollTestNg::Touch(TouchType touchType, Offset offset, SourceType sourceType)
145 {
146     TouchLocationInfo locationInfo(1);
147     locationInfo.SetTouchType(touchType);
148     locationInfo.SetLocalLocation(offset);
149     TouchEventInfo eventInfo("touch");
150     eventInfo.SetSourceDevice(sourceType);
151     eventInfo.AddTouchLocationInfo(std::move(locationInfo));
152     auto touchEvent = pattern_->GetScrollBar()->touchEvent_->GetTouchEventCallback();
153     touchEvent(eventInfo);
154 }
155 
Mouse(Offset location,MouseButton mouseButton,MouseAction mouseAction)156 void ScrollTestNg::Mouse(Offset location, MouseButton mouseButton, MouseAction mouseAction)
157 {
158     MouseInfo mouseInfo;
159     mouseInfo.SetLocalLocation(location);
160     mouseInfo.SetButton(mouseButton);
161     mouseInfo.SetAction(mouseAction);
162     auto mouseEventHub = frameNode_->GetOrCreateInputEventHub();
163     RefPtr<InputEvent> inputEvent = mouseEventHub->mouseEventActuator_->inputEvents_.front();
164     auto mouseEvent = inputEvent->GetOnMouseEventFunc();
165     mouseEvent(mouseInfo);
166 }
167 
Hover(bool isHover)168 void ScrollTestNg::Hover(bool isHover)
169 {
170     auto hoverEventHub = frameNode_->GetOrCreateInputEventHub();
171     RefPtr<InputEvent> inputEvent = hoverEventHub->hoverEventActuator_->inputEvents_.front();
172     auto hoverEvent = inputEvent->GetOnHoverEventFunc();
173     hoverEvent(isHover);
174 }
175 
OnScrollCallback(float offset,int32_t source)176 bool ScrollTestNg::OnScrollCallback(float offset, int32_t source)
177 {
178     bool result = pattern_->OnScrollCallback(offset, source);
179     FlushLayoutTask(frameNode_);
180     return result;
181 }
182 
ScrollToEdge(ScrollEdgeType scrollEdgeType)183 void ScrollTestNg::ScrollToEdge(ScrollEdgeType scrollEdgeType)
184 {
185     pattern_->ScrollToEdge(scrollEdgeType, false);
186     FlushLayoutTask(frameNode_);
187 }
188 
ScrollTo(float offset)189 void ScrollTestNg::ScrollTo(float offset)
190 {
191     pattern_->ScrollTo(offset);
192     FlushLayoutTask(frameNode_);
193 }
194 
GetAxis()195 Axis ScrollTestNg::GetAxis()
196 {
197     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
198     auto layoutProperty = frameNode->GetLayoutProperty<ScrollLayoutProperty>();
199     auto axis = layoutProperty->GetAxis();
200     return axis.has_value() ? axis.value() : Axis::VERTICAL;
201 }
202 
GetOffset(float childNumber)203 float ScrollTestNg::GetOffset(float childNumber)
204 {
205     bool isHorizontal = pattern_->GetAxis() == Axis::HORIZONTAL;
206     float offset = childNumber * (isHorizontal ? ITEM_WIDTH : ITEM_HEIGHT);
207     return offset;
208 }
209 
UpdateAndVerifyPosition(float delta,int32_t source,float expectOffset)210 AssertionResult ScrollTestNg::UpdateAndVerifyPosition(float delta, int32_t source, float expectOffset)
211 {
212     pattern_->UpdateCurrentOffset(delta, source);
213     FlushLayoutTask(frameNode_);
214     return IsEqual(pattern_->GetTotalOffset(), expectOffset);
215 }
216 
ScrollToNode(int32_t childIndex,float expectOffset)217 AssertionResult ScrollTestNg::ScrollToNode(int32_t childIndex, float expectOffset)
218 {
219     pattern_->ScrollToNode(GetContentChild(childIndex));
220     FlushLayoutTask(frameNode_);
221     return IsEqual(pattern_->GetTotalOffset(), expectOffset);
222 }
223 
IsEqualCurrentPosition(float expectOffset)224 AssertionResult ScrollTestNg::IsEqualCurrentPosition(float expectOffset)
225 {
226     FlushLayoutTask(frameNode_);
227     float currentOffset = pattern_->GetCurrentPosition();
228     return IsEqual(currentOffset, expectOffset);
229 }
230 
231 /**
232  * @tc.name: AttrScrollable001
233  * @tc.desc: Test attribute about scrollable,
234  * @tc.type: FUNC
235  */
236 HWTEST_F(ScrollTestNg, AttrScrollable001, TestSize.Level1)
237 {
238     /**
239      * @tc.steps: step1. Text default value: VERTICAL
240      */
241     CreateScroll();
242     CreateContent(TOTAL_ITEM_NUMBER);
243     CreateDone(frameNode_);
244     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_HEIGHT, SCROLL_FROM_JUMP, ITEM_HEIGHT));
245 
246     /**
247      * @tc.steps: step2. Text set value: HORIZONTAL
248      */
249     ClearOldNodes();
250     ScrollModelNG model = CreateScroll();
251     model.SetAxis(Axis::HORIZONTAL);
252     CreateContent(TOTAL_ITEM_NUMBER);
253     CreateDone(frameNode_);
254     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_WIDTH, SCROLL_FROM_JUMP, ITEM_WIDTH));
255 
256     /**
257      * @tc.steps: step3. Text set value: NONE
258      */
259     ClearOldNodes();
260     model = CreateScroll();
261     model.SetAxis(Axis::NONE);
262     CreateContent(TOTAL_ITEM_NUMBER);
263     CreateDone(frameNode_);
264     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_HEIGHT, SCROLL_FROM_JUMP, ITEM_HEIGHT));
265 }
266 
267 /**
268  * @tc.name: AttrEnableScrollInteraction001
269  * @tc.desc: Test attribute about enableScrollInteraction,
270  * @tc.type: FUNC
271  */
272 HWTEST_F(ScrollTestNg, AttrEnableScrollInteraction001, TestSize.Level1)
273 {
274     /**
275      * @tc.steps: step1. Test default value: true
276      */
277     CreateScroll();
278     CreateDone(frameNode_);
279     EXPECT_TRUE(pattern_->GetScrollableEvent()->GetEnabled());
280 
281     /**
282      * @tc.steps: step2. Test set value: false
283      */
284     ScrollModelNG model = CreateScroll();
285     model.SetScrollEnabled(false);
286     CreateDone(frameNode_);
287     EXPECT_FALSE(pattern_->GetScrollableEvent()->GetEnabled());
288 }
289 
290 /**
291  * @tc.name: ScrollTest002
292  * @tc.desc: When setting a fixed length and width, verify the related functions in the scroll pattern.
293  * @tc.type: FUNC
294  */
295 HWTEST_F(ScrollTestNg, ScrollTest002, TestSize.Level1)
296 {
297     ScrollModelNG model = CreateScroll();
298     model.SetAxis(Axis::HORIZONTAL);
299     model.SetDisplayMode(static_cast<int>(DisplayMode::OFF));
300     auto scrollProxy = model.CreateScrollBarProxy();
301     model.SetScrollBarProxy(scrollProxy);
302     CreateDone(frameNode_);
303 
304     /**
305      * @tc.steps: step1. When Axis is HORIZONTAL, Verify the callback function registered in scrollBarProxy.
306      * @tc.expected: Check whether the return value is as expected.
307      */
308     auto scrollBarProxy = pattern_->GetScrollBarProxy();
309     auto scrollableNode = scrollBarProxy->scorllableNode_;
310     if (scrollableNode.onPositionChanged) {
311         bool ret = scrollableNode.onPositionChanged(0.0, SCROLL_FROM_BAR, false);
312         EXPECT_TRUE(ret);
313         ret = scrollableNode.onPositionChanged(0.0, SCROLL_FROM_START, false);
314         EXPECT_TRUE(ret);
315     }
316 }
317 
318 /**
319  * @tc.name: ScrollTest003
320  * @tc.desc: When setting a fixed length and width, verify the related callback functions in the scroll pattern.
321  * @tc.type: FUNC
322  */
323 HWTEST_F(ScrollTestNg, ScrollTest003, TestSize.Level1)
324 {
325     /**
326      * @tc.steps: step1. Set ScrollSpringEffect and call relevant callback functions.
327      * @tc.expected: Check whether the return value is correct.
328      */
329     ScrollModelNG model = CreateScroll();
330     model.SetEdgeEffect(EdgeEffect::SPRING, true);
331     CreateContent(TOTAL_ITEM_NUMBER);
332     CreateDone(frameNode_);
333     EXPECT_EQ(pattern_->scrollableDistance_, VERTICAL_SCROLLABLE_DISTANCE);
334     RefPtr<ScrollEdgeEffect> scrollEdgeEffect = pattern_->GetScrollEdgeEffect();
335     auto springEffect = AceType::DynamicCast<ScrollSpringEffect>(scrollEdgeEffect);
336     pattern_->currentOffset_ = 100.f;
337     EXPECT_TRUE(springEffect->outBoundaryCallback_());
338     auto currentPosition = scrollEdgeEffect->currentPositionCallback_();
339     EXPECT_EQ(currentPosition, 100.0);
340 
341     /**
342      * @tc.steps: step2. When direction is the default value, call the relevant callback function.
343      * @tc.expected: Check whether the return value is correct.
344      */
345     auto leading = scrollEdgeEffect->leadingCallback_();
346     auto trailing = scrollEdgeEffect->trailingCallback_();
347     auto initLeading = scrollEdgeEffect->initLeadingCallback_();
348     auto initTrailing = scrollEdgeEffect->initTrailingCallback_();
349     EXPECT_EQ(leading, -VERTICAL_SCROLLABLE_DISTANCE);
350     EXPECT_EQ(trailing, 0.0);
351     EXPECT_EQ(initLeading, -VERTICAL_SCROLLABLE_DISTANCE);
352     EXPECT_EQ(initTrailing, 0.0);
353 
354     /**
355      * @tc.steps: step3. When direction is ROW_REVERSE, call the relevant callback function.
356      * @tc.expected: Check whether the return value is correct.
357      */
358     pattern_->direction_ = FlexDirection::ROW_REVERSE;
359     leading = scrollEdgeEffect->leadingCallback_();
360     trailing = scrollEdgeEffect->trailingCallback_();
361     initLeading = scrollEdgeEffect->initLeadingCallback_();
362     initTrailing = scrollEdgeEffect->initTrailingCallback_();
363     EXPECT_EQ(leading, 0.0);
364     EXPECT_EQ(trailing, VERTICAL_SCROLLABLE_DISTANCE);
365     EXPECT_EQ(initLeading, 0.0);
366     EXPECT_EQ(initTrailing, VERTICAL_SCROLLABLE_DISTANCE);
367 
368     /**
369      * @tc.steps: step4. When direction is COLUMN_REVERSE, call the relevant callback function.
370      * @tc.expected: Check whether the return value is correct.
371      */
372     pattern_->direction_ = FlexDirection::COLUMN_REVERSE;
373     leading = scrollEdgeEffect->leadingCallback_();
374     trailing = scrollEdgeEffect->trailingCallback_();
375     initLeading = scrollEdgeEffect->initLeadingCallback_();
376     initTrailing = scrollEdgeEffect->initTrailingCallback_();
377     EXPECT_EQ(leading, 0.0);
378     EXPECT_EQ(trailing, VERTICAL_SCROLLABLE_DISTANCE);
379     EXPECT_EQ(initLeading, 0.0);
380     EXPECT_EQ(initTrailing, VERTICAL_SCROLLABLE_DISTANCE);
381 
382     /**
383      * @tc.steps: step5. When direction is the default value and scrollableDistance_ <= 0.
384      * @tc.expected: return 0.0
385      */
386     ClearOldNodes();
387     model = CreateScroll();
388     model.SetEdgeEffect(EdgeEffect::SPRING, true);
389     CreateContent(VIEW_ITEM_NUMBER);
390     CreateDone(frameNode_);
391     EXPECT_EQ(pattern_->scrollableDistance_, 0);
392     scrollEdgeEffect = pattern_->GetScrollEdgeEffect();
393     leading = scrollEdgeEffect->leadingCallback_();
394     initLeading = scrollEdgeEffect->initLeadingCallback_();
395     EXPECT_EQ(leading, 0.0);
396     EXPECT_EQ(initLeading, 0.0);
397 }
398 
399 /**
400  * @tc.name: ScrollTest004
401  * @tc.desc: When setting a fixed length and width, verify the related functions in the scroll pattern.
402  * @tc.type: FUNC
403  */
404 HWTEST_F(ScrollTestNg, ScrollTest004, TestSize.Level1)
405 {
406     /**
407      * @tc.steps: step1. Set ScrollFadeEffect and call relevant callback functions.
408      * @tc.expected: Check whether the return value is correct.
409      */
410     CreateScroll();
411     CreateContent(TOTAL_ITEM_NUMBER);
412     CreateDone(frameNode_);
413     pattern_->SetEdgeEffect(EdgeEffect::FADE);
414     RefPtr<ScrollEdgeEffect> scrollEdgeEffect = pattern_->GetScrollEdgeEffect();
415     ASSERT_NE(scrollEdgeEffect, nullptr);
416     pattern_->currentOffset_ = 100.f;
417     pattern_->scrollableDistance_ = 100.f;
418     auto scrollFade = AceType::DynamicCast<ScrollFadeEffect>(scrollEdgeEffect);
419     ASSERT_NE(scrollFade, nullptr);
420     scrollFade->handleOverScrollCallback_();
421     ASSERT_NE(scrollFade->fadeController_, nullptr);
422     pattern_->SetEdgeEffect(EdgeEffect::NONE);
423     EXPECT_EQ(pattern_->scrollEffect_, nullptr);
424 }
425 
426 /**
427  * @tc.name: UpdateCurrentOffset001
428  * @tc.desc: Test UpdateCurrentOffset that return
429  * @tc.type: FUNC
430  */
431 HWTEST_F(ScrollTestNg, UpdateCurrentOffset001, TestSize.Level1)
432 {
433     /**
434      * @tc.steps: step1. When unscrollable
435      * @tc.expected: currentOffset would not change
436      */
437     CreateScroll();
438     CreateDone(frameNode_);
439     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_HEIGHT, SCROLL_FROM_UPDATE, 0.f));
440 
441     /**
442      * @tc.steps: step2. When !HandleEdgeEffect and !IsOutOfBoundary
443      * @tc.expected: currentOffset would not change
444      */
445     ClearOldNodes();
446     CreateScroll();
447     CreateContent(TOTAL_ITEM_NUMBER);
448     CreateDone(frameNode_);
449     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_HEIGHT, SCROLL_FROM_UPDATE, 0.f));
450 
451     /**
452      * @tc.steps: step3. When !HandleEdgeEffect and IsOutOfBoundary
453      * @tc.expected: currentOffset would not change
454      */
455     ClearOldNodes();
456     CreateScroll();
457     CreateContent(TOTAL_ITEM_NUMBER);
458     CreateDone(frameNode_);
459     pattern_->currentOffset_ = 10.f;
460     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_HEIGHT, SCROLL_FROM_UPDATE, 0.f));
461 }
462 
463 /**
464  * @tc.name: UpdateCurrentOffset002
465  * @tc.desc: Test UpdateCurrentOffset
466  * @tc.type: FUNC
467  */
468 HWTEST_F(ScrollTestNg, UpdateCurrentOffset002, TestSize.Level1)
469 {
470     /**
471      * @tc.steps: step1. When Axis::VERTICAL
472      */
473     CreateScroll();
474     CreateContent(TOTAL_ITEM_NUMBER);
475     CreateDone(frameNode_);
476     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_HEIGHT, SCROLL_FROM_JUMP, ITEM_HEIGHT));
477     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_HEIGHT, SCROLL_FROM_BAR, 0.f));
478     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_HEIGHT, SCROLL_FROM_ROTATE, ITEM_HEIGHT));
479     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_HEIGHT, SCROLL_FROM_ANIMATION, 0.f));
480     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_HEIGHT, SCROLL_FROM_ANIMATION_SPRING, ITEM_HEIGHT));
481 
482     /**
483      * @tc.steps: step2. When Axis::HORIZONTAL
484      */
485     ClearOldNodes();
486     ScrollModelNG model = CreateScroll();
487     model.SetAxis(Axis::HORIZONTAL);
488     CreateContent(TOTAL_ITEM_NUMBER);
489     CreateDone(frameNode_);
490     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_WIDTH, SCROLL_FROM_JUMP, ITEM_WIDTH));
491     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_WIDTH, SCROLL_FROM_BAR, 0.f));
492     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_WIDTH, SCROLL_FROM_ROTATE, ITEM_WIDTH));
493     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_WIDTH, SCROLL_FROM_ANIMATION, 0.f));
494     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_WIDTH, SCROLL_FROM_ANIMATION_SPRING, ITEM_WIDTH));
495 
496     /**
497      * @tc.steps: step3. When Axis::HORIZONTAL and ROW_REVERSE
498      */
499     ClearOldNodes();
500     model = CreateScroll();
501     model.SetAxis(Axis::HORIZONTAL);
502     CreateContent(TOTAL_ITEM_NUMBER);
503     CreateDone(frameNode_);
504     pattern_->SetDirection(FlexDirection::ROW_REVERSE);
505     FlushLayoutTask(frameNode_, true);
506     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_WIDTH, SCROLL_FROM_JUMP, ITEM_WIDTH));
507     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_WIDTH, SCROLL_FROM_BAR, 0.f));
508     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_WIDTH, SCROLL_FROM_ROTATE, 0.f));
509     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_WIDTH, SCROLL_FROM_ANIMATION, 0.f));
510     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_WIDTH, SCROLL_FROM_ANIMATION_SPRING, 0.f));
511 
512     /**
513      * @tc.steps: step4. When EdgeEffect::SPRING, Test ValidateOffset
514      */
515     ClearOldNodes();
516     model = CreateScroll();
517     model.SetEdgeEffect(EdgeEffect::SPRING, true);
518     CreateContent(TOTAL_ITEM_NUMBER);
519     CreateDone(frameNode_);
520     EXPECT_FALSE(pattern_->IsRestrictBoundary());
521     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_HEIGHT, SCROLL_FROM_JUMP, ITEM_HEIGHT));
522     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_HEIGHT, SCROLL_FROM_BAR, 0.f));
523     EXPECT_TRUE(UpdateAndVerifyPosition(-ITEM_HEIGHT, SCROLL_FROM_BAR_FLING, ITEM_HEIGHT));
524     EXPECT_TRUE(UpdateAndVerifyPosition(ITEM_HEIGHT, SCROLL_FROM_ROTATE, 0.f));
525 
526     pattern_->currentOffset_ = -10.f;
527     pattern_->UpdateScrollBarOffset();
528     FlushLayoutTask(frameNode_);
529     EXPECT_EQ(pattern_->GetScrollBarOutBoundaryExtent(), 0);
530 
531     pattern_->currentOffset_ = -1000.f;
532     pattern_->UpdateScrollBarOffset();
533     FlushLayoutTask(frameNode_);
534     EXPECT_EQ(pattern_->GetScrollBarOutBoundaryExtent(),
535         -pattern_->currentOffset_ - (ITEM_HEIGHT * TOTAL_ITEM_NUMBER - SCROLL_HEIGHT));
536 
537     pattern_->currentOffset_ = -100.f;
538     pattern_->UpdateScrollBarOffset();
539     FlushLayoutTask(frameNode_);
540     EXPECT_EQ(pattern_->GetScrollBarOutBoundaryExtent(), 0.0f);
541 }
542 
543 /**
544  * @tc.name:  UpdateCurrentOffset003
545  * @tc.desc: Test the correlation function in ScrollFadeEffect under different conditions.
546  * @tc.type: FUNC
547  */
548 HWTEST_F(ScrollTestNg, UpdateCurrentOffset003, TestSize.Level1)
549 {
550     /**
551      * @tc.steps: step1. Create scroll model with spring edgeEffect.
552      */
553     ScrollModelNG model = CreateScroll();
554     model.SetEdgeEffect(EdgeEffect::SPRING, true);
555     CreateContent(TOTAL_ITEM_NUMBER);
556     CreateDone(frameNode_);
557     pattern_->isAnimationStop_ = false;
558 
559     /**
560      * @tc.steps: step2. Make animateCanOverScroll_ true, UpdateCurrentOffset to a position where over the boundary.
561      * @tc.expected: pattern_->isAnimateOverScroll_ can be set to true.
562      */
563     pattern_->animateCanOverScroll_ = true;
564     pattern_->isAnimateOverScroll_ = false;
565     pattern_->UpdateCurrentOffset(100, SCROLL_FROM_ANIMATION_CONTROLLER);
566     EXPECT_EQ(pattern_->isAnimateOverScroll_, true);
567 
568     /**
569      * @tc.steps: step3. Make animateCanOverScroll_ false, UpdateCurrentOffset to a position where over the boundary.
570      * @tc.expected: pattern_->isAnimateOverScroll_ can't be set to true.
571      */
572     pattern_->animateCanOverScroll_ = false;
573     pattern_->isAnimateOverScroll_ = false;
574     pattern_->UpdateCurrentOffset(100, SCROLL_FROM_ANIMATION_CONTROLLER);
575     EXPECT_EQ(pattern_->isAnimateOverScroll_, false);
576 }
577 
578 /**
579  * @tc.name: UpdateCurrentOffset004
580  * @tc.desc: Test return value of UpdateCurrentOffset.
581  * @tc.type: FUNC
582  */
583 HWTEST_F(ScrollTestNg, UpdateCurrentOffset004, TestSize.Level1)
584 {
585     /**
586      * @tc.steps: step1. Create scroll model with spring edgeEffect.
587      */
588     ScrollModelNG model = CreateScroll();
589     model.SetEdgeEffect(EdgeEffect::SPRING, true);
590     CreateContent(TOTAL_ITEM_NUMBER);
591     CreateDone(frameNode_);
592     /**
593      * @tc.steps: step2. Make animateCanOverScroll_ true, UpdateCurrentOffset to a position where over the boundary.
594      * @tc.expected: the return value of UpdateCurrentOffset is true.
595      */
596     pattern_->animateCanOverScroll_ = true;
597     EXPECT_EQ(pattern_->UpdateCurrentOffset(100, SCROLL_FROM_ANIMATION_CONTROLLER), true);
598 
599     /**
600      * @tc.steps: step3. Make animateCanOverScroll_ false, UpdateCurrentOffset to a position where over the boundary.
601      * @tc.expected: the return value of UpdateCurrentOffset is false.
602      */
603     pattern_->animateCanOverScroll_ = false;
604     EXPECT_EQ(pattern_->UpdateCurrentOffset(100, SCROLL_FROM_ANIMATION_CONTROLLER), false);
605 }
606 
607 /**
608  * @tc.name: UpdateCurrentOffset005
609  * @tc.desc: Test whether the isAnimateOverScroll_ can be set right.
610  * @tc.type: FUNC
611  */
612 HWTEST_F(ScrollTestNg, UpdateCurrentOffset005, TestSize.Level1)
613 {
614     /**
615      * @tc.steps: step1. Create scroll model with spring edgeEffect.
616      */
617     ScrollModelNG model = CreateScroll();
618     model.SetEdgeEffect(EdgeEffect::SPRING, true);
619     CreateContent(TOTAL_ITEM_NUMBER);
620     CreateDone(frameNode_);
621     pattern_->isAnimationStop_ = false;
622 
623     /**
624      * @tc.steps: step2. Make animateCanOverScroll_ true, UpdateCurrentOffset to a position where over the boundary.
625      * @tc.expected: pattern_->isAnimateOverScroll_ can be set to true.
626      */
627     pattern_->animateCanOverScroll_ = true;
628     pattern_->isAnimateOverScroll_ = false;
629     pattern_->UpdateCurrentOffset(100, SCROLL_FROM_ANIMATION_CONTROLLER);
630     EXPECT_EQ(pattern_->isAnimateOverScroll_, true);
631 
632     /**
633      * @tc.steps: step3. Make animateCanOverScroll_ false, UpdateCurrentOffset to a position where over the boundary.
634      * @tc.expected: pattern_->isAnimateOverScroll_ can't be set to true.
635      */
636     pattern_->animateCanOverScroll_ = false;
637     pattern_->isAnimateOverScroll_ = false;
638     pattern_->UpdateCurrentOffset(100, SCROLL_FROM_ANIMATION_CONTROLLER);
639     EXPECT_EQ(pattern_->isAnimateOverScroll_, false);
640 }
641 
642 /**
643  * @tc.name: UpdateCurrentOffset006
644  * @tc.desc: Test return value of UpdateCurrentOffset.
645  * @tc.type: FUNC
646  */
647 HWTEST_F(ScrollTestNg, UpdateCurrentOffset006, TestSize.Level1)
648 {
649     /**
650      * @tc.steps: step1. Create scroll model with spring edgeEffect.
651      */
652     ScrollModelNG model = CreateScroll();
653     model.SetEdgeEffect(EdgeEffect::SPRING, true);
654     CreateContent(TOTAL_ITEM_NUMBER);
655     CreateDone(frameNode_);
656     /**
657      * @tc.steps: step2. Make animateCanOverScroll_ true, UpdateCurrentOffset to a position where over the boundary.
658      * @tc.expected: the return value of UpdateCurrentOffset is true.
659      */
660     pattern_->animateCanOverScroll_ = true;
661     EXPECT_EQ(pattern_->UpdateCurrentOffset(100, SCROLL_FROM_ANIMATION_CONTROLLER), true);
662 
663     /**
664      * @tc.steps: step3. Make animateCanOverScroll_ false, UpdateCurrentOffset to a position where over the boundary.
665      * @tc.expected: the return value of UpdateCurrentOffset is false.
666      */
667     pattern_->animateCanOverScroll_ = false;
668     EXPECT_EQ(pattern_->UpdateCurrentOffset(100, SCROLL_FROM_ANIMATION_CONTROLLER), false);
669 }
670 
671 /**
672  * @tc.name: Measure001
673  * @tc.desc: Test Measure
674  * @tc.type: FUNC
675  */
676 HWTEST_F(ScrollTestNg, Measure001, TestSize.Level1)
677 {
678     ScrollModelNG model;
679     model.Create();
680     model.SetAxis(Axis::NONE);
681     GetScroll();
682     CreateContent(TOTAL_ITEM_NUMBER);
683 
684     /**
685      * @tc.steps: step1. Do not set idealSize
686      * @tc.expected: The idealSize would be child size
687      */
688     RefPtr<LayoutWrapperNode> layoutWrapper = frameNode_->CreateLayoutWrapper(false, false);
689     layoutWrapper->SetActive();
690     layoutWrapper->SetRootMeasureNode();
691     LayoutConstraintF LayoutConstraint;
692     LayoutConstraint.parentIdealSize = { SCROLL_WIDTH, SCROLL_HEIGHT };
693     LayoutConstraint.percentReference = { SCROLL_WIDTH, SCROLL_HEIGHT };
694     layoutWrapper->Measure(LayoutConstraint);
695     layoutWrapper->Layout();
696     layoutWrapper->MountToHostOnMainThread();
697     auto scrollSize = frameNode_->GetGeometryNode()->GetFrameSize();
698     auto expectSize = SizeF(SCROLL_WIDTH, ITEM_HEIGHT * TOTAL_ITEM_NUMBER);
699     EXPECT_EQ(scrollSize, expectSize) << "scrollSize: " << scrollSize.ToString()
700                                       << " expectSize: " << expectSize.ToString();
701 }
702 
703 namespace {
704 constexpr float SCROLL_FIXED_VELOCITY = 200.f;
705 constexpr float OFFSET_TIME = 100.f;
706 constexpr int32_t TIME_CHANGED_COUNTS = 20;
707 } // namespace
708 /**
709  * @tc.name: ScrollPositionController004
710  * @tc.desc: Test ScrollPositionController with Axis::VERTICAL
711  * @tc.type: FUNC
712  */
713 HWTEST_F(ScrollTestNg, ScrollPositionController004, TestSize.Level1)
714 {
715     ScrollModelNG model = CreateScroll();
716     model.SetAxis(Axis::VERTICAL);
717     CreateContent(TOTAL_ITEM_NUMBER);
718     CreateDone(frameNode_);
719     auto controller = pattern_->GetScrollPositionController();
720     controller->ScrollToEdge(ScrollEdgeType::SCROLL_LEFT, SCROLL_FIXED_VELOCITY);
721     EXPECT_FALSE(pattern_->fixedVelocityMotion_);
722     controller->ScrollToEdge(ScrollEdgeType::SCROLL_RIGHT, SCROLL_FIXED_VELOCITY);
723     EXPECT_FALSE(pattern_->fixedVelocityMotion_);
724     controller->ScrollToEdge(ScrollEdgeType::SCROLL_BOTTOM, SCROLL_FIXED_VELOCITY);
725     EXPECT_TRUE(pattern_->fixedVelocityMotion_);
726     EXPECT_EQ(pattern_->fixedVelocityMotion_->GetCurrentVelocity(), -SCROLL_FIXED_VELOCITY);
727     int32_t offsetTime = OFFSET_TIME;
728     for (int i = 0; i < TIME_CHANGED_COUNTS; i++) {
729         pattern_->fixedVelocityMotion_->OnTimestampChanged(offsetTime, 0.0f, false);
730         offsetTime = offsetTime + OFFSET_TIME;
731         FlushLayoutTask(frameNode_);
732     }
733     EXPECT_TRUE(pattern_->IsAtBottom());
734     controller->ScrollToEdge(ScrollEdgeType::SCROLL_TOP, SCROLL_FIXED_VELOCITY);
735     EXPECT_TRUE(pattern_->fixedVelocityMotion_);
736     EXPECT_EQ(pattern_->fixedVelocityMotion_->GetCurrentVelocity(), SCROLL_FIXED_VELOCITY);
737     offsetTime = OFFSET_TIME;
738     for (int i = 0; i < TIME_CHANGED_COUNTS; i++) {
739         pattern_->fixedVelocityMotion_->OnTimestampChanged(offsetTime, 0.0f, false);
740         offsetTime = offsetTime + OFFSET_TIME;
741         FlushLayoutTask(frameNode_);
742     }
743     EXPECT_TRUE(pattern_->IsAtTop());
744 }
745 
746 /**
747  * @tc.name: Layout001
748  * @tc.desc: Test Layout
749  * @tc.type: FUNC
750  */
751 HWTEST_F(ScrollTestNg, Layout001, TestSize.Level1)
752 {
753     ScrollModelNG model = CreateScroll();
754     model.SetAxis(Axis::NONE);
755     CreateContent(TOTAL_ITEM_NUMBER);
756     CreateDone(frameNode_);
757     layoutProperty_->UpdateAlignment(Alignment::CENTER);
758     FlushLayoutTask(frameNode_);
759     auto col = frameNode_->GetChildAtIndex(0);
760     auto colNode = AceType::DynamicCast<FrameNode>(col);
761     auto colOffset = colNode->GetGeometryNode()->GetMarginFrameOffset();
762     auto expectOffset = OffsetF(0, 0);
763     EXPECT_EQ(colOffset, expectOffset) << "colOffset: " << colOffset.ToString()
764                                        << " expectOffset: " << expectOffset.ToString();
765 }
766 
767 /**
768  * @tc.name: ScrollToNode001
769  * @tc.desc: Test ScrollToNode
770  * @tc.type: FUNC
771  */
772 HWTEST_F(ScrollTestNg, ScrollToNode001, TestSize.Level1)
773 {
774     /**
775      * @tc.steps: step1. ScrollToNode in VERTICAL
776      * @tc.expected: currentOffset_ is correct
777      */
778     CreateScroll();
779     CreateContent(TOTAL_ITEM_NUMBER);
780     CreateDone(frameNode_);
781     EXPECT_TRUE(ScrollToNode(5, 0.f));
782     EXPECT_TRUE(ScrollToNode(8, ITEM_HEIGHT * 1));
783     EXPECT_TRUE(ScrollToNode(9, ITEM_HEIGHT * 2));
784     EXPECT_TRUE(ScrollToNode(5, ITEM_HEIGHT * 2));
785     EXPECT_TRUE(ScrollToNode(0, 0.f));
786 
787     /**
788      * @tc.steps: step2. ScrollToNode in HORIZONTAL
789      * @tc.expected: currentOffset_ is correct
790      */
791     ClearOldNodes();
792     ScrollModelNG model = CreateScroll();
793     model.SetAxis(Axis::HORIZONTAL);
794     CreateContent(TOTAL_ITEM_NUMBER);
795     CreateDone(frameNode_);
796     EXPECT_TRUE(ScrollToNode(5, 0.f));
797     EXPECT_TRUE(ScrollToNode(8, ITEM_WIDTH * 1));
798     EXPECT_TRUE(ScrollToNode(9, ITEM_WIDTH * 2));
799     EXPECT_TRUE(ScrollToNode(5, ITEM_WIDTH * 2));
800     EXPECT_TRUE(ScrollToNode(0, 0.f));
801 
802     /**
803      * @tc.steps: step1. ScrollToNode itSelf
804      * @tc.expected: currentOffset_ is zero
805      */
806     ClearOldNodes();
807     CreateScroll();
808     CreateContent(TOTAL_ITEM_NUMBER);
809     CreateDone(frameNode_);
810     pattern_->ScrollToNode(frameNode_);
811     EXPECT_TRUE(IsEqualCurrentPosition(0));
812     pattern_->ScrollToNode(GetChildFrameNode(frameNode_, 0));
813     EXPECT_TRUE(IsEqualCurrentPosition(0));
814 }
815 
816 /**
817  * @tc.name: ScrollToNode002
818  * @tc.desc: Test ScrollToNode when animate is running, can not scroll
819  * @tc.type: FUNC
820  */
821 HWTEST_F(ScrollTestNg, ScrollToNode002, TestSize.Level1)
822 {
823     /**
824      * @tc.steps: step1. Play animate
825      * @tc.expected: ScrollToNode can not scroll
826      */
827     CreateScroll();
828     CreateContent(TOTAL_ITEM_NUMBER);
829     CreateDone(frameNode_);
830     pattern_->isAnimationStop_ = false;
831     EXPECT_FALSE(pattern_->AnimateStoped());
832     EXPECT_TRUE(ScrollToNode(8, 0.f));
833 }
834 
835 /**
836  * @tc.name: Pattern003
837  * @tc.desc: Test HandleScrollBarOutBoundary
838  * @tc.type: FUNC
839  */
840 HWTEST_F(ScrollTestNg, Pattern003, TestSize.Level1)
841 {
842     CreateScroll();
843     CreateContent(TOTAL_ITEM_NUMBER);
844     CreateDone(frameNode_);
845 
846     /**
847      * @tc.steps: step1. When scrollBar is not OFF
848      * @tc.expected: outBoundary_ would be set
849      */
850     pattern_->HandleScrollBarOutBoundary(100.f);
851     auto scrollBar = pattern_->GetScrollBar();
852     EXPECT_EQ(scrollBar->outBoundary_, 100.f);
853 
854     /**
855      * @tc.steps: step1. When scrollBar is OFF
856      * @tc.expected: outBoundary_ would not be set
857      */
858     scrollBar->displayMode_ = DisplayMode::OFF;
859     pattern_->HandleScrollBarOutBoundary(200.f);
860     EXPECT_EQ(scrollBar->outBoundary_, 100.f);
861 }
862 
863 /**
864  * @tc.name: Test001
865  * @tc.desc: Test GetOverScrollOffset
866  * @tc.type: FUNC
867  */
868 HWTEST_F(ScrollTestNg, Test001, TestSize.Level1)
869 {
870     CreateScroll();
871     CreateContent(TOTAL_ITEM_NUMBER);
872     CreateDone(frameNode_);
873 
874     OverScrollOffset offset = pattern_->GetOverScrollOffset(ITEM_HEIGHT);
875     OverScrollOffset expectOffset = { ITEM_HEIGHT, 0 };
876     EXPECT_TRUE(IsEqual(offset, expectOffset));
877     offset = pattern_->GetOverScrollOffset(0.f);
878     expectOffset = { 0, 0 };
879     EXPECT_TRUE(IsEqual(offset, expectOffset));
880     offset = pattern_->GetOverScrollOffset(-ITEM_HEIGHT);
881     expectOffset = { 0, 0 };
882     EXPECT_TRUE(IsEqual(offset, expectOffset));
883 
884     pattern_->currentOffset_ = -ITEM_HEIGHT;
885     offset = pattern_->GetOverScrollOffset(ITEM_HEIGHT * 2);
886     expectOffset = { ITEM_HEIGHT, 0 };
887     EXPECT_TRUE(IsEqual(offset, expectOffset));
888     offset = pattern_->GetOverScrollOffset(0.f);
889     expectOffset = { 0, 0 };
890     EXPECT_TRUE(IsEqual(offset, expectOffset));
891     offset = pattern_->GetOverScrollOffset(-ITEM_HEIGHT * 2);
892     expectOffset = { 0, -ITEM_HEIGHT };
893     EXPECT_TRUE(IsEqual(offset, expectOffset));
894 
895     pattern_->currentOffset_ = -ITEM_HEIGHT * 2;
896     offset = pattern_->GetOverScrollOffset(ITEM_HEIGHT);
897     expectOffset = { 0, 0 };
898     EXPECT_TRUE(IsEqual(offset, expectOffset));
899     offset = pattern_->GetOverScrollOffset(0.f);
900     expectOffset = { 0, 0 };
901     EXPECT_TRUE(IsEqual(offset, expectOffset));
902     offset = pattern_->GetOverScrollOffset(-ITEM_HEIGHT);
903     expectOffset = { 0, -ITEM_HEIGHT };
904     EXPECT_TRUE(IsEqual(offset, expectOffset));
905 
906     pattern_->currentOffset_ = ITEM_HEIGHT;
907     offset = pattern_->GetOverScrollOffset(ITEM_HEIGHT);
908     expectOffset = { ITEM_HEIGHT, 0 };
909     EXPECT_TRUE(IsEqual(offset, expectOffset));
910     offset = pattern_->GetOverScrollOffset(0.f);
911     expectOffset = { 0, 0 };
912     EXPECT_TRUE(IsEqual(offset, expectOffset));
913     offset = pattern_->GetOverScrollOffset(-ITEM_HEIGHT * 2);
914     expectOffset = { -ITEM_HEIGHT, 0 };
915     EXPECT_TRUE(IsEqual(offset, expectOffset));
916 
917     pattern_->currentOffset_ = -ITEM_HEIGHT * 3;
918     offset = pattern_->GetOverScrollOffset(ITEM_HEIGHT * 2);
919     expectOffset = { 0, ITEM_HEIGHT };
920     EXPECT_TRUE(IsEqual(offset, expectOffset));
921     offset = pattern_->GetOverScrollOffset(0.f);
922     expectOffset = { 0, 0 };
923     EXPECT_TRUE(IsEqual(offset, expectOffset));
924     offset = pattern_->GetOverScrollOffset(-ITEM_HEIGHT);
925     expectOffset = { 0, -ITEM_HEIGHT };
926     EXPECT_TRUE(IsEqual(offset, expectOffset));
927 }
928 
929 /**
930  * @tc.name: AccessibilityProperty001
931  * @tc.desc: Test AccessibilityProperty
932  * @tc.type: FUNC
933  */
934 HWTEST_F(ScrollTestNg, AccessibilityProperty001, TestSize.Level1)
935 {
936     /**
937      * @tc.steps: step1. Create unscrollable scroll, test SetSpecificSupportAction
938      * @tc.expected: action is correct
939      */
940     CreateScroll();
941     CreateDone(frameNode_);
942     accessibilityProperty_->ResetSupportAction();
943     EXPECT_EQ(GetActions(accessibilityProperty_), 0);
944 
945     /**
946      * @tc.steps: step2. scroll is at top
947      * @tc.expected: action is correct
948      */
949     ClearOldNodes();
950     CreateScroll();
951     CreateContent(TOTAL_ITEM_NUMBER);
952     CreateDone(frameNode_);
953     accessibilityProperty_->ResetSupportAction();
954     uint64_t expectActions = 0;
955     expectActions |= 1UL << static_cast<uint32_t>(AceAction::ACTION_SCROLL_FORWARD);
956     EXPECT_EQ(GetActions(accessibilityProperty_), expectActions);
957 
958     /**
959      * @tc.steps: step3. scroll to middle
960      * @tc.expected: action is correct
961      */
962     ScrollTo(ITEM_HEIGHT * 1);
963     accessibilityProperty_->ResetSupportAction();
964     expectActions = 0;
965     expectActions |= 1UL << static_cast<uint32_t>(AceAction::ACTION_SCROLL_FORWARD);
966     expectActions |= 1UL << static_cast<uint32_t>(AceAction::ACTION_SCROLL_BACKWARD);
967     EXPECT_EQ(GetActions(accessibilityProperty_), expectActions);
968 
969     /**
970      * @tc.steps: step4. scroll to bottom
971      * @tc.expected: action is correct
972      */
973     ScrollTo(ITEM_HEIGHT * 2);
974     accessibilityProperty_->ResetSupportAction();
975     expectActions = 0;
976     expectActions |= 1UL << static_cast<uint32_t>(AceAction::ACTION_SCROLL_BACKWARD);
977     EXPECT_EQ(GetActions(accessibilityProperty_), expectActions);
978 
979     /**
980      * @tc.steps: step6. test IsScrollable()
981      * @tc.expected: return value is correct
982      */
983     ClearOldNodes();
984     CreateScroll();
985     CreateContent(TOTAL_ITEM_NUMBER);
986     CreateDone(frameNode_);
987     EXPECT_TRUE(accessibilityProperty_->IsScrollable());
988     ClearOldNodes();
989     ScrollModelNG model = CreateScroll();
990     model.SetAxis(Axis::NONE);
991     CreateContent(TOTAL_ITEM_NUMBER);
992     CreateDone(frameNode_);
993     EXPECT_FALSE(accessibilityProperty_->IsScrollable());
994 }
995 
996 /**
997  * @tc.name: OnModifyDone001
998  * @tc.desc: Test OnModifyDone
999  * @tc.type: FUNC
1000  */
1001 HWTEST_F(ScrollTestNg, OnModifyDone001, TestSize.Level1)
1002 {
1003     /**
1004      * @tc.steps: step1. Create to trigger OnModifyDone
1005      * @tc.expected: Has ScrollableEvent, has AccessibilityAction, set Axis::VERTICAL
1006      */
1007     CreateScroll();
1008     CreateContent(TOTAL_ITEM_NUMBER);
1009     CreateDone(frameNode_);
1010     ASSERT_NE(pattern_->GetScrollableEvent(), nullptr);
1011     ASSERT_NE(accessibilityProperty_->actionScrollForwardWithParamImpl_, nullptr);
1012     ASSERT_NE(accessibilityProperty_->actionScrollBackwardWithParamImpl_, nullptr);
1013     EXPECT_EQ(pattern_->GetAxis(), Axis::VERTICAL);
1014 
1015     /**
1016      * @tc.steps: step2. Change axis and trigger OnModifyDone
1017      * @tc.expected: Axis would be changed
1018      */
1019     layoutProperty_->UpdateAxis(Axis::HORIZONTAL);
1020     pattern_->OnModifyDone();
1021     EXPECT_EQ(pattern_->GetAxis(), Axis::HORIZONTAL);
1022 
1023     /**
1024      * @tc.steps: step3. Change scrollSnapUpdate_ to true
1025      * @tc.expected: Will MarkDirtyNode
1026      */
1027     pattern_->scrollSnapUpdate_ = true;
1028     pattern_->OnModifyDone();
1029 }
1030 
1031 /**
1032  * @tc.name: Pattern002
1033  * @tc.desc: Test SetAccessibilityAction
1034  * @tc.type: FUNC
1035  */
1036 HWTEST_F(ScrollTestNg, Pattern002, TestSize.Level1)
1037 {
1038     /**
1039      * @tc.steps: step1. Test SetAccessibilityAction with scrollable scroll
1040      * @tc.expected: Can trigger AnimateTo()
1041      */
1042     CreateScroll();
1043     CreateContent(TOTAL_ITEM_NUMBER);
1044     CreateDone(frameNode_);
1045     accessibilityProperty_->actionScrollForwardWithParamImpl_(AccessibilityScrollType::SCROLL_FULL);
1046     ASSERT_NE(pattern_->springAnimation_, nullptr);
1047     pattern_->springAnimation_ = nullptr;
1048     accessibilityProperty_->actionScrollBackwardWithParamImpl_(AccessibilityScrollType::SCROLL_FULL);
1049     ASSERT_NE(pattern_->springAnimation_, nullptr);
1050 
1051     /**
1052      * @tc.steps: step2. Test SetAccessibilityAction with unScrollable scroll, scrollableDistance_ <= 0
1053      * @tc.expected: Cannot trigger AnimateTo()
1054      */
1055     CreateScroll();
1056     CreateDone(frameNode_);
1057     accessibilityProperty_->actionScrollForwardWithParamImpl_(AccessibilityScrollType::SCROLL_FULL);
1058     EXPECT_EQ(pattern_->animator_, nullptr);
1059     accessibilityProperty_->actionScrollBackwardWithParamImpl_(AccessibilityScrollType::SCROLL_FULL);
1060     EXPECT_EQ(pattern_->animator_, nullptr);
1061 
1062     /**
1063      * @tc.steps: step3. Test SetAccessibilityAction with unScrollable scroll, Axis::NONE
1064      * @tc.expected: Cannot trigger AnimateTo()
1065      */
1066     ClearOldNodes();
1067     ScrollModelNG model = CreateScroll();
1068     model.SetAxis(Axis::NONE);
1069     CreateContent(TOTAL_ITEM_NUMBER);
1070     CreateDone(frameNode_);
1071     accessibilityProperty_->actionScrollForwardWithParamImpl_(AccessibilityScrollType::SCROLL_FULL);
1072     EXPECT_EQ(pattern_->animator_, nullptr);
1073     accessibilityProperty_->actionScrollBackwardWithParamImpl_(AccessibilityScrollType::SCROLL_FULL);
1074     EXPECT_EQ(pattern_->animator_, nullptr);
1075 }
1076 
1077 /**
1078  * @tc.name: ScrollTest005
1079  * @tc.desc: Scroll Accessibility PerformAction test ScrollForward and ScrollBackward..
1080  * @tc.type: FUNC
1081  */
1082 HWTEST_F(ScrollTestNg, ScrollTest005, TestSize.Level1)
1083 {
1084     /**
1085      * @tc.steps: step1. Create scroll and initialize related properties.
1086      */
1087     ScrollModelNG model = CreateScroll();
1088     model.SetAxis(Axis::NONE);
1089     CreateContent(TOTAL_ITEM_NUMBER);
1090     CreateDone(frameNode_);
1091 
1092     /**
1093      * @tc.steps: step2. Get scroll frameNode and pattern, set callback function.
1094      * @tc.expected: Related function is called.
1095      */
1096     pattern_->scrollableDistance_ = 0.0;
1097     pattern_->SetAccessibilityAction();
1098 
1099     /**
1100      * @tc.steps: step4. When scroll is not scrollable and scrollable distance is 0, call the callback function in
1101      *                   accessibilityProperty_.
1102      * @tc.expected: Related function is called.
1103      */
1104     EXPECT_TRUE(accessibilityProperty_->ActActionScrollForward());
1105     EXPECT_TRUE(accessibilityProperty_->ActActionScrollBackward());
1106 
1107     /**
1108      * @tc.steps: step5. When scroll is not scrollable and scrollable distance is not 0, call the callback function in
1109      *                   accessibilityProperty_.
1110      * @tc.expected: Related function is called.
1111      */
1112     pattern_->scrollableDistance_ = 100.f;
1113     EXPECT_TRUE(accessibilityProperty_->ActActionScrollForward());
1114     EXPECT_TRUE(accessibilityProperty_->ActActionScrollBackward());
1115 
1116     /**
1117      * @tc.steps: step6. When scroll is scrollable and scrollable distance is not 0, call the callback function in
1118      *                   accessibilityProperty_.
1119      * @tc.expected: Related function is called.
1120      */
1121     pattern_->SetAxis(Axis::VERTICAL);
1122     EXPECT_TRUE(accessibilityProperty_->ActActionScrollForward());
1123     EXPECT_TRUE(accessibilityProperty_->ActActionScrollBackward());
1124 
1125     /**
1126      * @tc.steps: step7. When scroll is scrollable and scrollable distance is 0, call the callback function in
1127      *                   accessibilityProperty_.
1128      * @tc.expected: Related function is called.
1129      */
1130     pattern_->scrollableDistance_ = 0.0;
1131     EXPECT_TRUE(accessibilityProperty_->ActActionScrollForward());
1132     EXPECT_TRUE(accessibilityProperty_->ActActionScrollBackward());
1133 }
1134 
1135 /**
1136  * @tc.name: ScrollSetFrictionTest001
1137  * @tc.desc: Test SetFriction
1138  * @tc.type: FUNC
1139  */
1140 HWTEST_F(ScrollTestNg, ScrollSetFrictionTest001, TestSize.Level1)
1141 {
1142     /**
1143      * @tc.steps: step1. set friction less than 0
1144      * @tc.expected: should be more than 0.0,if out of range,should be default value.
1145      */
1146     auto pipelineContext = PipelineContext::GetCurrentContext();
1147     pipelineContext->SetMinPlatformVersion(static_cast<int32_t>(PlatformVersion::VERSION_ELEVEN));
1148     double friction = -1;
1149     ScrollModelNG model = CreateScroll();
1150     model.SetFriction(friction);
1151     CreateDone(frameNode_);
1152     EXPECT_DOUBLE_EQ(pattern_->GetFriction(), DEFAULT_FRICTION);
1153 
1154     /**
1155      * @tc.steps: step1. set friction more than 0
1156      * @tc.expected: friction should be more than 0.0,if out of range,should be default value.
1157      */
1158     friction = 10;
1159     ClearOldNodes();
1160     model = CreateScroll();
1161     model.SetFriction(friction);
1162     CreateDone(frameNode_);
1163     EXPECT_DOUBLE_EQ(pattern_->GetFriction(), friction);
1164 }
1165 
1166 /**
1167  * @tc.name: Snap001
1168  * @tc.desc: Test snap
1169  * @tc.type: FUNC
1170  */
1171 HWTEST_F(ScrollTestNg, Snap001, TestSize.Level1)
1172 {
1173     Dimension intervalSize = Dimension(10.f);
1174     std::vector<Dimension> snapPaginations = {
1175         Dimension(10.f),
1176         Dimension(20.f),
1177         Dimension(30.f),
1178     };
1179 
1180     // snapOffsets_: { 0.f, -10.f, -20.f, -30.f, -2200.f }
1181     std::pair<bool, bool> enableSnapToSide = { false, false };
1182     CreateSnapScroll(ScrollSnapAlign::START, intervalSize, snapPaginations, enableSnapToSide);
1183     EXPECT_FALSE(pattern_->CalePredictSnapOffset(0.f).has_value());
1184     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-20.f).has_value());
1185     pattern_->currentOffset_ = -20.f;
1186     EXPECT_TRUE(pattern_->CalePredictSnapOffset(0.f).has_value());
1187 
1188     pattern_->currentOffset_ = -10.f;
1189     EXPECT_TRUE(pattern_->NeedScrollSnapToSide(-10.f));
1190     EXPECT_FALSE(pattern_->NeedScrollSnapToSide(10.f));
1191     pattern_->currentOffset_ = -20.f;
1192     EXPECT_FALSE(pattern_->NeedScrollSnapToSide(0.f));
1193 
1194     enableSnapToSide = { true, false };
1195     ClearOldNodes();
1196     CreateSnapScroll(ScrollSnapAlign::START, intervalSize, snapPaginations, enableSnapToSide);
1197     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-40.f).has_value());
1198     pattern_->currentOffset_ = 20.f;
1199     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-40.f).has_value());
1200     EXPECT_FALSE(pattern_->CalePredictSnapOffset(0.f).has_value());
1201 
1202     pattern_->currentOffset_ = -30.f;
1203     EXPECT_TRUE(pattern_->NeedScrollSnapToSide(10.f));
1204     EXPECT_FALSE(pattern_->NeedScrollSnapToSide(-10.f));
1205     pattern_->currentOffset_ = -20.f;
1206     EXPECT_FALSE(pattern_->NeedScrollSnapToSide(0.f));
1207 
1208     // snapOffsets_: { 0.f, -10.f, -20.f, -30.f, -40.f, ... , -180.f, -190.f, -200.f }
1209     snapPaginations = {};
1210     ClearOldNodes();
1211     CreateSnapScroll(ScrollSnapAlign::START, intervalSize, snapPaginations, enableSnapToSide);
1212     EXPECT_FALSE(pattern_->CalePredictSnapOffset(10.f).has_value());
1213     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-(SNAP_SCROLLABLE_DISTANCE + 10.f)).has_value());
1214     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-2.f).has_value());
1215     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-158.f).has_value());
1216     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-10.f).has_value());
1217 }
1218 
1219 /**
1220  * @tc.name: Snap002
1221  * @tc.desc: Test snap
1222  * @tc.type: FUNC
1223  */
1224 HWTEST_F(ScrollTestNg, Snap002, TestSize.Level1)
1225 {
1226     Dimension intervalSize = Dimension(10.f / SCROLL_HEIGHT, DimensionUnit::PERCENT);
1227     std::vector<Dimension> snapPaginations = {
1228         Dimension(0.f, DimensionUnit::PERCENT),
1229         Dimension(10.f / SCROLL_HEIGHT, DimensionUnit::PERCENT),
1230         Dimension(20.f / SCROLL_HEIGHT, DimensionUnit::PERCENT),
1231         Dimension(30.f / SCROLL_HEIGHT, DimensionUnit::PERCENT),
1232         Dimension((VERTICAL_SCROLLABLE_DISTANCE + 10.f) / SCROLL_HEIGHT, DimensionUnit::PERCENT),
1233     };
1234 
1235     // snapOffsets_: { 0.f, -1205.f, -2200.f }
1236     std::pair<bool, bool> enableSnapToSide = { false, false };
1237     CreateSnapScroll(ScrollSnapAlign::CENTER, intervalSize, snapPaginations, enableSnapToSide);
1238     EXPECT_FALSE(pattern_->CalePredictSnapOffset(0.f).has_value());
1239     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-20.f).has_value());
1240     pattern_->currentOffset_ = -20.f;
1241     EXPECT_FALSE(pattern_->CalePredictSnapOffset(0.f).has_value());
1242 
1243     enableSnapToSide = { true, false };
1244     ClearOldNodes();
1245     CreateSnapScroll(ScrollSnapAlign::CENTER, intervalSize, snapPaginations, enableSnapToSide);
1246     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-40.f).has_value());
1247     pattern_->currentOffset_ = -1200.f;
1248     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-40.f).has_value());
1249     EXPECT_TRUE(pattern_->CalePredictSnapOffset(0.f).has_value());
1250     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(0.f).value(), -5.f);
1251 
1252     // snapOffsets_: { 0.f, -5.f, -15.f, -25.f, -35.f, ... , -2185.f, -2195.f }
1253     snapPaginations = {};
1254     ClearOldNodes();
1255     CreateSnapScroll(ScrollSnapAlign::CENTER, intervalSize, snapPaginations, enableSnapToSide);
1256     EXPECT_FALSE(pattern_->CalePredictSnapOffset(10.f).has_value());
1257     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-(SNAP_SCROLLABLE_DISTANCE + 10.f)).has_value());
1258     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-2.f).has_value());
1259     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-158.f).has_value());
1260     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-10.f).has_value());
1261 }
1262 
1263 /**
1264  * @tc.name: Snap003
1265  * @tc.desc: Test snap
1266  * @tc.type: FUNC
1267  */
1268 HWTEST_F(ScrollTestNg, Snap003, TestSize.Level1)
1269 {
1270     Dimension intervalSize = Dimension(10.f);
1271     std::vector<Dimension> snapPaginations = {
1272         Dimension(10.f),
1273         Dimension(20.f),
1274         Dimension(30.f),
1275     };
1276 
1277     // snapOffsets_: { 0.f, -2200.f }
1278     std::pair<bool, bool> enableSnapToSide = { false, false };
1279     CreateSnapScroll(ScrollSnapAlign::END, intervalSize, snapPaginations, enableSnapToSide);
1280     EXPECT_FALSE(pattern_->CalePredictSnapOffset(0.f).has_value());
1281     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-20.f).has_value());
1282     pattern_->currentOffset_ = -20.f;
1283     EXPECT_FALSE(pattern_->CalePredictSnapOffset(0.f).has_value());
1284 
1285     enableSnapToSide = { true, false };
1286     ClearOldNodes();
1287     CreateSnapScroll(ScrollSnapAlign::END, intervalSize, snapPaginations, enableSnapToSide);
1288     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-40.f).has_value());
1289     pattern_->currentOffset_ = 20.f;
1290     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-40.f).has_value());
1291     EXPECT_FALSE(pattern_->CalePredictSnapOffset(0.f).has_value());
1292 
1293     // snapOffsets_: { 0.f, -10.f, -20.f, -30.f, -40.f, ... , -180.f, -190.f, -200.f }
1294     snapPaginations = {};
1295     ClearOldNodes();
1296     CreateSnapScroll(ScrollSnapAlign::END, intervalSize, snapPaginations, enableSnapToSide);
1297     EXPECT_FALSE(pattern_->CalePredictSnapOffset(10.f).has_value());
1298     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-(SNAP_SCROLLABLE_DISTANCE + 10.f)).has_value());
1299     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-2.f).has_value());
1300     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-158.f).has_value());
1301     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-10.f).has_value());
1302 }
1303 
1304 /**
1305  * @tc.name: CaleSnapOffsetsByPaginations001
1306  * @tc.desc: Test CaleSnapOffsetsByPaginations where the page size is lesser than the scroll size.
1307  * @tc.type: FUNC
1308  */
1309 HWTEST_F(ScrollTestNg, CaleSnapOffsetsByPaginations001, TestSize.Level1)
1310 {
1311     /**
1312      * @tc.steps: step1. Init snapPaginations.
1313      */
1314     Dimension intervalSize = Dimension(0.f);
1315     std::vector<Dimension> snapPaginations = {
1316         Dimension(400.f),
1317         Dimension(800.f),
1318         Dimension(1400.f),
1319         Dimension(1600.f),
1320         Dimension(2200.f),
1321     };
1322 
1323     /**
1324      * @tc.steps: step2. EnableSnapToSide is { true, true } and SnapAlign is ScrollSnapAlign::START.
1325      * @tc.expected: SnapOffsets is correct.
1326      */
1327     // snapPaginations: { 400.f, 800.f, 1400.f, 1600.f, 2200.f }
1328     std::pair<bool, bool> enableSnapToSide = { true, true };
1329     CreateSnapScroll(ScrollSnapAlign::START, intervalSize, snapPaginations, enableSnapToSide);
1330     pattern_->CaleSnapOffsets();
1331     auto snapOffsets = pattern_->GetSnapOffsets();
1332     std::vector<float> testSnapOffsets = { 0.f, -400.f, -800.f, -1400.f, -1600.f, -2200.f };
1333     EXPECT_TRUE(snapOffsets == testSnapOffsets);
1334     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-200.f).has_value());
1335     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-200.f).value(), -400.f);
1336     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-2000.f).has_value());
1337     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-2000.f).value(), -2200.f);
1338 
1339     /**
1340      * @tc.steps: step3. EnableSnapToSide is { false, false }.
1341      * @tc.expected: SnapOffsets is correct.
1342      */
1343     pattern_->SetEnableSnapToSide({ false, false });
1344     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-200.f).has_value());
1345     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-2000.f).has_value());
1346 
1347     /**
1348      * @tc.steps: step4. EnableSnapToSide is { true, true } and SnapAlign is ScrollSnapAlign::CENTER.
1349      * @tc.expected: SnapOffsets is correct.
1350      */
1351     auto host = pattern_->GetHost();
1352     ASSERT_NE(host, nullptr);
1353     pattern_->SetEnableSnapToSide({ true, true });
1354     ACE_UPDATE_NODE_LAYOUT_PROPERTY(ScrollLayoutProperty, ScrollSnapAlign, ScrollSnapAlign::CENTER, host);
1355     pattern_->CaleSnapOffsets();
1356     snapOffsets = pattern_->GetSnapOffsets();
1357     testSnapOffsets = { 0.f, -200.f, -700.f, -1100.f, -1500.f, -2200.f };
1358     EXPECT_TRUE(snapOffsets == testSnapOffsets);
1359     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-99.f).has_value());
1360     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-99.f).value(), 0.f);
1361     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-1700.f).has_value());
1362     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-1700.f).value(), -1500.f);
1363 
1364     /**
1365      * @tc.steps: step5. EnableSnapToSide is { false, false }.
1366      * @tc.expected: SnapOffsets is correct.
1367      */
1368     pattern_->SetEnableSnapToSide({ false, false });
1369     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-99.f).has_value());
1370     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-1700.f).has_value());
1371 
1372     /**
1373      * @tc.steps: step6. EnableSnapToSide is { true, true } and SnapAlign is ScrollSnapAlign::END.
1374      * @tc.expected: SnapOffsets is correct.
1375      */
1376     pattern_->SetEnableSnapToSide({ true, true });
1377     ACE_UPDATE_NODE_LAYOUT_PROPERTY(ScrollLayoutProperty, ScrollSnapAlign, ScrollSnapAlign::END, host);
1378     pattern_->CaleSnapOffsets();
1379     snapOffsets = pattern_->GetSnapOffsets();
1380     testSnapOffsets = { 0.f, -600.f, -800.f, -1400.f, -2200.f };
1381     EXPECT_TRUE(snapOffsets == testSnapOffsets);
1382     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-300.f).has_value());
1383     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-300.f).value(), -600.f);
1384     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-1799.f).has_value());
1385     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-1799.f).value(), -1400.f);
1386 
1387     /**
1388      * @tc.steps: step7. EnableSnapToSide is { false, false }.
1389      * @tc.expected: SnapOffsets is correct.
1390      */
1391     pattern_->SetEnableSnapToSide({ false, false });
1392     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-300.f).has_value());
1393     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-1799.f).has_value());
1394 }
1395 
1396 /**
1397  * @tc.name: CaleSnapOffsetsByPaginations002
1398  * @tc.desc: Test CaleSnapOffsetsByPaginations where the page size is greater than the scroll size.
1399  * @tc.type: FUNC
1400  */
1401 HWTEST_F(ScrollTestNg, CaleSnapOffsetsByPaginations002, TestSize.Level1)
1402 {
1403     /**
1404      * @tc.steps: step1. Init snapPaginations.
1405      */
1406     Dimension intervalSize = Dimension(0.f);
1407     std::vector<Dimension> snapPaginations = {
1408         Dimension(1000.f),
1409         Dimension(1200.f),
1410         Dimension(2000.f),
1411     };
1412 
1413     /**
1414      * @tc.steps: step2. EnableSnapToSide is { true, true } and SnapAlign is ScrollSnapAlign::START.
1415      * @tc.expected: SnapOffsets is correct.
1416      */
1417     // snapPaginations: { 1000.f, 1200.f, 2000.f }
1418     std::pair<bool, bool> enableSnapToSide = { true, true };
1419     CreateSnapScroll(ScrollSnapAlign::START, intervalSize, snapPaginations, enableSnapToSide);
1420     pattern_->CaleSnapOffsets();
1421     auto snapOffsets = pattern_->GetSnapOffsets();
1422     std::vector<float> testSnapOffsets = { 0.f, -1000.f, -1200.f, -2000.f, -2200.f };
1423     EXPECT_TRUE(snapOffsets == testSnapOffsets);
1424     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-500.f).has_value());
1425     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-500.f).value(), -1000.f);
1426     pattern_->currentOffset_ = -2000.f;
1427     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-100.f).has_value());
1428     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-100.f).value(), -200.f);
1429     // The midpoint of -1200.f and -2000.f is -1600.f
1430     EXPECT_TRUE(pattern_->CalePredictSnapOffset(400.f).has_value());
1431     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(400.f).value(), 0.f);
1432     EXPECT_TRUE(pattern_->CalePredictSnapOffset(401.f).has_value());
1433     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(401.f).value(), 800.f);
1434 
1435     /**
1436      * @tc.steps: step3. EnableSnapToSide is { false, false }.
1437      * @tc.expected: SnapOffsets is correct.
1438      */
1439     pattern_->SetEnableSnapToSide({ false, false });
1440     pattern_->currentOffset_ = -1900.f;
1441     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-100.f).has_value());
1442     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-100.f).value(), -100.f);
1443     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-101.f).has_value());
1444     EXPECT_TRUE(pattern_->CalePredictSnapOffset(900.f).has_value());
1445     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(900.f).value(), 900.f);
1446     EXPECT_FALSE(pattern_->CalePredictSnapOffset(901.f).has_value());
1447 
1448     /**
1449      * @tc.steps: step4. EnableSnapToSide is { true, true } and SnapAlign is ScrollSnapAlign::CENTER.
1450      * @tc.expected: SnapOffsets is correct.
1451      */
1452     auto host = pattern_->GetHost();
1453     ASSERT_NE(host, nullptr);
1454     pattern_->currentOffset_ = 0.f;
1455     pattern_->SetEnableSnapToSide({ true, true });
1456     ACE_UPDATE_NODE_LAYOUT_PROPERTY(ScrollLayoutProperty, ScrollSnapAlign, ScrollSnapAlign::CENTER, host);
1457     pattern_->CaleSnapOffsets();
1458     snapOffsets = pattern_->GetSnapOffsets();
1459     testSnapOffsets = { 0.f, -100.f, -700.f, -1200.f, -2100.f, -2200.f };
1460     EXPECT_TRUE(snapOffsets == testSnapOffsets);
1461     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-49.f).has_value());
1462     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-49.f).value(), 0.f);
1463     pattern_->currentOffset_ = -2000.f;
1464     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-100.f).has_value());
1465     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-100.f).value(), -100.f);
1466     // The midpoint of -1200.f and -2100.f is -1650.f
1467     EXPECT_TRUE(pattern_->CalePredictSnapOffset(350.f).has_value());
1468     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(350.f).value(), -100.f);
1469     EXPECT_TRUE(pattern_->CalePredictSnapOffset(351.f).has_value());
1470     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(351.f).value(), 800.f);
1471 
1472     /**
1473      * @tc.steps: step5. EnableSnapToSide is { false, false }.
1474      * @tc.expected: SnapOffsets is correct.
1475      */
1476     pattern_->SetEnableSnapToSide({ false, false });
1477     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-100.f).has_value());
1478     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-100.f).value(), -100.f);
1479     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-101.f).has_value());
1480     EXPECT_TRUE(pattern_->CalePredictSnapOffset(1900.f).has_value());
1481     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(1900.f).value(), 1900.f);
1482     EXPECT_FALSE(pattern_->CalePredictSnapOffset(1901.f).has_value());
1483 
1484     /**
1485      * @tc.steps: step6. EnableSnapToSide is { true, true } and SnapAlign is ScrollSnapAlign::END.
1486      * @tc.expected: SnapOffsets is correct.
1487      */
1488     pattern_->currentOffset_ = 0.f;
1489     pattern_->SetEnableSnapToSide({ true, true });
1490     ACE_UPDATE_NODE_LAYOUT_PROPERTY(ScrollLayoutProperty, ScrollSnapAlign, ScrollSnapAlign::END, host);
1491     pattern_->CaleSnapOffsets();
1492     snapOffsets = pattern_->GetSnapOffsets();
1493     testSnapOffsets = { 0.f, -200.f, -400.f, -1200.f, -2200.f };
1494     EXPECT_TRUE(snapOffsets == testSnapOffsets);
1495     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-100.f).has_value());
1496     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-100.f).value(), -200.f);
1497     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-1200.f).has_value());
1498     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-1200.f).value(), -1200.f);
1499     pattern_->currentOffset_ = -300.f;
1500     // The midpoint of 0.f and -200.f is -100.f
1501     EXPECT_TRUE(pattern_->CalePredictSnapOffset(200.f).has_value());
1502     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(200.f).value(), 100.f);
1503     EXPECT_TRUE(pattern_->CalePredictSnapOffset(201.f).has_value());
1504     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(201.f).value(), 300.f);
1505 
1506     /**
1507      * @tc.steps: step7. EnableSnapToSide is { false, false }.
1508      * @tc.expected: SnapOffsets is correct.
1509      */
1510     pattern_->SetEnableSnapToSide({ false, false });
1511     EXPECT_TRUE(pattern_->CalePredictSnapOffset(100.f).has_value());
1512     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(100.f).value(), 100.f);
1513     EXPECT_FALSE(pattern_->CalePredictSnapOffset(101.f).has_value());
1514     EXPECT_TRUE(pattern_->CalePredictSnapOffset(-900.f).has_value());
1515     EXPECT_DOUBLE_EQ(pattern_->CalePredictSnapOffset(-900.f).value(), -900.f);
1516     EXPECT_FALSE(pattern_->CalePredictSnapOffset(-901.f).has_value());
1517 }
1518 
1519 /**
1520  * @tc.name: Distributed001
1521  * @tc.desc: Test the distributed capability of Scroll.
1522  * @tc.type: FUNC
1523  */
1524 HWTEST_F(ScrollTestNg, Distributed001, TestSize.Level1)
1525 {
1526     /**
1527      * @tc.steps: step1. Initialize Scroll node
1528      */
1529     CreateScroll();
1530     CreateContent(TOTAL_ITEM_NUMBER);
1531     CreateDone(frameNode_);
1532 
1533     // need dpi to be 1
1534     /**
1535      * @tc.steps: step2. get pattern .
1536      * @tc.expected: function ProvideRestoreInfo is called.
1537      */
1538     pattern_->currentOffset_ = 1.0f;
1539     std::string ret = pattern_->ProvideRestoreInfo();
1540 
1541     /**
1542      * @tc.steps: step3. function OnRestoreInfo is called.
1543      * @tc.expected: Passing JSON format.
1544      */
1545     pattern_->OnRestoreInfo(ret);
1546     EXPECT_DOUBLE_EQ(pattern_->currentOffset_, 1.0f);
1547 }
1548 
1549 /**
1550  * @tc.name: ScrollGetItemRect001
1551  * @tc.desc: Test Scroll GetItemRect function.
1552  * @tc.type: FUNC
1553  */
1554 HWTEST_F(ScrollTestNg, ScrollGetItemRect001, TestSize.Level1)
1555 {
1556     /**
1557      * @tc.steps: step1. Initialize Scroll.
1558      */
1559     ScrollModelNG model = CreateScroll();
1560     model.SetAxis(Axis::HORIZONTAL);
1561     CreateContent(TOTAL_ITEM_NUMBER);
1562     CreateDone(frameNode_);
1563 
1564     /**
1565      * @tc.steps: step2. Get invalid ScrollItem Rect.
1566      * @tc.expected: Return 0 when input invalid index.
1567      */
1568     EXPECT_TRUE(IsEqual(pattern_->GetItemRect(-1), Rect()));
1569     EXPECT_TRUE(IsEqual(pattern_->GetItemRect(1), Rect()));
1570 
1571     /**
1572      * @tc.steps: step3. Get valid ScrollItem Rect.
1573      * @tc.expected: Return actual Rect when input valid index.
1574      */
1575     EXPECT_TRUE(IsEqual(
1576         pattern_->GetItemRect(0), Rect(0, 0, TOTAL_ITEM_NUMBER * ITEM_WIDTH, FILL_LENGTH.Value() * SCROLL_HEIGHT)));
1577 }
1578 
1579 /**
1580  * @tc.name: ScrollWidth001
1581  * @tc.desc: Test the usability of scroll width property and its get and set function.
1582  * @tc.type: FUNC
1583  */
1584 HWTEST_F(ScrollTestNg, ScrollWidth001, TestSize.Level1)
1585 {
1586     /**
1587      * @tc.steps: step1. verify the scroll width property
1588      * of scroll layout property.
1589      * @tc.expected: Default value is ought to be false.
1590      */
1591     CreateScroll();
1592     CreateContent(TOTAL_ITEM_NUMBER);
1593     CreateDone(frameNode_);
1594     float scrollWidth = 150.0f;
1595     EXPECT_FALSE(layoutProperty_->GetScrollWidth().has_value());
1596     layoutProperty_->UpdateScrollWidth(scrollWidth);
1597     EXPECT_EQ(layoutProperty_->GetScrollWidth().value(), scrollWidth);
1598 }
1599 
1600 /**
1601  * @tc.name: SelectScroll001
1602  * @tc.desc: Test the flags of select scroll that determines whether it belong to or be modified by a select
1603  * and their get and set functions.
1604  * @tc.type: FUNC
1605  */
1606 HWTEST_F(ScrollTestNg, SelectScroll001, TestSize.Level1)
1607 {
1608     /**
1609      * @tc.steps: step1. verify the default value of the flags
1610      * which inform whether the scroll belongs to or is modified by a select.
1611      * @tc.expected: Default value is ought to be false.
1612      */
1613     CreateScroll();
1614     CreateContent(TOTAL_ITEM_NUMBER);
1615     CreateDone(frameNode_);
1616     EXPECT_FALSE(pattern_->IsWidthModifiedBySelect());
1617     EXPECT_FALSE(pattern_->IsSelectScroll());
1618     /**
1619      * @tc.steps: step2. Set both flags to be true and verify the usability of their get and set functions in
1620      * select pattern.
1621      * @tc.expected: After setting the value should be true.
1622      */
1623     pattern_->SetIsWidthModifiedBySelect(true);
1624     pattern_->SetIsSelectScroll(true);
1625     EXPECT_TRUE(pattern_->IsWidthModifiedBySelect());
1626     EXPECT_TRUE(pattern_->IsSelectScroll());
1627 }
1628 
1629 /**
1630  * @tc.name: Measure002
1631  * @tc.desc: Test ScrollLayoutAlgorithm Measure when the scroll belongs to a select.
1632  * @tc.type: FUNC
1633  */
1634 HWTEST_F(ScrollTestNg, Measure002, TestSize.Level1)
1635 {
1636     /**
1637      * @tc.steps: step1. Create scroll model and set the width, height, axis of the scroll, create the content of
1638      * the scroll and get its instance.
1639      * @tc.expected: Objects are created successfully.
1640      */
1641     CreateScroll();
1642     CreateContent(TOTAL_ITEM_NUMBER);
1643     CreateDone(frameNode_);
1644     RefPtr<LayoutWrapperNode> layoutWrapper = frameNode_->CreateLayoutWrapper(false, false);
1645     pattern_->SetIsSelectScroll(true);
1646     FlushLayoutTask(frameNode_);
1647     layoutWrapper->MountToHostOnMainThread();
1648 
1649     RefPtr<GridColumnInfo> columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::MENU);
1650     columnInfo->GetParent()->BuildColumnWidth();
1651     auto defaultWidth = static_cast<float>(columnInfo->GetWidth(2));
1652     auto scrollSize = frameNode_->GetGeometryNode()->GetFrameSize();
1653     auto expectSize = SizeF(defaultWidth, ITEM_HEIGHT * TOTAL_ITEM_NUMBER);
1654     EXPECT_NE(scrollSize, expectSize) << "scrollSize: " << scrollSize.ToString()
1655                                       << " expectSize: " << expectSize.ToString();
1656 }
1657 
1658 /**
1659  * @tc.name: Measure003
1660  * @tc.desc: Test ScrollLayoutAlgorithm Measure.
1661  * @tc.type: FUNC
1662  */
1663 HWTEST_F(ScrollTestNg, Measure003, TestSize.Level1)
1664 {
1665     /**
1666      * @tc.steps: step1. Create scroll without children
1667      */
1668     CreateScroll();
1669     CreateDone(frameNode_);
1670     auto scrollSize = frameNode_->GetGeometryNode()->GetFrameSize();
1671     auto expectSize = SizeF(SCROLL_WIDTH, SCROLL_HEIGHT);
1672     EXPECT_TRUE(IsEqual(scrollSize, expectSize));
1673 
1674     /**
1675      * @tc.steps: step1. set idealSize
1676      * @tc.expected: The frameSize would be idealSize
1677      */
1678     ViewAbstract::SetWidth(AceType::RawPtr(frameNode_), CalcLength(300.f));
1679     ViewAbstract::SetHeight(AceType::RawPtr(frameNode_), CalcLength(500.f));
1680     FlushLayoutTask(frameNode_);
1681 
1682     scrollSize = frameNode_->GetGeometryNode()->GetFrameSize();
1683     expectSize = SizeF(300.f, 500.f);
1684     EXPECT_TRUE(IsEqual(scrollSize, expectSize));
1685 }
1686 
1687 /**
1688  * @tc.name: SelectScroll002
1689  * @tc.desc: Test select scroll default width.
1690  * @tc.type: FUNC
1691  */
1692 HWTEST_F(ScrollTestNg, SelectScroll002, TestSize.Level1)
1693 {
1694     /**
1695      * @tc.steps: step1. Get the width of select scroll without setting it, this case is meant to test the correctness
1696      * of its default value.
1697      * @tc.expected: Default width of select scroll should be 0.0.
1698      */
1699     CreateScroll();
1700     CreateContent(TOTAL_ITEM_NUMBER);
1701     CreateDone(frameNode_);
1702     ASSERT_NE(pattern_, nullptr);
1703     auto ScrollWidth = pattern_->GetSelectScrollWidth();
1704     ASSERT_NE(ScrollWidth, 0.0);
1705 }
1706 
1707 /**
1708  * @tc.name: EnablePaging001
1709  * @tc.desc: Test enablePaging
1710  * @tc.type: FUNC
1711  */
1712 HWTEST_F(ScrollTestNg, EnablePaging001, TestSize.Level1)
1713 {
1714     /**
1715      * @tc.steps: step1. Create scroll and initialize related properties.
1716      */
1717     ScrollModelNG model = CreateScroll();
1718     model.SetEnablePaging(true);
1719     CreateContent(TOTAL_ITEM_NUMBER);
1720     CreateDone(frameNode_);
1721     auto viewPortLength = pattern_->GetMainContentSize();
1722     pattern_->scrollableDistance_ = viewPortLength * 10;
1723     pattern_->currentOffset_ = -viewPortLength * 5 - 10.0f;
1724     SizeF viewPortExtent(SCROLL_WIDTH, viewPortLength * 11);
1725     pattern_->viewPortExtent_ = viewPortExtent;
1726     pattern_->SetIntervalSize(Dimension(static_cast<double>(viewPortLength)));
1727     pattern_->CaleSnapOffsets();
1728 
1729     /**
1730      * @tc.steps: step2. dragDistance and dragSpeed less than threshold
1731      * @tc.expected: predictSnapOffset.value() less than 0
1732      */
1733     auto dragDistance = viewPortLength * 0.5 - 1;
1734     auto dragSpeed = SCROLL_PAGING_SPEED_THRESHOLD - 1;
1735     auto predictSnapOffset = pattern_->CalePredictSnapOffset(0.f, dragDistance, dragSpeed);
1736     EXPECT_TRUE(predictSnapOffset.has_value());
1737     EXPECT_LT(predictSnapOffset.value(), 0);
1738 
1739     /**
1740      * @tc.steps: step3. dragDistance and dragSpeed larger than threshold
1741      * @tc.expected: the absolute value of predictSnapOffset.value() less than viewPortLength
1742      */
1743     dragDistance = viewPortLength * 0.5 * 5;
1744     dragSpeed = SCROLL_PAGING_SPEED_THRESHOLD * 5;
1745     predictSnapOffset = pattern_->CalePredictSnapOffset(0.f, dragDistance, dragSpeed);
1746     EXPECT_TRUE(predictSnapOffset.has_value());
1747     EXPECT_LT(abs(predictSnapOffset.value()), viewPortLength);
1748     EXPECT_GT(predictSnapOffset.value(), 0);
1749 
1750     /**
1751      * @tc.steps: step4. dragDistance equals threshold and dragSpeed less than threshold
1752      * @tc.expected: the absolute value of predictSnapOffset.value() less than viewPortLength
1753      */
1754     dragDistance = viewPortLength * 0.5;
1755     dragSpeed = SCROLL_PAGING_SPEED_THRESHOLD - 1;
1756     predictSnapOffset = pattern_->CalePredictSnapOffset(0.f, dragDistance, dragSpeed);
1757     EXPECT_TRUE(predictSnapOffset.has_value());
1758     EXPECT_LT(abs(predictSnapOffset.value()), viewPortLength);
1759     EXPECT_GT(predictSnapOffset.value(), 0);
1760 
1761     /**
1762      * @tc.steps: step5. dragDistance less than threshold and dragSpeed equals threshold
1763      * @tc.expected: the absolute value of predictSnapOffset.value() less than viewPortLength
1764      */
1765     dragDistance = viewPortLength * 0.5 - 1;
1766     dragSpeed = SCROLL_PAGING_SPEED_THRESHOLD;
1767     predictSnapOffset = pattern_->CalePredictSnapOffset(0.f, dragDistance, dragSpeed);
1768     EXPECT_TRUE(predictSnapOffset.has_value());
1769     EXPECT_LT(abs(predictSnapOffset.value()), viewPortLength);
1770     EXPECT_GT(predictSnapOffset.value(), 0);
1771 }
1772 
1773 /**
1774  * @tc.name: EnablePaging002
1775  * @tc.desc: Test enablePaging
1776  * @tc.type: FUNC
1777  */
1778 HWTEST_F(ScrollTestNg, EnablePaging002, TestSize.Level1)
1779 {
1780     /**
1781      * @tc.steps: step1. Create scroll and set enablePaging.
1782      * @tc.expected: the value of GetEnablePaging() is VALID
1783      */
1784     ScrollModelNG model = CreateScroll();
1785     model.SetEnablePaging(true);
1786     CreateContent(TOTAL_ITEM_NUMBER);
1787     CreateDone(frameNode_);
1788     EXPECT_EQ(pattern_->GetEnablePaging(), ScrollPagingStatus::VALID);
1789     EXPECT_EQ(pattern_->IsEnablePagingValid(), true);
1790 
1791     /**
1792      * @tc.steps: step2. Create scroll, first set enablePaging and than set snap.
1793      * @tc.expected: the value of IsEnablePagingValid() is false
1794      */
1795     Dimension intervalSize = Dimension(10.f);
1796     std::vector<Dimension> snapPaginations = {
1797         Dimension(10.f),
1798         Dimension(20.f),
1799         Dimension(30.f),
1800     };
1801     std::pair<bool, bool> enableSnapToSide = { false, false };
1802     auto scrollSnapAlign = ScrollSnapAlign::START;
1803     ClearOldNodes();
1804     model = CreateScroll();
1805     model.SetEnablePaging(true);
1806     model.SetScrollSnap(scrollSnapAlign, intervalSize, snapPaginations, enableSnapToSide);
1807     CreateContent(TOTAL_ITEM_NUMBER);
1808     CreateDone(frameNode_);
1809     EXPECT_EQ(pattern_->IsEnablePagingValid(), false);
1810 
1811     /**
1812      * @tc.steps: step3. Create scroll, first set snap and than set enablePaging.
1813      * @tc.expected: the value of IsEnablePagingValid() is false
1814      */
1815     ClearOldNodes();
1816     model = CreateScroll();
1817     model.SetScrollSnap(scrollSnapAlign, intervalSize, snapPaginations, enableSnapToSide);
1818     model.SetEnablePaging(true);
1819     CreateContent(TOTAL_ITEM_NUMBER);
1820     CreateDone(frameNode_);
1821     EXPECT_EQ(pattern_->IsEnablePagingValid(), false);
1822 
1823     /**
1824      * @tc.steps: step4. Create scroll, set enablePaging true and than set enablePaging false.
1825      * @tc.expected: the value of GetEnablePaging() is INVALID
1826      */
1827     ClearOldNodes();
1828     model = CreateScroll();
1829     model.SetEnablePaging(true);
1830     model.SetEnablePaging(false);
1831     CreateContent(TOTAL_ITEM_NUMBER);
1832     CreateDone(frameNode_);
1833     EXPECT_EQ(pattern_->GetEnablePaging(), ScrollPagingStatus::INVALID);
1834     EXPECT_EQ(pattern_->IsEnablePagingValid(), false);
1835 
1836     /**
1837      * @tc.steps: step5. Create scroll, set enablePaging false and than set enablePaging true.
1838      * @tc.expected: the value of GetEnablePaging() is VALID
1839      */
1840     ClearOldNodes();
1841     model = CreateScroll();
1842     model.SetEnablePaging(false);
1843     model.SetEnablePaging(true);
1844     CreateContent(TOTAL_ITEM_NUMBER);
1845     CreateDone(frameNode_);
1846     EXPECT_EQ(pattern_->GetEnablePaging(), ScrollPagingStatus::VALID);
1847     EXPECT_EQ(pattern_->IsEnablePagingValid(), true);
1848 }
1849 
1850 /**
1851  * @tc.name: InitialOffset001
1852  * @tc.desc: Test initialOffset
1853  * @tc.type: FUNC
1854  */
1855 HWTEST_F(ScrollTestNg, InitialOffset001, TestSize.Level1)
1856 {
1857     /**
1858      * @tc.steps: step1. Create scroll.
1859      * @tc.expected: the value of currentOffset_ is 0
1860      */
1861     CreateScroll();
1862     CreateContent(TOTAL_ITEM_NUMBER);
1863     CreateDone(frameNode_);
1864     EXPECT_EQ(pattern_->currentOffset_, 0.f);
1865 
1866     /**
1867      * @tc.steps: step2. Create scroll and set initialOffset ITEM_HEIGHT.
1868      * @tc.expected: the value of currentOffset_ is -ITEM_HEIGHT
1869      */
1870     ClearOldNodes();
1871     ScrollModelNG model = CreateScroll();
1872     model.SetInitialOffset(OffsetT(CalcDimension(0.f), CalcDimension(ITEM_HEIGHT)));
1873     CreateContent(TOTAL_ITEM_NUMBER);
1874     CreateDone(frameNode_);
1875     EXPECT_EQ(pattern_->currentOffset_, -ITEM_HEIGHT);
1876 
1877     /**
1878      * @tc.steps: step3. Create scroll , set axis HORIZONTAL and set initialOffset ITEM_HEIGHT.
1879      * @tc.expected: the value of currentOffset_ is -ITEM_WIDTH
1880      */
1881     ClearOldNodes();
1882     model = CreateScroll();
1883     model.SetInitialOffset(OffsetT(CalcDimension(ITEM_WIDTH), CalcDimension(0.f)));
1884     model.SetAxis(Axis::HORIZONTAL);
1885     CreateContent(TOTAL_ITEM_NUMBER);
1886     CreateDone(frameNode_);
1887     EXPECT_EQ(pattern_->currentOffset_, - ITEM_WIDTH);
1888 
1889     /**
1890      * @tc.steps: step4. Create scroll , set initialOffset 10%.
1891      * @tc.expected: the value of currentOffset_ is -ITEM_WIDTH
1892      */
1893     ClearOldNodes();
1894     model = CreateScroll();
1895     auto offset = Dimension(0.1, DimensionUnit::PERCENT);
1896     model.SetInitialOffset(OffsetT(CalcDimension(0.f), CalcDimension(offset)));
1897     CreateContent(TOTAL_ITEM_NUMBER);
1898     CreateDone(frameNode_);
1899     EXPECT_EQ(pattern_->currentOffset_, - SCROLL_HEIGHT * 0.1f);
1900 
1901     /**
1902      * @tc.steps: step5. Create scroll , set axis HORIZONTAL and set initialOffset 10%.
1903      * @tc.expected: the value of currentOffset_ is -ITEM_WIDTH
1904      */
1905     ClearOldNodes();
1906     model = CreateScroll();
1907     model.SetInitialOffset(OffsetT(CalcDimension(offset), CalcDimension(0.f)));
1908     model.SetAxis(Axis::HORIZONTAL);
1909     CreateContent(TOTAL_ITEM_NUMBER);
1910     CreateDone(frameNode_);
1911     EXPECT_EQ(pattern_->currentOffset_, - SCROLL_WIDTH * 0.1f);
1912 }
1913 
1914 /**
1915  * @tc.name: InitialOffset002
1916  * @tc.desc: Test initialOffset
1917  * @tc.type: FUNC
1918  */
1919 HWTEST_F(ScrollTestNg, InitialOffset002, TestSize.Level1)
1920 {
1921     /**
1922      * @tc.steps: step1. Create scroll and set initialOffset 2*ITEM_HEIGHT.
1923      * @tc.expected: the value of currentOffset_ is -2*ITEM_HEIGHT
1924      */
1925     ScrollModelNG model = CreateScroll();
1926     model.SetInitialOffset(OffsetT(CalcDimension(0.f), CalcDimension(2 * ITEM_HEIGHT)));
1927     CreateContent(TOTAL_ITEM_NUMBER);
1928     CreateDone(frameNode_);
1929     EXPECT_EQ(pattern_->currentOffset_, - 2 * ITEM_HEIGHT);
1930 
1931     /**
1932      * @tc.steps: step2. Create scroll and set initialOffset 3*ITEM_HEIGHT.
1933      * @tc.expected: the value of currentOffset_ is -2*ITEM_HEIGHT
1934      */
1935     ClearOldNodes();
1936     model = CreateScroll();
1937     model.SetInitialOffset(OffsetT(CalcDimension(0.f), CalcDimension(3 * ITEM_HEIGHT)));
1938     CreateContent(TOTAL_ITEM_NUMBER);
1939     CreateDone(frameNode_);
1940     EXPECT_EQ(pattern_->currentOffset_, - 2 * ITEM_HEIGHT);
1941 
1942     /**
1943      * @tc.steps: step3. Create scroll and set initialOffset -ITEM_HEIGHT.
1944      * @tc.expected: the value of currentOffset_ is 0
1945      */
1946     ClearOldNodes();
1947     model = CreateScroll();
1948     model.SetInitialOffset(OffsetT(CalcDimension(0.f), CalcDimension(- ITEM_HEIGHT)));
1949     CreateContent(TOTAL_ITEM_NUMBER);
1950     CreateDone(frameNode_);
1951     EXPECT_EQ(pattern_->currentOffset_, 0.f);
1952 
1953     /**
1954      * @tc.steps: step4. Create scroll , set initialOffset 100%.
1955      * @tc.expected: the value of currentOffset_ is -2*ITEM_WIDTH
1956      */
1957     ClearOldNodes();
1958     model = CreateScroll();
1959     auto offset = Dimension(100, DimensionUnit::PERCENT);
1960     model.SetInitialOffset(OffsetT(CalcDimension(0.f), CalcDimension(offset)));
1961     CreateContent(TOTAL_ITEM_NUMBER);
1962     CreateDone(frameNode_);
1963     EXPECT_EQ(pattern_->currentOffset_, - 2 * ITEM_HEIGHT);
1964 }
1965 
1966 /**
1967  * @tc.name: Model001
1968  * @tc.desc: Test scroll model
1969  * @tc.type: FUNC
1970  */
1971 HWTEST_F(ScrollTestNg, Model001, TestSize.Level1)
1972 {
1973     ScrollModelNG model = CreateScroll();
1974     EXPECT_NE(model.GetOrCreateController(), nullptr);
1975     pattern_->positionController_ = nullptr;
1976     EXPECT_NE(model.GetOrCreateController(), nullptr);
1977     EXPECT_NE(model.GetOrCreateController(AceType::RawPtr(frameNode_)), nullptr);
1978     pattern_->positionController_ = nullptr;
1979     EXPECT_NE(model.GetOrCreateController(AceType::RawPtr(frameNode_)), nullptr);
1980     EXPECT_EQ(model.GetAxis(AceType::RawPtr(frameNode_)), 0);
1981     model.SetAxis(Axis::VERTICAL);
1982     EXPECT_EQ(model.GetAxis(AceType::RawPtr(frameNode_)), 0);
1983     EXPECT_EQ(model.GetScrollEnabled(AceType::RawPtr(frameNode_)), 1);
1984     model.SetScrollEnabled(AceType::RawPtr(frameNode_), false);
1985     EXPECT_EQ(model.GetScrollEnabled(AceType::RawPtr(frameNode_)), 0);
1986     model.SetEnablePaging(AceType::RawPtr(frameNode_), true);
1987     EXPECT_EQ(pattern_->GetEnablePaging(), ScrollPagingStatus::VALID);
1988     EXPECT_EQ(pattern_->IsEnablePagingValid(), true);
1989     model.SetEnablePaging(AceType::RawPtr(frameNode_), false);
1990     EXPECT_EQ(pattern_->GetEnablePaging(), ScrollPagingStatus::INVALID);
1991     EXPECT_EQ(pattern_->IsEnablePagingValid(), false);
1992     CreateContent(TOTAL_ITEM_NUMBER);
1993     CreateDone(frameNode_);
1994 
1995     EXPECT_EQ(model.GetOnScrollEdge(AceType::RawPtr(frameNode_)), ScrollEdgeType::SCROLL_TOP);
1996     ScrollTo(ITEM_HEIGHT * 1);
1997     EXPECT_EQ(model.GetOnScrollEdge(AceType::RawPtr(frameNode_)), ScrollEdgeType::SCROLL_NONE);
1998     ScrollTo(ITEM_HEIGHT * 2);
1999     EXPECT_EQ(model.GetOnScrollEdge(AceType::RawPtr(frameNode_)), ScrollEdgeType::SCROLL_BOTTOM);
2000 
2001     ScrollTo(0.f);
2002     pattern_->SetAxis(Axis::HORIZONTAL);
2003     FlushLayoutTask(frameNode_);
2004     EXPECT_EQ(model.GetOnScrollEdge(AceType::RawPtr(frameNode_)), ScrollEdgeType::SCROLL_LEFT);
2005     ScrollTo(ITEM_HEIGHT * 1);
2006     EXPECT_EQ(model.GetOnScrollEdge(AceType::RawPtr(frameNode_)), ScrollEdgeType::SCROLL_NONE);
2007     ScrollTo(ITEM_HEIGHT * 2);
2008     EXPECT_EQ(model.GetOnScrollEdge(AceType::RawPtr(frameNode_)), ScrollEdgeType::SCROLL_RIGHT);
2009 
2010     pattern_->SetAxis(Axis::NONE);
2011     FlushLayoutTask(frameNode_);
2012     EXPECT_EQ(model.GetOnScrollEdge(AceType::RawPtr(frameNode_)), ScrollEdgeType::SCROLL_NONE);
2013 }
2014 
2015 /**
2016  * @tc.name: Alignment001
2017  * @tc.desc: Test UpdateScrollAlignment in RTL Layout, content size less than scroll size
2018  * @tc.type: FUNC
2019  */
2020 HWTEST_F(ScrollTestNg, Alignment001, TestSize.Level1)
2021 {
2022     AceApplicationInfo::GetInstance().isRightToLeft_ = true;
2023     CreateScroll();
2024     CreateContent(1); // Set content height less than scroll height
2025     CreateDone(frameNode_);
2026 
2027     /**
2028      * @tc.steps: step1. Set content width less than scroll width
2029      */
2030     float contentWidth = SCROLL_WIDTH / 2;
2031     auto contentNode = GetChildFrameNode(frameNode_, 0);
2032     ViewAbstract::SetWidth(AceType::RawPtr(contentNode), CalcLength(contentWidth));
2033     FlushLayoutTask(frameNode_);
2034     float centerPosition = (SCROLL_HEIGHT - ITEM_HEIGHT) / 2;
2035     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(0.f, centerPosition)));
2036 
2037     layoutProperty_->UpdateAlignment(Alignment::TOP_LEFT);
2038     FlushLayoutTask(frameNode_);
2039     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(contentWidth, 0.f)));
2040 
2041     layoutProperty_->UpdateAlignment(Alignment::TOP_RIGHT);
2042     FlushLayoutTask(frameNode_);
2043     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF()));
2044 
2045     layoutProperty_->UpdateAlignment(Alignment::BOTTOM_LEFT);
2046     FlushLayoutTask(frameNode_);
2047     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(contentWidth, SCROLL_HEIGHT - ITEM_HEIGHT)));
2048 
2049     layoutProperty_->UpdateAlignment(Alignment::BOTTOM_RIGHT);
2050     FlushLayoutTask(frameNode_);
2051     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(0.f, SCROLL_HEIGHT - ITEM_HEIGHT)));
2052 
2053     layoutProperty_->UpdateAlignment(Alignment::CENTER_RIGHT);
2054     FlushLayoutTask(frameNode_);
2055     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(0.f, centerPosition)));
2056 
2057     layoutProperty_->UpdateAlignment(Alignment::CENTER_LEFT);
2058     FlushLayoutTask(frameNode_);
2059     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(contentWidth, centerPosition)));
2060 
2061     layoutProperty_->UpdateAlignment(Alignment::CENTER);
2062     FlushLayoutTask(frameNode_);
2063     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(contentWidth / 2, centerPosition)));
2064 }
2065 
2066 /**
2067  * @tc.name: Alignment002
2068  * @tc.desc: Test UpdateScrollAlignment in RTL Layout, content size greater than scroll size
2069  * @tc.type: FUNC
2070  */
2071 HWTEST_F(ScrollTestNg, Alignment002, TestSize.Level1)
2072 {
2073     AceApplicationInfo::GetInstance().isRightToLeft_ = true;
2074     CreateScroll();
2075     CreateContent(TOTAL_ITEM_NUMBER); // Set content height less than scroll height
2076     CreateDone(frameNode_);
2077 
2078     /**
2079      * @tc.steps: step1. Set content width greater than scroll width
2080      */
2081     float contentWidth = SCROLL_WIDTH * 2;
2082     auto contentNode = GetChildFrameNode(frameNode_, 0);
2083     ViewAbstract::SetWidth(AceType::RawPtr(contentNode), CalcLength(contentWidth));
2084     FlushLayoutTask(frameNode_);
2085     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF()));
2086 
2087     layoutProperty_->UpdateAlignment(Alignment::TOP_LEFT);
2088     FlushLayoutTask(frameNode_);
2089     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(-SCROLL_WIDTH, 0.f)));
2090 
2091     layoutProperty_->UpdateAlignment(Alignment::TOP_RIGHT);
2092     FlushLayoutTask(frameNode_);
2093     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(-SCROLL_WIDTH, 0.f)));
2094 
2095     layoutProperty_->UpdateAlignment(Alignment::BOTTOM_LEFT);
2096     FlushLayoutTask(frameNode_);
2097     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(-SCROLL_WIDTH, 0.f)));
2098 
2099     layoutProperty_->UpdateAlignment(Alignment::BOTTOM_RIGHT);
2100     FlushLayoutTask(frameNode_);
2101     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(-SCROLL_WIDTH, 0.f)));
2102 
2103     layoutProperty_->UpdateAlignment(Alignment::CENTER_RIGHT);
2104     FlushLayoutTask(frameNode_);
2105     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(-SCROLL_WIDTH, 0.f)));
2106 
2107     layoutProperty_->UpdateAlignment(Alignment::CENTER_LEFT);
2108     FlushLayoutTask(frameNode_);
2109     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(-SCROLL_WIDTH, 0.f)));
2110 
2111     layoutProperty_->UpdateAlignment(Alignment::CENTER);
2112     FlushLayoutTask(frameNode_);
2113     EXPECT_TRUE(IsEqual(GetChildOffset(frameNode_, 0), OffsetF(-SCROLL_WIDTH, 0.f)));
2114 }
2115 
2116 /**
2117  * @tc.name: ToJsonValue001
2118  * @tc.desc: Test ToJsonValue
2119  * @tc.type: FUNC
2120  */
2121 HWTEST_F(ScrollTestNg, ToJsonValue001, TestSize.Level1)
2122 {
2123     ScrollModelNG model = CreateScroll();
2124     model.SetInitialOffset(OffsetT(CalcDimension(10.f), CalcDimension(20.f)));
2125     CreateContent(TOTAL_ITEM_NUMBER);
2126     CreateDone(frameNode_);
2127     EXPECT_EQ(pattern_->GetInitialOffset().GetX().ToString(), "10.00px");
2128     EXPECT_EQ(pattern_->GetInitialOffset().GetY().ToString(), "20.00px");
2129 
2130     /**
2131      * @tc.steps: step1. !IsFastFilter
2132      */
2133     InspectorFilter filter;
2134     auto json = JsonUtil::Create(true);
2135     pattern_->ToJsonValue(json, filter);
2136     auto initialOffset = json->GetObject("initialOffset");
2137     EXPECT_EQ(initialOffset->GetString("xOffset"), "10.00px");
2138     EXPECT_EQ(initialOffset->GetString("yOffset"), "20.00px");
2139 
2140     /**
2141      * @tc.steps: step2. IsFastFilter
2142      */
2143     std::string attr = "id";
2144     filter.AddFilterAttr(attr);
2145     json = JsonUtil::Create(true);
2146     pattern_->ToJsonValue(json, filter);
2147     initialOffset = json->GetObject("initialOffset");
2148     EXPECT_EQ(initialOffset->GetString("xOffset"), "");
2149     EXPECT_EQ(initialOffset->GetString("yOffset"), "");
2150 }
2151 } // namespace OHOS::Ace::NG
2152