1 /*
2 * SPDX-License-Identifier: Apache-2.0
3 * Copyright (c) 2025 Huawei Device Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "gtest/gtest.h"
17
18 #define private public
19 #define protected public
20 #include "test/mock/core/common/mock_resource_adapter.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/unittest/core/event/focus_core/focus_area_test.h"
25 #include "test/unittest/core/event/frame_node_on_tree.h"
26 #include "test/unittest/core/pattern/test_ng.h"
27
28 #include "base/log/log_wrapper.h"
29 #include "core/components/container_modal/container_modal_constants.h"
30 #include "core/components/theme/app_theme.h"
31 #include "core/components/theme/theme_constants.h"
32 #include "core/components_ng/base/ui_node.h"
33 #include "core/components_ng/base/view_stack_processor.h"
34 #include "core/components_ng/event/focus_box.h"
35 #include "core/components_ng/event/focus_hub.h"
36 #include "core/components_ng/pattern/button/button_pattern.h"
37 #include "core/components_ng/pattern/container_modal/container_modal_pattern.h"
38 #include "core/components_ng/pattern/container_modal/container_modal_theme.h"
39 #include "core/components_ng/pattern/container_modal/container_modal_view.h"
40 #include "core/components_ng/pattern/image/image_layout_property.h"
41 #include "core/components_ng/pattern/image/image_pattern.h"
42 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
43 #include "core/components_ng/pattern/pattern.h"
44 #include "core/components_ng/pattern/root/root_pattern.h"
45 #include "core/components_ng/pattern/stack/stack_pattern.h"
46 #include "core/components_ng/pattern/text/text_pattern.h"
47 #include "core/components_ng/pattern/text_picker/textpicker_column_pattern.h"
48 #include "core/pipeline_ng/pipeline_context.h"
49
50 using namespace testing;
51 using namespace testing::ext;
52 namespace OHOS::Ace::NG {
53 int32_t childSize = 4;
54 const std::vector<FocusAreaTestCase> FOCUS_AREA_CASES = {
55 // case1
56 FocusAreaTestCase(true, false, FocusStep::TAB,
57 FocusAreaNodeOffset { 10.0f, 60.0f, 120.0f, 0.0f, 120.0f, 120.0f, 180.0f, 130.0f }),
58 // case2
59 FocusAreaTestCase(
60 true, true, FocusStep::TAB, FocusAreaNodeOffset { 10.0f, 60.0f, 120.0f, 0.0f, 120.0f, 80.0f, 180.0f, 130.0f }),
61 // case3
62 FocusAreaTestCase(
63 true, true, FocusStep::TAB, FocusAreaNodeOffset { 10.0f, 60.0f, 120.0f, 0.0f, 120.0f, 80.0f, 200.0f, 60.0f }),
64 // case4
65 FocusAreaTestCase(
66 true, false, FocusStep::UP, FocusAreaNodeOffset { 110.0f, 160.0f, 230.0f, 0.0f, 0.0f, 0.0f, 230.0f, 80.0f }),
67 // case5
68 FocusAreaTestCase(
69 true, true, FocusStep::UP, FocusAreaNodeOffset { 110.0f, 160.0f, 230.0f, 0.0f, 0.0f, 0.0f, 180.0f, 80.0f }),
70 // case6
71 FocusAreaTestCase(
72 true, true, FocusStep::UP, FocusAreaNodeOffset { 110.0f, 160.0f, 190.0f, 40.0f, 0.0f, 0.0f, 160.0f, 60.0f }),
73 // case7
74 FocusAreaTestCase(
75 true, false, FocusStep::DOWN, FocusAreaNodeOffset { 110.0f, 160.0f, 230.0f, 0.0f, 0.0f, 0.0f, 230.0f, 80.0f }),
76 // case8
77 FocusAreaTestCase(
78 true, true, FocusStep::DOWN, FocusAreaNodeOffset { 110.0f, 160.0f, 230.0f, 0.0f, 0.0f, 0.0f, 180.0f, 80.0f }),
79 // case9
80 FocusAreaTestCase(
81 true, true, FocusStep::DOWN, FocusAreaNodeOffset { 110.0f, 160.0f, 160.0f, 60.0f, 0.0f, 0.0f, 190.0f, 40.0f }),
82 // case10
83 FocusAreaTestCase(
84 true, false, FocusStep::LEFT, FocusAreaNodeOffset { 210.0f, 60.0f, 0.0f, 180.0f, 0.0f, 0.0f, 110.0f, 0.0f }),
85 // case11
86 FocusAreaTestCase(
87 true, true, FocusStep::LEFT, FocusAreaNodeOffset { 210.0f, 60.0f, 0.0f, 180.0f, 0.0f, 0.0f, 110.0f, 40.0f }),
88 // case12
89 FocusAreaTestCase(
90 true, true, FocusStep::LEFT, FocusAreaNodeOffset { 210.0f, 60.0f, 0.0f, 180.0f, 0.0f, 30.0f, 110.0f, 40.0f }),
91 // case13
92 FocusAreaTestCase(true, false, FocusStep::RIGHT,
93 FocusAreaNodeOffset { 10.0f, 60.0f, 120.0f, 0.0f, 120.0f, 120.0f, 180.0f, 130.0f }),
94 // case14
95 FocusAreaTestCase(true, true, FocusStep::RIGHT,
96 FocusAreaNodeOffset { 10.0f, 60.0f, 120.0f, 0.0f, 120.0f, 80.0f, 180.0f, 130.0f }),
97 // case15
98 FocusAreaTestCase(
99 true, true, FocusStep::RIGHT, FocusAreaNodeOffset { 10.0f, 60.0f, 120.0f, 0.0f, 120.0f, 80.0f, 200.0f, 60.0f }),
100 };
101
SetUpTestSuite()102 void FocusAreaTestNG::SetUpTestSuite()
103 {
104 MockPipelineContext::SetUp();
105 GTEST_LOG_(INFO) << "FocusAreaTestNG SetUpTestCase";
106 }
107
TearDownTestSuite()108 void FocusAreaTestNG::TearDownTestSuite()
109 {
110 MockPipelineContext::TearDown();
111 GTEST_LOG_(INFO) << "FocusAreaTestNG TearDownTestCase";
112 }
CreatNode(float nodex,float nodey)113 RefPtr<FrameNode> FocusAreaTestNG::CreatNode(float nodex, float nodey)
114 {
115 auto node = AceType::MakeRefPtr<FrameNodeOnTree>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<ButtonPattern>());
116 node->geometryNode_ = AceType::MakeRefPtr<GeometryNode>();
117 node->geometryNode_->SetFrameOffset(OffsetF(nodex, nodey));
118 EXPECT_NE(node, nullptr);
119 return node;
120 }
CreatRootNode()121 RefPtr<FrameNode> FocusAreaTestNG::CreatRootNode()
122 {
123 auto rootNode = AceType::MakeRefPtr<FrameNodeOnTree>(V2::ROW_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
124 return rootNode;
125 }
InitFocusareaTest()126 void FocusAreaTestNG::InitFocusareaTest()
127 {
128 for (const auto& testCase : FOCUS_AREA_CASES) {
129 auto rootNode = CreatRootNode();
130 auto rootNodeFocusHub = rootNode->GetOrCreateFocusHub();
131 rootNodeFocusHub->focusAlgorithm_.scopeType = ScopeType::PROJECT_AREA;
132 auto nodeA = FocusAreaTestNG::CreatNode(testCase.nodeOffset.nodeAx, testCase.nodeOffset.nodeAy);
133 auto nodeB = FocusAreaTestNG::CreatNode(testCase.nodeOffset.nodeBx, testCase.nodeOffset.nodeBy);
134 auto nodeC = FocusAreaTestNG::CreatNode(testCase.nodeOffset.nodeCx, testCase.nodeOffset.nodeCy);
135 auto nodeD = FocusAreaTestNG::CreatNode(testCase.nodeOffset.nodeDx, testCase.nodeOffset.nodeDy);
136
137 auto focusHubA = nodeA->GetOrCreateFocusHub();
138 auto focusHubB = nodeB->GetOrCreateFocusHub();
139 auto focusHubC = nodeC->GetOrCreateFocusHub();
140 auto focusHubD = nodeD->GetOrCreateFocusHub();
141 rootNode->AddChild(nodeA);
142 rootNode->AddChild(nodeB);
143 rootNode->AddChild(nodeC);
144 rootNode->AddChild(nodeD);
145 std::list<RefPtr<FocusHub>> children;
146 rootNodeFocusHub->FlushChildrenFocusHub(children);
147 EXPECT_EQ(children.size(), childSize);
148 if (!testCase.isFocusBrotherNode) {
149 auto nextnode = focusHubA->GetNearestNodeByProjectArea(children, testCase.StepMethod);
150 CHECK_NULL_VOID(nextnode);
151 nextnode->TryRequestFocus(nextnode, RectF(), testCase.StepMethod);
152 EXPECT_TRUE(focusHubA->IsCurrentFocus());
153 }
154 if ((testCase.isFocusBrotherNode && testCase.StepMethod == FocusStep::TAB) ||
155 (testCase.isFocusBrotherNode && testCase.StepMethod == FocusStep::RIGHT)) {
156 auto nextnode = focusHubA->GetNearestNodeByProjectArea(children, testCase.StepMethod);
157 CHECK_NULL_VOID(nextnode);
158 nextnode->TryRequestFocus(nextnode, RectF(), testCase.StepMethod);
159 EXPECT_TRUE(focusHubC->IsCurrentFocus());
160 }
161 if ((testCase.isFocusBrotherNode && testCase.StepMethod == FocusStep::UP) ||
162 (testCase.isFocusBrotherNode && testCase.StepMethod == FocusStep::LEFT)) {
163 auto nextnode = focusHubA->GetNearestNodeByProjectArea(children, testCase.StepMethod);
164 CHECK_NULL_VOID(nextnode);
165 nextnode->TryRequestFocus(nextnode, RectF(), testCase.StepMethod);
166 EXPECT_TRUE(focusHubD->IsCurrentFocus());
167 }
168 if (testCase.isFocusBrotherNode && testCase.StepMethod == FocusStep::DOWN) {
169 auto nextnode = focusHubA->GetNearestNodeByProjectArea(children, testCase.StepMethod);
170 CHECK_NULL_VOID(nextnode);
171 nextnode->TryRequestFocus(nextnode, RectF(), testCase.StepMethod);
172 EXPECT_TRUE(focusHubB->IsCurrentFocus());
173 }
174 }
175 }
176 HWTEST_F(FocusAreaTestNG, FocusAreaTest001, TestSize.Level1)
177 {
178 bool initResult = InitFocusTestBaseNG();
179 EXPECT_TRUE(initResult);
180 InitFocusareaTest();
181 }
182 } // namespace OHOS::Ace::NG