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