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