1 /*
2 * Copyright (c) 2022-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "tabs_test_ng.h"
17
18 #include "test/mock/base/mock_system_properties.h"
19 #include "test/mock/base/mock_task_executor.h"
20 #include "test/mock/core/common/mock_resource_adapter_v2.h"
21 #include "test/mock/core/common/mock_theme_manager.h"
22 #include "test/mock/core/pipeline/mock_pipeline_context.h"
23 #include "test/mock/core/render/mock_render_context.h"
24 #include "test/mock/core/rosen/mock_canvas.h"
25
26 #include "core/common/agingadapation/aging_adapation_dialog_theme.h"
27 #include "core/components/dialog/dialog_theme.h"
28 #include "core/components/tab_bar/tab_theme.h"
29 #include "core/components_ng/pattern/linear_layout/column_model_ng.h"
30
31 namespace OHOS::Ace::NG {
32 namespace {
GetTheme(ThemeType type)33 RefPtr<Theme> GetTheme(ThemeType type)
34 {
35 if (type == AgingAdapationDialogTheme::TypeId()) {
36 auto agingAdapationDialogTheme = AceType::MakeRefPtr<AgingAdapationDialogTheme>();
37 agingAdapationDialogTheme->bigFontSizeScale_ = BIG_FONT_SIZE_SCALE;
38 agingAdapationDialogTheme->largeFontSizeScale_ = LARGE_FONT_SIZE_SCALE;
39 agingAdapationDialogTheme->maxFontSizeScale_ = MAX_FONT_SIZE_SCALE;
40 agingAdapationDialogTheme->bigDialogWidth_ = BIG_DIALOG_WIDTH;
41 agingAdapationDialogTheme->maxDialogWidth_ = MAX_DIALOG_WIDTH;
42 return agingAdapationDialogTheme;
43 } else if (type == TabTheme::TypeId()) {
44 auto themeConstants = TestNG::CreateThemeConstants(THEME_PATTERN_TAB);
45 auto tabTheme = TabTheme::Builder().Build(themeConstants);
46 tabTheme->defaultTabBarName_ = "tabBarItemName";
47 tabTheme->tabBarDefaultWidth_ = Dimension(TAB_BAR_SIZE);
48 tabTheme->tabBarDefaultHeight_ = Dimension(TAB_BAR_SIZE);
49 tabTheme->subTabBarHoverColor_ = Color::RED;
50 tabTheme->subTabBarPressedColor_ = Color::GREEN;
51 tabTheme->bottomTabSymbolOn_ = Color::BLUE;
52 tabTheme->bottomTabIconOff_ = Color::BLACK;
53 tabTheme->tabBarFocusedColor_ = Color::GRAY;
54 return tabTheme;
55 } else {
56 return AceType::MakeRefPtr<DialogTheme>();
57 }
58 }
59 } // namespace
60
SetUpTestSuite()61 void TabsTestNg::SetUpTestSuite()
62 {
63 TestNG::SetUpTestSuite();
64 MockPipelineContext::GetCurrent()->SetUseFlushUITasks(true);
65 auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
66 EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly([](ThemeType type) -> RefPtr<Theme> {
67 return GetTheme(type);
68 });
69 EXPECT_CALL(*themeManager, GetTheme(_, _))
70 .WillRepeatedly([](ThemeType type, int32_t themeScopeId) -> RefPtr<Theme> { return GetTheme(type); });
71 MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
72 }
73
TearDownTestSuite()74 void TabsTestNg::TearDownTestSuite()
75 {
76 TestNG::TearDownTestSuite();
77 ResetMockResourceData();
78 g_isConfigChangePerform = false;
79 }
80
SetUp()81 void TabsTestNg::SetUp() {}
82
TearDown()83 void TabsTestNg::TearDown()
84 {
85 RemoveFromStageNode();
86 frameNode_ = nullptr;
87 pattern_ = nullptr;
88 layoutProperty_ = nullptr;
89
90 swiperNode_ = nullptr;
91 swiperPattern_ = nullptr;
92 swiperLayoutProperty_ = nullptr;
93 swiperPaintProperty_ = nullptr;
94 swiperController_ = nullptr;
95
96 tabBarNode_ = nullptr;
97 tabBarPattern_ = nullptr;
98 tabBarLayoutProperty_ = nullptr;
99 tabBarPaintProperty_ = nullptr;
100 tabBarAccessibilityProperty_ = nullptr;
101
102 dividerNode_ = nullptr;
103 dividerRenderProperty_ = nullptr;
104 ClearOldNodes(); // Each testCase will create new list at begin
105 AceApplicationInfo::GetInstance().isRightToLeft_ = false;
106 ResetMockResourceData();
107 g_isConfigChangePerform = false;
108 }
109
GetTabs()110 void TabsTestNg::GetTabs()
111 {
112 // tabs
113 RefPtr<UINode> element = ViewStackProcessor::GetInstance()->GetMainElementNode();
114 frameNode_ = AceType::DynamicCast<TabsNode>(element);
115 pattern_ = frameNode_->GetPattern<TabsPattern>();
116 layoutProperty_ = frameNode_->GetLayoutProperty<TabsLayoutProperty>();
117 // swiper>tabContent
118 swiperNode_ = AceType::DynamicCast<FrameNode>(frameNode_->GetTabs());
119 swiperPattern_ = swiperNode_->GetPattern<SwiperPattern>();
120 swiperLayoutProperty_ = swiperNode_->GetLayoutProperty<SwiperLayoutProperty>();
121 swiperPaintProperty_ = swiperNode_->GetPaintProperty<SwiperPaintProperty>();
122 swiperController_ = swiperPattern_->GetSwiperController();
123 // tabBar
124 tabBarNode_ = AceType::DynamicCast<FrameNode>(frameNode_->GetTabBar());
125 tabBarPattern_ = tabBarNode_->GetPattern<TabBarPattern>();
126 tabBarLayoutProperty_ = tabBarNode_->GetLayoutProperty<TabBarLayoutProperty>();
127 tabBarPaintProperty_ = tabBarNode_->GetPaintProperty<TabBarPaintProperty>();
128 tabBarAccessibilityProperty_ = tabBarNode_->GetAccessibilityProperty<TabBarAccessibilityProperty>();
129 // divider
130 dividerNode_ = AceType::DynamicCast<FrameNode>(frameNode_->GetDivider());
131 dividerRenderProperty_ = dividerNode_->GetPaintProperty<DividerRenderProperty>();
132 }
133
CreateTabs(BarPosition barPosition,int32_t index)134 TabsModelNG TabsTestNg::CreateTabs(BarPosition barPosition, int32_t index)
135 {
136 ResetElmtId();
137 ViewStackProcessor::GetInstance()->StartGetAccessRecordingFor(GetElmtId());
138 TabsModelNG model;
139 model.Create(barPosition, index, nullptr, nullptr);
140 ViewAbstract::SetWidth(CalcLength(TABS_WIDTH));
141 ViewAbstract::SetHeight(CalcLength(TABS_HEIGHT));
142 auto tabNode = AceType::DynamicCast<TabsNode>(ViewStackProcessor::GetInstance()->GetMainFrameNode());
143 auto tabBarNode = AceType::DynamicCast<FrameNode>(tabNode->GetTabBar());
144 tabBarNode->GetOrCreateFocusHub();
145 GetTabs();
146 return model;
147 }
148
CreateTabContent()149 TabContentModelNG TabsTestNg::CreateTabContent()
150 {
151 return CreateTabContentWithDeepRender(nullptr);
152 }
153
CreateTabContentWithDeepRender(std::function<void ()> && deepRenderFunc)154 TabContentModelNG TabsTestNg::CreateTabContentWithDeepRender(std::function<void()>&& deepRenderFunc)
155 {
156 int32_t elmtId = GetElmtId();
157 ViewStackProcessor::GetInstance()->StartGetAccessRecordingFor(elmtId);
158 auto tabFrameNode = ViewStackProcessor::GetInstance()->GetMainElementNode();
159 auto weakTab = AceType::WeakClaim(AceType::RawPtr(tabFrameNode));
160 TabContentModelNG tabContentModel;
161 tabContentModel.Create(std::move(deepRenderFunc));
162 ViewAbstract::SetWidth(CalcLength(FILL_LENGTH));
163 ViewAbstract::SetHeight(CalcLength(FILL_LENGTH));
164 auto tabContentFrameNode = ViewStackProcessor::GetInstance()->GetMainElementNode();
165 auto tabContentNode = AceType::DynamicCast<TabContentNode>(tabContentFrameNode);
166 tabContentNode->UpdateRecycleElmtId(elmtId); // for AddChildToGroup
167 tabContentNode->GetTabBarItemId(); // for AddTabBarItem
168 tabContentNode->SetParent(weakTab); // for AddTabBarItem
169 return tabContentModel;
170 }
171
CreateTabsDone(TabsModelNG model)172 void TabsTestNg::CreateTabsDone(TabsModelNG model)
173 {
174 model.Pop();
175 CreateDone();
176 auto pipeline = frameNode_->GetContext();
177 pipeline->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
178 }
179
CreateTabContents(int32_t itemNumber)180 void TabsTestNg::CreateTabContents(int32_t itemNumber)
181 {
182 for (int32_t index = 0; index < itemNumber; index++) {
183 TabContentModelNG tabContentModel = CreateTabContent();
184 ViewStackProcessor::GetInstance()->Pop();
185 ViewStackProcessor::GetInstance()->StopGetAccessRecording();
186 }
187 }
188
CreateTabContentsWithBuilder(int32_t itemNumber)189 void TabsTestNg::CreateTabContentsWithBuilder(int32_t itemNumber)
190 {
191 for (int32_t index = 0; index < itemNumber; index++) {
192 TabContentModelNG tabContentModel = CreateTabContent();
193 auto tabBarItemFunc = TabBarItemBuilder();
194 tabContentModel.SetTabBar("", "", std::nullopt, std::move(tabBarItemFunc), true);
195 ViewStackProcessor::GetInstance()->Pop();
196 ViewStackProcessor::GetInstance()->StopGetAccessRecording();
197 }
198 }
199
TabBarItemBuilder()200 TabBarBuilderFunc TabsTestNg::TabBarItemBuilder()
201 {
202 return []() {
203 ColumnModelNG colModel;
204 colModel.Create(Dimension(0), nullptr, "");
205 ViewAbstract::SetWidth(CalcLength(BAR_ITEM_SIZE));
206 ViewAbstract::SetHeight(CalcLength(BAR_ITEM_SIZE));
207 };
208 }
209
CreateTabContentTabBarStyle(TabBarStyle tabBarStyle)210 void TabsTestNg::CreateTabContentTabBarStyle(TabBarStyle tabBarStyle)
211 {
212 TabContentModelNG tabContentModel = CreateTabContent();
213 tabContentModel.SetTabBarStyle(tabBarStyle);
214 tabContentModel.SetTabBar("text", IMAGE_SRC_URL, std::nullopt, nullptr, true);
215 ViewStackProcessor::GetInstance()->Pop();
216 ViewStackProcessor::GetInstance()->StopGetAccessRecording();
217 }
218
CreateTabContentTabBarStyleWithBuilder(TabBarStyle tabBarStyle)219 void TabsTestNg::CreateTabContentTabBarStyleWithBuilder(TabBarStyle tabBarStyle)
220 {
221 TabContentModelNG tabContentModel = CreateTabContent();
222 tabContentModel.SetTabBarStyle(tabBarStyle);
223 auto tabBarItemFunc = TabBarItemBuilder();
224 tabContentModel.SetTabBar("", "", std::nullopt, std::move(tabBarItemFunc), true);
225 ViewStackProcessor::GetInstance()->Pop();
226 ViewStackProcessor::GetInstance()->StopGetAccessRecording();
227 }
228
ChangeIndex(int32_t index)229 void TabsTestNg::ChangeIndex(int32_t index)
230 {
231 swiperController_->SwipeTo(index);
232 frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); // for update swiper
233 FlushUITasks();
234 }
235
HandleClick(int32_t index)236 void TabsTestNg::HandleClick(int32_t index)
237 {
238 tabBarPattern_->HandleClick(SourceType::NONE, index);
239 frameNode_->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); // for update swiper
240 FlushUITasks();
241 }
242
HandleMouseEvent(MouseAction action,Offset location)243 void TabsTestNg::HandleMouseEvent(MouseAction action, Offset location)
244 {
245 MouseInfo mouseInfo;
246 mouseInfo.SetAction(action);
247 mouseInfo.SetLocalLocation(location);
248 tabBarPattern_->HandleMouseEvent(mouseInfo);
249 }
250
HandleHoverEvent(bool isHover)251 void TabsTestNg::HandleHoverEvent(bool isHover)
252 {
253 tabBarPattern_->HandleHoverEvent(isHover);
254 }
255
CreateDragInfo(bool moveDirection)256 GestureEvent TabsTestNg::CreateDragInfo(bool moveDirection)
257 {
258 GestureEvent info;
259 info.SetInputEventType(InputEventType::AXIS);
260 info.SetSourceTool(SourceTool::TOUCHPAD);
261 info.SetGlobalLocation(Offset(100.f, 100.f));
262 info.SetMainDelta(moveDirection ? -DRAG_DELTA : DRAG_DELTA);
263 info.SetMainVelocity(moveDirection ? -2000.f : 2000.f);
264 return info;
265 }
266
CurrentIndex(int32_t expectIndex)267 AssertionResult TabsTestNg::CurrentIndex(int32_t expectIndex)
268 {
269 if (swiperPattern_->GetCurrentIndex() != expectIndex) {
270 return IsEqual(swiperPattern_->GetCurrentIndex(), expectIndex);
271 }
272 if (tabBarLayoutProperty_->GetIndicatorValue() != expectIndex) {
273 return IsEqual(tabBarLayoutProperty_->GetIndicatorValue(), expectIndex);
274 }
275 if (!GetChildFrameNode(swiperNode_, expectIndex)) {
276 return AssertionFailure() << "There is no item at expectIndex: " << expectIndex;
277 }
278 if (!GetChildFrameNode(swiperNode_, expectIndex)->IsActive()) {
279 return AssertionFailure() << "The expectIndex item is not active";
280 }
281 if (GetChildFrameNode(swiperNode_, expectIndex)->GetLayoutProperty()->GetVisibility() != VisibleType::GONE) {
282 if (NearZero(GetChildWidth(swiperNode_, expectIndex))) {
283 return AssertionFailure() << "The expectIndex item width is 0";
284 }
285 if (NearZero(GetChildHeight(swiperNode_, expectIndex))) {
286 return AssertionFailure() << "The expectIndex item height is 0";
287 }
288 }
289 return AssertionSuccess();
290 }
291
OnDraw()292 RefPtr<TabBarModifier> TabsTestNg::OnDraw()
293 {
294 RefPtr<NodePaintMethod> paint = tabBarPattern_->CreateNodePaintMethod();
295 RefPtr<TabBarPaintMethod> tabBarPaint = AceType::DynamicCast<TabBarPaintMethod>(paint);
296 auto tabBarPaintWrapper = tabBarNode_->CreatePaintWrapper();
297 tabBarPaint->UpdateContentModifier(AceType::RawPtr(tabBarPaintWrapper));
298
299 auto modifier = tabBarPaint->GetContentModifier(nullptr);
300 auto tabBarModifier = AceType::DynamicCast<TabBarModifier>(modifier);
301 Testing::MockCanvas canvas;
302 DrawingContext drawingContext = { canvas, TABS_WIDTH, TABS_HEIGHT };
303 tabBarModifier->onDraw(drawingContext);
304 return tabBarModifier;
305 }
306
VerifyBackgroundColor(int32_t itemIndex,Color expectColor)307 AssertionResult TabsTestNg::VerifyBackgroundColor(int32_t itemIndex, Color expectColor)
308 {
309 Color actualColor = GetChildFrameNode(tabBarNode_, itemIndex)->GetRenderContext()->GetBackgroundColor().value();
310 return IsEqual(actualColor, expectColor);
311 }
312
MockPaintRect(const RefPtr<FrameNode> & frameNode)313 void TabsTestNg::MockPaintRect(const RefPtr<FrameNode>& frameNode)
314 {
315 auto mockRenderContext = AceType::DynamicCast<MockRenderContext>(frameNode->renderContext_);
316 mockRenderContext->paintRect_ = RectF(0.f, 0.f, TABS_WIDTH, TABS_HEIGHT);
317 }
318
MockPaintRectSmallSize(const RefPtr<FrameNode> & frameNode)319 void TabsTestNg::MockPaintRectSmallSize(const RefPtr<FrameNode>& frameNode)
320 {
321 auto mockRenderContext = AceType::DynamicCast<MockRenderContext>(frameNode->renderContext_);
322 mockRenderContext->paintRect_ = RectF(0.f, 0.f, TABS_WIDTH, 0.f);
323 }
324
325 /**
326 * @tc.name: InitSurfaceChangedCallback001
327 * @tc.desc: test InitSurfaceChangedCallback
328 * @tc.type: FUNC
329 */
330 HWTEST_F(TabsTestNg, InitSurfaceChangedCallback001, TestSize.Level1)
331 {
332 TabsModelNG model = CreateTabs();
333 CreateTabContents(TABCONTENT_NUMBER);
334 CreateTabsDone(model);
335
336 /**
337 * @tc.steps: case1. WindowSizeChangeReason::UNDEFINED
338 */
339 auto callbackId = tabBarPattern_->surfaceChangedCallbackId_.value();
340 auto func = MockPipelineContext::GetCurrent()->surfaceChangedCallbackMap_[callbackId];
341 func(100.f, 100.f, TABS_WIDTH, TABS_HEIGHT, WindowSizeChangeReason::UNDEFINED);
342 EXPECT_EQ(tabBarPattern_->windowSizeChangeReason_, WindowSizeChangeReason::UNDEFINED);
343
344 /**
345 * @tc.steps: case2. WindowSizeChangeReason::ROTATION
346 * @tc.expected: StopTranslateAnimation
347 */
348 func(100.f, 100.f, TABS_WIDTH, TABS_HEIGHT, WindowSizeChangeReason::ROTATION);
349 EXPECT_EQ(tabBarPattern_->windowSizeChangeReason_, WindowSizeChangeReason::ROTATION);
350 EXPECT_FALSE(tabBarPattern_->indicatorAnimationIsRunning_);
351 EXPECT_FALSE(tabBarPattern_->translateAnimationIsRunning_);
352
353 /**
354 * @tc.steps: case3. Other WindowSizeChangeReason
355 * @tc.expected: Nothing happend
356 */
357 func(100.f, 100.f, TABS_WIDTH, TABS_HEIGHT, WindowSizeChangeReason::TRANSFORM);
358 EXPECT_EQ(tabBarPattern_->windowSizeChangeReason_, WindowSizeChangeReason::TRANSFORM);
359 }
360
361 /**
362 * @tc.name: TabsPatternGetScopeFocusAlgorithm001
363 * @tc.desc: test GetScopeFocusAlgorithm
364 * @tc.type: FUNC
365 */
366 HWTEST_F(TabsTestNg, TabsPatternGetScopeFocusAlgorithm001, TestSize.Level1)
367 {
368 TabsModelNG model = CreateTabs(BarPosition::END);
369 CreateTabContentTabBarStyle(TabBarStyle::SUBTABBATSTYLE);
370 CreateTabContentTabBarStyle(TabBarStyle::SUBTABBATSTYLE);
371 CreateTabsDone(model);
372
373 /**
374 * @tc.steps: steps2. GetScopeFocusAlgorithm
375 * @tc.expected: steps2. Check the result of GetScopeFocusAlgorithm
376 */
377 auto tabsLayoutProperty = layoutProperty_;
378 auto tabsPattern = frameNode_->GetPattern<TabsPattern>();
379 tabsLayoutProperty->UpdateAxis(Axis::HORIZONTAL);
380 tabsPattern->GetScopeFocusAlgorithm();
381 EXPECT_EQ(tabsLayoutProperty->GetAxis().value(), Axis::HORIZONTAL);
382 tabsLayoutProperty->UpdateAxis(Axis::VERTICAL);
383 tabsPattern->GetScopeFocusAlgorithm();
384 EXPECT_EQ(tabsLayoutProperty->GetAxis().value(), Axis::VERTICAL);
385 }
386
387 /**
388 * @tc.name: ConvertToString001
389 * @tc.desc: Test the ConvertLayoutModeToString function in the TabContentNodel class.
390 * @tc.type: FUNC
391 */
392 HWTEST_F(TabsTestNg, ConvertToString001, TestSize.Level1)
393 {
394 TabsModelNG model = CreateTabs();
395 CreateTabContents(1);
396 CreateTabsDone(model);
397 auto tabContentFrameNode = AceType::DynamicCast<TabContentNode>(GetChildFrameNode(swiperNode_, 0));
398 EXPECT_EQ(tabContentFrameNode->ConvertFlexAlignToString(FlexAlign::FLEX_START), "VerticalAlign.Top");
399 EXPECT_EQ(tabContentFrameNode->ConvertFlexAlignToString(FlexAlign::FLEX_END), "VerticalAlign.Bottom");
400 EXPECT_EQ(tabContentFrameNode->ConvertLayoutModeToString(LayoutMode::VERTICAL), "LayoutMode.VERTICAL");
401 EXPECT_EQ(tabContentFrameNode->ConvertLayoutModeToString(LayoutMode::HORIZONTAL), "LayoutMode.HORIZONTAL");
402 EXPECT_EQ(tabContentFrameNode->ConvertLayoutModeToString(LayoutMode::AUTO), "LayoutMode.AUTO");
403 }
404
405 /**
406 * @tc.name: TabsNodeToJsonValue001
407 * @tc.desc: Test the ToJsonValue function in the TabsNode class.
408 * @tc.type: FUNC
409 */
410 HWTEST_F(TabsTestNg, TabsNodeToJsonValue001, TestSize.Level2)
411 {
412 TabsModelNG model = CreateTabs();
413 CreateTabContents(1);
414 CreateTabsDone(model);
415
416 auto json = JsonUtil::Create(true);
417 InspectorFilter filter;
418 frameNode_->ToJsonValue(json, filter);
419 EXPECT_EQ(json->GetString("index"), "0");
420 EXPECT_EQ(json->GetString("animationDuration"), "");
421 EXPECT_EQ(json->GetString("barMode"), "BarMode.Fixed");
422 EXPECT_EQ(json->GetString("barWidth"), "720.000000");
423 EXPECT_EQ(json->GetString("barHeight"), "56.000000");
424 EXPECT_EQ(json->GetString("fadingEdge"), "true");
425 EXPECT_EQ(json->GetString("barBackgroundColor"), "#00000000");
426 EXPECT_EQ(json->GetString("barBackgroundBlurStyle"), "BlurStyle.NONE");
427 EXPECT_EQ(json->GetString("animationMode"), "AnimationMode.CONTENT_FIRST");
428 EXPECT_EQ(json->GetString("edgeEffect"), "EdgeEffect::SPRING");
429 EXPECT_EQ(json->GetString("barGridAlign"), "");
430
431 pattern_->SetAnimateMode(TabAnimateMode::ACTION_FIRST);
432 tabBarLayoutProperty_->UpdateTabBarMode(TabBarMode::SCROLLABLE);
433 swiperPaintProperty_->UpdateEdgeEffect(EdgeEffect::FADE);
434 json = JsonUtil::Create(true);
435 frameNode_->ToJsonValue(json, filter);
436 EXPECT_EQ(json->GetString("barMode"),
437 "BarMode.Scrollable,{\"margin\":\"0.00vp\",\"nonScrollableLayoutStyle\":\"LayoutStyle.ALWAYS_CENTER\"}");
438 EXPECT_EQ(json->GetString("animationMode"), "AnimationMode.ACTION_FIRST");
439 EXPECT_EQ(json->GetString("edgeEffect"), "EdgeEffect::FADE");
440
441 ScrollableBarModeOptions options;
442 options.nonScrollableLayoutStyle = LayoutStyle::ALWAYS_AVERAGE_SPLIT;
443 tabBarLayoutProperty_->UpdateScrollableBarModeOptions(options);
444 pattern_->SetAnimateMode(TabAnimateMode::NO_ANIMATION);
445 swiperPaintProperty_->UpdateEdgeEffect(EdgeEffect::NONE);
446 json = JsonUtil::Create(true);
447 frameNode_->ToJsonValue(json, filter);
448 EXPECT_EQ(json->GetString("barMode"),
449 "BarMode.Scrollable,{\"margin\":\"0.00vp\",\"nonScrollableLayoutStyle\":\"LayoutStyle.ALWAYS_AVERAGE_SPLIT\"}");
450 EXPECT_EQ(json->GetString("animationMode"), "AnimationMode.NO_ANIMATION");
451 EXPECT_EQ(json->GetString("edgeEffect"), "EdgeEffect::NONE");
452
453 options.nonScrollableLayoutStyle = LayoutStyle::SPACE_BETWEEN_OR_CENTER;
454 tabBarLayoutProperty_->UpdateScrollableBarModeOptions(options);
455 pattern_->SetAnimateMode(TabAnimateMode::MAX_VALUE);
456 json = JsonUtil::Create(true);
457 frameNode_->ToJsonValue(json, filter);
458 EXPECT_EQ(json->GetString("barMode"), "BarMode.Scrollable,{\"margin\":\"0.00vp\",\"nonScrollableLayoutStyle\":"
459 "\"LayoutStyle.SPACE_BETWEEN_OR_CENTER\"}");
460 EXPECT_EQ(json->GetString("animationMode"), "AnimationMode.CONTENT_FIRST");
461 }
462
463 /**
464 * @tc.name: TabsNodeToJsonValue002
465 * @tc.desc: Test the ToJsonValue function in the TabsNode class.
466 * @tc.type: FUNC
467 */
468 HWTEST_F(TabsTestNg, TabsNodeToJsonValue002, TestSize.Level2)
469 {
470 TabsModelNG model = CreateTabs();
471 CreateTabContents(1);
472 CreateTabsDone(model);
473
474 frameNode_->swiperId_ = std::nullopt;
475 frameNode_->tabBarId_ = std::nullopt;
476 auto json = JsonUtil::Create(true);
477 InspectorFilter filter;
478 frameNode_->ToJsonValue(json, filter);
479 EXPECT_EQ(json->GetString("index"), "0");
480 EXPECT_EQ(json->GetString("animationDuration"), "");
481 EXPECT_EQ(json->GetString("barMode"), "BarMode.Fixed");
482 EXPECT_EQ(json->GetString("barWidth"), "0.000000");
483 EXPECT_EQ(json->GetString("barHeight"), "0.000000");
484 EXPECT_EQ(json->GetString("fadingEdge"), "true");
485 EXPECT_EQ(json->GetString("barBackgroundColor"), "#00000000");
486 EXPECT_EQ(json->GetString("barBackgroundBlurStyle"), "BlurStyle.NONE");
487 EXPECT_EQ(json->GetString("animationMode"), "AnimationMode.CONTENT_FIRST");
488 EXPECT_EQ(json->GetString("edgeEffect"), "EdgeEffect::SPRING");
489 EXPECT_EQ(json->GetString("barGridAlign"), "");
490
491 std::string attr = "id";
492 filter.AddFilterAttr(attr);
493 json = JsonUtil::Create(true);
494 frameNode_->ToJsonValue(json, filter);
495 EXPECT_TRUE(filter.IsFastFilter());
496 EXPECT_EQ(json->ToString(), "{\"id\":\"\",\"isLayoutDirtyMarked\":false,\"isRenderDirtyMarked\":false,"
497 "\"isMeasureBoundary\":false,\"hasPendingRequest\":false,\"isFirstBuilding\":false}");
498 }
499
500 /**
501 * @tc.name: TabsNodeToJsonValue003
502 * @tc.desc: Test the ToJsonValue function in the TabsNode class.
503 * @tc.type: FUNC
504 */
505 HWTEST_F(TabsTestNg, TabsNodeToJsonValue003, TestSize.Level2)
506 {
507 TabsModelNG model = CreateTabs();
508 CreateTabContents(1);
509 CreateTabsDone(model);
510 ASSERT_NE(frameNode_, nullptr);
511 ASSERT_NE(pattern_, nullptr);
512
513 InspectorFilter filter;
514 auto json = JsonUtil::Create(true);
515 ASSERT_NE(json, nullptr);
516 frameNode_->ToJsonValue(json, filter);
517 EXPECT_EQ(json->GetString("animationMode"), "AnimationMode.CONTENT_FIRST");
518
519 pattern_->SetAnimateMode(TabAnimateMode::CONTENT_FIRST_WITH_JUMP);
520 json = JsonUtil::Create(true);
521 ASSERT_NE(json, nullptr);
522 frameNode_->ToJsonValue(json, filter);
523 EXPECT_EQ(json->GetString("animationMode"), "AnimationMode.CONTENT_FIRST_WITH_JUMP");
524
525 pattern_->SetAnimateMode(TabAnimateMode::ACTION_FIRST_WITH_JUMP);
526 json = JsonUtil::Create(true);
527 ASSERT_NE(json, nullptr);
528 frameNode_->ToJsonValue(json, filter);
529 EXPECT_EQ(json->GetString("animationMode"), "AnimationMode.ACTION_FIRST_WITH_JUMP");
530 }
531
532 /**
533 * @tc.name: TabsNodeGetScrollableBarModeOptions001
534 * @tc.desc: Test the GetScrollableBarModeOptions function in the TabsNode class.
535 * @tc.type: FUNC
536 */
537 HWTEST_F(TabsTestNg, TabsNodeGetScrollableBarModeOptions001, TestSize.Level2)
538 {
539 TabsModelNG model = CreateTabs();
540 CreateTabContents(TABCONTENT_NUMBER);
541 CreateTabsDone(model);
542 tabBarPattern_->tabBarStyle_ = TabBarStyle::SUBTABBATSTYLE;
543
544 /**
545 * @tc.steps: steps2. GetScrollableBarModeOptions.
546 * @tc.expected: steps2. Check the result of GetScrollableBarModeOptions.
547 */
548 frameNode_->GetScrollableBarModeOptions();
549 frameNode_->tabBarId_ = frameNode_->GetTabBarId();
550 ScrollableBarModeOptions option = frameNode_->GetScrollableBarModeOptions();
551 EXPECT_EQ(option.margin.Value(), 0.0f);
552 EXPECT_EQ(option.nonScrollableLayoutStyle, std::nullopt);
553 frameNode_->tabBarId_ = {};
554 option = frameNode_->GetScrollableBarModeOptions();
555 EXPECT_EQ(option.margin.Value(), 0.0f);
556 EXPECT_EQ(option.nonScrollableLayoutStyle, std::nullopt);
557 }
558
559 /**
560 * @tc.name: ProvideRestoreInfo001
561 * @tc.desc: test AddTabBarItem
562 * @tc.type: FUNC
563 */
564 HWTEST_F(TabsTestNg, ProvideRestoreInfo001, TestSize.Level1)
565 {
566 TabsModelNG model = CreateTabs();
567 CreateTabContents(TABCONTENT_NUMBER);
568 CreateTabsDone(model);
569 EXPECT_EQ(tabBarPattern_->ProvideRestoreInfo(), "{\"Index\":0}");
570 ChangeIndex(1);
571 EXPECT_EQ(tabBarPattern_->ProvideRestoreInfo(), "{\"Index\":1}");
572 }
573
574 /**
575 * @tc.name: Create003
576 * @tc.desc: test SetEdgeEffect
577 * @tc.type: FUNC
578 */
579 HWTEST_F(TabsTestNg, Create003, TestSize.Level1)
580 {
581 /**
582 * @tc.steps: step1. Construct TabContentModelNG object
583 */
584 int32_t testIndex = 0;
585 TabsModelNG model = CreateTabs(BarPosition::END, testIndex);
586 CreateTabContents(TABCONTENT_NUMBER);
587 CreateTabsDone(model);
588
589 /**
590 * @tc.steps: step2. Test function Create.
591 * @tc.expected: TestIndex greater than or equal to 0
592 */
593 swiperPaintProperty_->UpdateEdgeEffect(EdgeEffect::SPRING);
594 EXPECT_TRUE(testIndex >= 0);
595 }
596
597 /**
598 * @tc.name: TabsPatternParseJsonString002
599 * @tc.desc: test ParseJsonString
600 * @tc.type: FUNC
601 */
602 HWTEST_F(TabsTestNg, TabsPatternOnRestoreInfo002, TestSize.Level1)
603 {
604 /**
605 * @tc.steps: step1. Function OnRestoreInfo is called.
606 * @tc.expected: Passing invalid & valid JSON format.
607 */
608 TabsModelNG model = CreateTabs(BarPosition::END);
609 CreateTabContents(TABCONTENT_NUMBER);
610 CreateTabsDone(model);
611 pattern_->OnRestoreInfo("");
612 auto info = JsonUtil::ParseJsonString("");
613 EXPECT_FALSE(info->IsObject());
614 }
615
616 /**
617 * @tc.name: TabsPatternSetOnAnimationEnd002
618 * @tc.desc: test Measure
619 * @tc.type: FUNC
620 */
621 HWTEST_F(TabsTestNg, TabsPatternSetOnAnimationEnd002, TestSize.Level1)
622 {
__anon162bc9530502(int32_t index, int32_t targetIndex, const AnimationCallbackInfo& info) 623 auto onAnimationStart = [](int32_t index, int32_t targetIndex, const AnimationCallbackInfo& info) {};
__anon162bc9530602(int32_t index, const AnimationCallbackInfo& info) 624 auto onAnimationEnd = [](int32_t index, const AnimationCallbackInfo& info) {};
625 TabsModelNG model = CreateTabs();
626 model.SetOnAnimationStart(std::move(onAnimationStart));
627 model.SetOnAnimationEnd(std::move(onAnimationEnd));
628 CreateTabContents(TABCONTENT_NUMBER);
629 CreateTabsDone(model);
630
631 /**
632 * @tc.steps: step2.2. Test SetOnAnimationEnd function.
633 * @tc.expected:pattern_->animationEndEvent_ not null.
634 */
635 tabBarPattern_->InitTurnPageRateEvent();
636 int32_t testswipingIndex = 1;
637 float testturnPageRate = 1.0f;
638 swiperController_->GetTurnPageRateCallback()(testswipingIndex, testturnPageRate);
639
640 /**
641 * @tc.steps: step1. Convert lvalue to rvalue reference using std:: move()
642 */
643 EXPECT_NE(pattern_->animationEndEvent_, nullptr);
644 pattern_->SetAnimationEndEvent(std::move(*tabBarPattern_->animationEndEvent_));
645 EXPECT_NE(pattern_->animationEndEvent_, nullptr);
646 }
647
648 /**
649 * @tc.name: TabsPatternGetAxis003
650 * @tc.desc: test GetAxis
651 * @tc.type: FUNC
652 */
653 HWTEST_F(TabsTestNg, TabsPatternGetAxis003, TestSize.Level1)
654 {
655 TabsModelNG model = CreateTabs();
656 CreateTabContents(TABCONTENT_NUMBER);
657 CreateTabsDone(model);
658
659 /**
660 * @tc.steps: steps2. GetScopeFocusAlgorithm
661 * @tc.expected: steps2. Check the result of GetScopeFocusAlgorithm
662 */
663 layoutProperty_->UpdateAxis(Axis::HORIZONTAL);
664 pattern_->GetScopeFocusAlgorithm();
665 EXPECT_EQ(layoutProperty_->GetAxis().value(), Axis::HORIZONTAL);
666
667 layoutProperty_->UpdateAxis(Axis::VERTICAL);
668 pattern_->GetScopeFocusAlgorithm();
669 EXPECT_EQ(layoutProperty_->GetAxis().value(), Axis::VERTICAL);
670
671 layoutProperty_->UpdateAxis(Axis::FREE);
672 pattern_->GetScopeFocusAlgorithm();
673 EXPECT_EQ(layoutProperty_->GetAxis().value(), Axis::FREE);
674
675 layoutProperty_->UpdateAxis(Axis::NONE);
676 pattern_->GetScopeFocusAlgorithm();
677 EXPECT_EQ(layoutProperty_->GetAxis().value(), Axis::NONE);
678 }
679
680 /**
681 * @tc.name: TabsPatternGetScopeFocusAlgorithm004
682 * @tc.desc: test GetScopeFocusAlgorithm
683 * @tc.type: FUNC
684 */
685 HWTEST_F(TabsTestNg, TabsPatternGetScopeFocusAlgorithm004, TestSize.Level1)
686 {
687 /**
688 * @tc.steps: steps2. GetScopeFocusAlgorithm
689 * @tc.expected: steps2. Check the result of GetScopeFocusAlgorithm
690 */
691 TabsModelNG model = CreateTabs();
692 CreateTabContents(TABCONTENT_NUMBER);
693 CreateTabsDone(model);
694 layoutProperty_->Reset();
695 pattern_->GetScopeFocusAlgorithm();
696 EXPECT_FALSE(layoutProperty_->GetAxis().has_value());
697 }
698
699 /**
700 * @tc.name: CustomAnimationTest001
701 * @tc.desc: test custom animation disable swipe
702 * @tc.type: FUNC
703 */
704 HWTEST_F(TabsTestNg, CustomAnimationTest001, TestSize.Level1)
705 {
706 TabsModelNG model = CreateTabs(BarPosition::START, 1);
707 model.SetIsCustomAnimation(true);
__anon162bc9530702(int32_t from, int32_t to) 708 model.SetOnCustomAnimation([](int32_t from, int32_t to) -> TabContentAnimatedTransition {
709 TabContentAnimatedTransition transitionInfo;
710 transitionInfo.transition = [](const RefPtr<TabContentTransitionProxy>& proxy) {};
711 return transitionInfo;
712 });
713 CreateTabContentsWithBuilder(TABCONTENT_NUMBER);
714 CreateTabsDone(model);
715
716 tabBarLayoutProperty_->UpdateAxis(Axis::VERTICAL);
717 EXPECT_EQ(tabBarLayoutProperty_->GetAxisValue(), Axis::VERTICAL);
718 tabBarPattern_->tabBarStyle_ = TabBarStyle::SUBTABBATSTYLE;
719 tabBarPattern_->visibleItemPosition_[0] = { 0.0f, 10.0f };
720 swiperLayoutProperty_->UpdateIndex(1);
721 GestureEvent info;
722 Offset offset(1, 1);
723 info.SetLocalLocation(offset);
724 tabBarLayoutProperty_->UpdateAxis(Axis::HORIZONTAL);
725 tabBarPattern_->HandleClick(info.GetSourceDevice(), 0);
726 EXPECT_TRUE(swiperPattern_->IsDisableSwipe());
727 EXPECT_TRUE(swiperPattern_->customAnimationToIndex_.has_value());
728
729 swiperPattern_->OnCustomAnimationFinish(1, 0, false);
730 EXPECT_FALSE(swiperPattern_->customAnimationToIndex_.has_value());
731
732 swiperPattern_->SwipeTo(1);
733 EXPECT_TRUE(swiperPattern_->customAnimationToIndex_.has_value());
734 }
735
736 /**
737 * @tc.name: CustomAnimationTest002
738 * @tc.desc: test custom animation set undefined
739 * @tc.type: FUNC
740 */
741 HWTEST_F(TabsTestNg, CustomAnimationTest002, TestSize.Level1)
742 {
743 TabsModelNG model = CreateTabs();
744 model.SetIsCustomAnimation(false);
745 CreateTabContents(TABCONTENT_NUMBER);
746 CreateTabsDone(model);
747 EXPECT_FALSE(swiperPattern_->IsDisableSwipe());
748 }
749
750 /**
751 * @tc.name: DragSwiper001
752 * @tc.desc: Could drag swiper, change tabBar index
753 * @tc.type: FUNC
754 */
755 HWTEST_F(TabsTestNg, DragSwiper001, TestSize.Level1)
756 {
757 MockAnimationManager::Enable(true);
758 MockAnimationManager::GetInstance().SetTicks(1);
759 TabsModelNG model = CreateTabs();
760 CreateTabContents(TABCONTENT_NUMBER);
761 CreateTabsDone(model);
762 EXPECT_TRUE(swiperPattern_->panEvent_);
763
764 GestureEvent info = CreateDragInfo(true);
765 swiperPattern_->HandleDragStart(info);
766 swiperPattern_->HandleDragUpdate(info);
767 FlushUITasks();
768 swiperPattern_->HandleDragEnd(info.GetMainVelocity());
769 FlushUITasks();
770 MockAnimationManager::GetInstance().Tick();
771 FlushUITasks();
772 EXPECT_TRUE(CurrentIndex(1));
773 MockAnimationManager::Enable(false);
774 }
775
776 /**
777 * @tc.name: DragSwiper002
778 * @tc.desc: Set BOTTOMTABBATSTYLE, Test drag swiper, would change tabBar index
779 * @tc.type: FUNC
780 */
781 HWTEST_F(TabsTestNg, DragSwiper002, TestSize.Level1)
782 {
783 MockAnimationManager::Enable(true);
784 MockAnimationManager::GetInstance().SetTicks(1);
785 TabsModelNG model = CreateTabs();
786 // set BOTTOMTABBATSTYLE
787 CreateTabContentTabBarStyle(TabBarStyle::BOTTOMTABBATSTYLE);
788 CreateTabContentTabBarStyle(TabBarStyle::BOTTOMTABBATSTYLE);
789 CreateTabsDone(model);
790
791 GestureEvent info = CreateDragInfo(true);
792 swiperPattern_->HandleDragStart(info);
793 swiperPattern_->HandleDragUpdate(info);
794 FlushUITasks();
795 swiperPattern_->HandleDragEnd(info.GetMainVelocity());
796 FlushUITasks();
797 MockAnimationManager::GetInstance().Tick();
798 FlushUITasks();
799 EXPECT_TRUE(CurrentIndex(1));
800 MockAnimationManager::Enable(false);
801 }
802
803 /**
804 * @tc.name: DragSwiper003
805 * @tc.desc: SetScrollable to false, could not drag to change page
806 * @tc.type: FUNC
807 */
808 HWTEST_F(TabsTestNg, DragSwiper003, TestSize.Level1)
809 {
810 TabsModelNG model = CreateTabs();
811 // SetScrollable to false, could not drag to change page
812 model.SetScrollable(false);
813 CreateTabContents(TABCONTENT_NUMBER);
814 CreateTabsDone(model);
815 EXPECT_FALSE(swiperPattern_->panEvent_);
816 }
817
818 /**
819 * @tc.name: OnColorModeChangeTest001
820 * @tc.desc: Test Tabs OnColorModeChange
821 * @tc.type: FUNC
822 */
823 HWTEST_F(TabsTestNg, OnColorModeChangeTest001, TestSize.Level1)
824 {
825 g_isConfigChangePerform = true;
826
827 /**
828 * @tc.steps: step1. create tabs and set parameters.
829 */
830 TabsModelNG model = CreateTabs();
831 CreateTabContents(TABCONTENT_NUMBER);
832 CreateTabsDone(model);
833 ASSERT_NE(pattern_, nullptr);
834 ASSERT_NE(layoutProperty_, nullptr);
835 ASSERT_NE(dividerRenderProperty_, nullptr);
836
837 /**
838 * @tc.steps: step2. reset data.
839 */
840 int32_t colorMode = static_cast<int32_t>(ColorMode::DARK);
841 layoutProperty_->ResetDividerColorSetByUser();
842 dividerRenderProperty_->ResetDividerColor();
843 pattern_->OnColorModeChange(colorMode);
844 EXPECT_TRUE(dividerRenderProperty_->HasDividerColor());
845
846 layoutProperty_->UpdateDividerColorSetByUser(false);
847 dividerRenderProperty_->ResetDividerColor();
848 pattern_->OnColorModeChange(colorMode);
849 EXPECT_TRUE(dividerRenderProperty_->HasDividerColor());
850
851 layoutProperty_->UpdateDividerColorSetByUser(true);
852 dividerRenderProperty_->ResetDividerColor();
853 pattern_->OnColorModeChange(colorMode);
854 EXPECT_FALSE(dividerRenderProperty_->HasDividerColor());
855
856 g_isConfigChangePerform = false;
857 }
858
859 /**
860 * @tc.name: TabContentCreatePaddingWithResourceObj001
861 * @tc.desc: test CreatePaddingWithResourceObj of TabContentModelNG
862 * @tc.type: FUNC
863 */
864 HWTEST_F(TabsTestNg, TabContentCreatePaddingWithResourceObj001, TestSize.Level1)
865 {
866 CreateTabContent();
867 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
868 ASSERT_NE(frameNode, nullptr);
869
870 EXPECT_TRUE(TabContentModelNG::CreatePaddingLeftWithResourceObj(frameNode, nullptr));
871 EXPECT_TRUE(TabContentModelNG::CreatePaddingRightWithResourceObj(frameNode, nullptr));
872 EXPECT_TRUE(TabContentModelNG::CreatePaddingTopWithResourceObj(frameNode, nullptr));
873 EXPECT_TRUE(TabContentModelNG::CreatePaddingBottomWithResourceObj(frameNode, nullptr));
874 EXPECT_TRUE(TabContentModelNG::CreatePaddingWithResourceObj(frameNode, nullptr));
875 EXPECT_TRUE(TabContentModelNG::CreateTextContentWithResourceObj(frameNode, nullptr));
876 EXPECT_TRUE(TabContentModelNG::CreateIconWithResourceObjWithKey(frameNode, "", nullptr));
877 EXPECT_TRUE(TabContentModelNG::CreateBoardStyleBorderRadiusWithResourceObj(frameNode, nullptr));
878 EXPECT_TRUE(TabContentModelNG::CreateIndicatorColorWithResourceObj(frameNode, nullptr));
879 EXPECT_TRUE(TabContentModelNG::CreateIndicatorHeightWithResourceObj(frameNode, nullptr));
880 EXPECT_TRUE(TabContentModelNG::CreateIndicatorWidthWithResourceObj(frameNode, nullptr));
881 EXPECT_TRUE(TabContentModelNG::CreateIndicatorBorderRadiusWithResourceObj(frameNode, nullptr));
882 EXPECT_TRUE(TabContentModelNG::CreateIndicatorMarginTopWithResourceObj(frameNode, nullptr));
883
884 RefPtr<ResourceObject> resObj = AceType::MakeRefPtr<ResourceObject>("", "", Container::CurrentIdSafely());
885 RefPtr<ResourceObject> resObjLeft = AceType::MakeRefPtr<ResourceObject>("", "", Container::CurrentIdSafely());
886 RefPtr<ResourceObject> resObjRight = AceType::MakeRefPtr<ResourceObject>("", "", Container::CurrentIdSafely());
887 RefPtr<ResourceObject> resObjTop = AceType::MakeRefPtr<ResourceObject>("", "", Container::CurrentIdSafely());
888 RefPtr<ResourceObject> resObjBottom = AceType::MakeRefPtr<ResourceObject>("", "", Container::CurrentIdSafely());
889
890 EXPECT_TRUE(TabContentModelNG::CreatePaddingLeftWithResourceObj(frameNode, resObjLeft));
891 EXPECT_TRUE(TabContentModelNG::CreatePaddingRightWithResourceObj(frameNode, resObjRight));
892 EXPECT_TRUE(TabContentModelNG::CreatePaddingTopWithResourceObj(frameNode, resObjTop));
893 EXPECT_TRUE(TabContentModelNG::CreatePaddingBottomWithResourceObj(frameNode, resObjBottom));
894 EXPECT_TRUE(TabContentModelNG::CreatePaddingWithResourceObj(frameNode, resObj));
895 EXPECT_TRUE(TabContentModelNG::CreateTextContentWithResourceObj(frameNode, resObj));
896 EXPECT_TRUE(TabContentModelNG::CreateIconWithResourceObjWithKey(frameNode, "", resObj));
897 EXPECT_TRUE(TabContentModelNG::CreateBoardStyleBorderRadiusWithResourceObj(frameNode, resObj));
898 EXPECT_TRUE(TabContentModelNG::CreateIndicatorColorWithResourceObj(frameNode, resObj));
899 EXPECT_TRUE(TabContentModelNG::CreateIndicatorHeightWithResourceObj(frameNode, resObj));
900 EXPECT_TRUE(TabContentModelNG::CreateIndicatorWidthWithResourceObj(frameNode, resObj));
901 EXPECT_TRUE(TabContentModelNG::CreateIndicatorBorderRadiusWithResourceObj(frameNode, resObj));
902 EXPECT_TRUE(TabContentModelNG::CreateIndicatorMarginTopWithResourceObj(frameNode, resObj));
903 }
904 } // namespace OHOS::Ace::NG
905