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