1 /*
2 * Copyright (c) 2023 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 <cstddef>
17 #include <cstdint>
18 #include <unistd.h>
19
20 #include "gtest/gtest.h"
21
22 #define private public
23 #define protected public
24 #include "core/components_ng/event/state_style_manager.h"
25 #include "core/components_ng/pattern/list/list_pattern.h"
26 #include "core/components_ng/pattern/pattern.h"
27 #include "test/mock/base/mock_task_executor.h"
28 #include "test/mock/core/pipeline/mock_pipeline_context.h"
29
30 using namespace testing;
31 using namespace testing::ext;
32
33 namespace OHOS::Ace::NG {
34 class StateStyleManagerTestNg : public testing::Test {
35 public:
36 static void SetUpTestSuite();
37 static void TearDownTestSuite();
38 void SetUp() override;
39 void TearDown() override;
40 };
41
SetUpTestSuite()42 void StateStyleManagerTestNg::SetUpTestSuite()
43 {
44 GTEST_LOG_(INFO) << "StateStyleManagerTestNg SetUpTestCase";
45 }
46
TearDownTestSuite()47 void StateStyleManagerTestNg::TearDownTestSuite()
48 {
49 GTEST_LOG_(INFO) << "StateStyleManagerTestNg TearDownTestCase";
50 }
51
SetUp()52 void StateStyleManagerTestNg::SetUp()
53 {
54 MockPipelineContext::SetUp();
55 }
56
TearDown()57 void StateStyleManagerTestNg::TearDown()
58 {
59 MockPipelineContext::TearDown();
60 }
61
62 /**
63 * @tc.name: StateStyleTest001
64 * @tc.desc: Create StateStyleManager and execute pressed listener.
65 * @tc.type: FUNC
66 */
67 HWTEST_F(StateStyleManagerTestNg, StateStyleTest001, TestSize.Level1)
68 {
69 /**
70 * @tc.steps: step1. Create state style manger.
71 * @tc.expected: State style pressed listener is valid.
72 */
73 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
74 EXPECT_NE(frameNode, nullptr);
75 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
76 EXPECT_NE(stateStyleMgr, nullptr);
77 stateStyleMgr->SetSupportedStates(UI_STATE_PRESSED);
78 auto callback = stateStyleMgr->GetPressedListener();
79 EXPECT_NE(callback, nullptr);
80
81 /**
82 * @tc.steps: step2. Create touch down event and execute it.
83 * @tc.expected: Should change to pressed state.
84 */
85
86 TouchEventInfo touchEventInfo = TouchEventInfo("touch");
87 TouchLocationInfo touchLocationInfo = TouchLocationInfo(1);
88 touchLocationInfo.SetLocalLocation(Offset(100.0, 100.0));
89 touchLocationInfo.SetTouchType(TouchType::DOWN);
90 touchEventInfo.AddTouchLocationInfo(std::move(touchLocationInfo));
91 touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
92
93 (*callback)(touchEventInfo);
94 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
95
96 /**
97 * @tc.steps: step3. Create touch up event and execute it.
98 * @tc.expected: Should cancel pressed state.
99 */
100
101 touchLocationInfo.SetTouchType(TouchType::UP);
102 touchEventInfo.AddTouchLocationInfo(std::move(touchLocationInfo));
103 touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
104
105 (*callback)(touchEventInfo);
106 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
107 }
108
109 /**
110 * @tc.name: StateStyleTest002
111 * @tc.desc: Create StateStyleManager and execute pressed listener when multi fingers.
112 * @tc.type: FUNC
113 */
114 HWTEST_F(StateStyleManagerTestNg, StateStyleTest002, TestSize.Level1)
115 {
116 /**
117 * @tc.steps: step1. Create state style manger.
118 * @tc.expected: State style pressed listener is valid.
119 */
120 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
121 EXPECT_NE(frameNode, nullptr);
122 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
123 EXPECT_NE(stateStyleMgr, nullptr);
124 stateStyleMgr->SetSupportedStates(UI_STATE_PRESSED);
125 auto callback = stateStyleMgr->GetPressedListener();
126 EXPECT_NE(callback, nullptr);
127
128 /**
129 * @tc.steps: step2. One finger touch down.
130 * @tc.expected: Should change to pressed state.
131 */
132
133 TouchEventInfo touchEventInfo = TouchEventInfo("touch");
134 TouchLocationInfo touchLocationInfo1 = TouchLocationInfo(1);
135 touchLocationInfo1.SetLocalLocation(Offset(100.0, 100.0));
136 touchLocationInfo1.SetTouchType(TouchType::DOWN);
137 touchEventInfo.AddTouchLocationInfo(std::move(touchLocationInfo1));
138 touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo1));
139
140 (*callback)(touchEventInfo);
141 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
142
143 /**
144 * @tc.steps: step3. One more finger touch down.
145 * @tc.expected: Should hold on pressed state.
146 */
147
148 TouchLocationInfo touchLocationInfo2 = TouchLocationInfo(2);
149 touchLocationInfo2.SetLocalLocation(Offset(100.0, 100.0));
150 touchLocationInfo2.SetTouchType(TouchType::DOWN);
151 touchEventInfo.AddTouchLocationInfo(std::move(touchLocationInfo2));
152 touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo2));
153
154 (*callback)(touchEventInfo);
155 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
156
157 /**
158 * @tc.steps: step4. One finger touch up.
159 * @tc.expected: Should hold on pressed state.
160 */
161
162 touchLocationInfo1.SetTouchType(TouchType::UP);
163 touchEventInfo.AddTouchLocationInfo(std::move(touchLocationInfo1));
164 touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo1));
165
166 (*callback)(touchEventInfo);
167 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
168
169 /**
170 * @tc.steps: step5. One more finger touch up.
171 * @tc.expected: Should cancel pressed state.
172 */
173
174 touchLocationInfo2.SetTouchType(TouchType::UP);
175 touchEventInfo.AddTouchLocationInfo(std::move(touchLocationInfo2));
176 touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo2));
177
178 (*callback)(touchEventInfo);
179 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
180 }
181
182 /**
183 * @tc.name: StateStyleTest003
184 * @tc.desc: Create StateStyleManager and execute its functions.
185 * @tc.type: FUNC
186 */
187 HWTEST_F(StateStyleManagerTestNg, StateStyleTest003, TestSize.Level1)
188 {
189 /**
190 * @tc.steps: step1. Create state style manger.
191 * @tc.expected: Should have no scrolling parent.
192 */
193 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
194 EXPECT_NE(frameNode, nullptr);
195 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
196 EXPECT_NE(stateStyleMgr, nullptr);
197 stateStyleMgr->HandleScrollingParent();
198 bool hasScrollingParent = stateStyleMgr->GetHasScrollingParent();
199 EXPECT_EQ(false, hasScrollingParent);
200
201 /**
202 * @tc.steps: step2. Set parent to current frame node.
203 * @tc.expected: Should have scrolling parent.
204 */
205
206 auto parent = AceType::MakeRefPtr<FrameNode>(V2::LIST_ETS_TAG, -1, AceType::MakeRefPtr<ListPattern>());
207 EXPECT_NE(parent, nullptr);
208 frameNode->SetParent(parent);
209 stateStyleMgr->HandleScrollingParent();
210 hasScrollingParent = stateStyleMgr->GetHasScrollingParent();
211 EXPECT_EQ(true, hasScrollingParent);
212 }
213
214 HWTEST_F(StateStyleManagerTestNg, StateStyleTest004, TestSize.Level1)
215 {
216 /**
217 * @tc.steps: step1. Create state style manger.
218 * @tc.expected: State style pressed listener is valid.
219 */
220 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
221 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
222 stateStyleMgr->SetSupportedStates(UI_STATE_PRESSED);
223 auto callback = stateStyleMgr->GetPressedListener();
224 EXPECT_NE(callback, nullptr);
225 auto callback2 = stateStyleMgr->GetPressedListener();
226 EXPECT_EQ(callback, callback2);
227
228 /**
229 * @tc.steps: step2. Create condition that touches.empty() changeTouches.empty()
230 * @tc.expected: State style pressed listener is valid.
231 */
232 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
233 TouchEventInfo touchEventInfo = TouchEventInfo("touch");
234 (*callback)(touchEventInfo);
235 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
236
237 /**
238 * @tc.steps: step3. Create condition that touches.empty()=false changeTouches.empty true
239 * @tc.expected: State style pressed listener is valid.
240 */
241 TouchLocationInfo touchLocationInfo = TouchLocationInfo(1);
242 touchLocationInfo.SetLocalLocation(Offset(100.0, 100.0));
243 touchLocationInfo.SetTouchType(TouchType::CANCEL);
244 touchEventInfo.AddTouchLocationInfo(std::move(touchLocationInfo));
245 stateStyleMgr->SetSupportedStates(UI_STATE_PRESSED);
246 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
247 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
248 (*callback)(touchEventInfo);
249 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
250
251 /**
252 * @tc.steps: step3. Create condition that touches.empty false changeTouches.empty false
253 * @tc.expected: State style pressed listener is valid.
254 */
255 touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
256 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
257 (*callback)(touchEventInfo);
258 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
259 }
260
261 HWTEST_F(StateStyleManagerTestNg, StateStyleTest005, TestSize.Level1)
262 {
263 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
264 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
265 auto callback = stateStyleMgr->GetPressedListener();
266 EXPECT_NE(callback, nullptr);
267 auto callback2 = stateStyleMgr->GetPressedListener();
268 EXPECT_EQ(callback, callback2);
269
270 TouchEventInfo touchEventInfo = TouchEventInfo("touch");
271 TouchLocationInfo touchLocationInfo = TouchLocationInfo(1);
272 touchLocationInfo.SetLocalLocation(Offset(-100.0, -100.0));
273 touchLocationInfo.SetTouchType(TouchType::MOVE);
274 touchEventInfo.AddTouchLocationInfo(std::move(touchLocationInfo));
275 touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
276 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
277 stateStyleMgr->ResetPressedPendingState();
278 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
279 (*callback)(touchEventInfo);
280 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
281
282 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, false);
283 stateStyleMgr->ResetPressedPendingState();
284 (*callback)(touchEventInfo);
285 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
286 }
287
288 HWTEST_F(StateStyleManagerTestNg, HandleTouchDown, TestSize.Level1)
289 {
290 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
291 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
292 stateStyleMgr->SetSupportedStates(UI_STATE_NORMAL);
293 stateStyleMgr->HandleTouchDown();
294 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
295
296 stateStyleMgr->SetSupportedStates(UI_STATE_PRESSED);
297 stateStyleMgr->HandleTouchDown();
298 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
299
300 auto parent = AceType::MakeRefPtr<FrameNode>(V2::LIST_ETS_TAG, -1, AceType::MakeRefPtr<ListPattern>());
301 EXPECT_NE(parent, nullptr);
302 frameNode->SetParent(parent);
303 stateStyleMgr->PendingCancelPressedState();
304 EXPECT_EQ(true, stateStyleMgr->IsPressedCancelStatePending());
305 stateStyleMgr->HandleTouchDown();
306 EXPECT_EQ(false, stateStyleMgr->IsPressedCancelStatePending());
307 EXPECT_EQ(true, stateStyleMgr->IsPressedStatePending());
308
309 stateStyleMgr->ResetPressedCancelPendingState();
310 stateStyleMgr->HandleTouchDown();
311 EXPECT_EQ(false, stateStyleMgr->IsPressedCancelStatePending());
312 EXPECT_EQ(true, stateStyleMgr->IsPressedStatePending());
313 }
314
315 HWTEST_F(StateStyleManagerTestNg, HandleTouchUp, TestSize.Level1)
316 {
317 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
318 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
319 auto parent = AceType::MakeRefPtr<FrameNode>(V2::LIST_ETS_TAG, -1, AceType::MakeRefPtr<ListPattern>());
320 EXPECT_NE(parent, nullptr);
321 frameNode->SetParent(parent);
322
323 stateStyleMgr->PendingPressedState();
324 stateStyleMgr->SetSupportedStates(UI_STATE_PRESSED);
325 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
326 stateStyleMgr->HandleTouchUp();
327 EXPECT_EQ(false, stateStyleMgr->IsPressedStatePending());
328 EXPECT_EQ(true, stateStyleMgr->IsPressedCancelStatePending());
329 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
330
331 stateStyleMgr->ResetPressedPendingState();
332 stateStyleMgr->ResetPressedCancelPendingState();
333 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
334 stateStyleMgr->HandleTouchUp();
335 EXPECT_EQ(false, stateStyleMgr->IsPressedStatePending());
336 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
337
338 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
339 stateStyleMgr->PendingCancelPressedState();
340 stateStyleMgr->HandleTouchUp();
341 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
342 }
343
344 HWTEST_F(StateStyleManagerTestNg, PostPressStyleTask, TestSize.Level1)
345 {
346 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
347 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
348 stateStyleMgr->PendingPressedState();
349 EXPECT_EQ(true, stateStyleMgr->IsPressedStatePending());
350 stateStyleMgr->SetSupportedStates(UI_STATE_PRESSED);
351 auto context = PipelineContext::GetCurrentContext();
352 ASSERT_NE(context, nullptr);
353 context->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
354 auto taskExecutor = context->GetTaskExecutor();
355 ASSERT_NE(taskExecutor, nullptr);
356 stateStyleMgr->PostPressStyleTask(1);
357 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
358
359 stateStyleMgr->ResetPressedPendingState();
360 stateStyleMgr->ResetPressedCancelPendingState();
361 EXPECT_EQ(false, stateStyleMgr->IsPressedStatePending());
362 stateStyleMgr->PostPressStyleTask(1);
363 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
364 }
365
366 HWTEST_F(StateStyleManagerTestNg, PostPressCancelStyleTask, TestSize.Level1)
367 {
368 auto frameNode = AceType::MakeRefPtr<FrameNode>(V2::BUTTON_ETS_TAG, -1, AceType::MakeRefPtr<Pattern>());
369 auto stateStyleMgr = AceType::MakeRefPtr<StateStyleManager>(frameNode);
370 auto context = PipelineContext::GetCurrentContext();
371 ASSERT_NE(context, nullptr);
372 context->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
373 auto taskExecutor = context->GetTaskExecutor();
374 ASSERT_NE(taskExecutor, nullptr);
375
376 stateStyleMgr->SetSupportedStates(UI_STATE_PRESSED);
377 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
378
379 stateStyleMgr->PendingPressedState();
380 stateStyleMgr->PendingCancelPressedState();
381 stateStyleMgr->PostPressCancelStyleTask(1);
382 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
383
384 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
385 stateStyleMgr->ResetPressedPendingState();
386 stateStyleMgr->PendingCancelPressedState();
387 stateStyleMgr->PostPressCancelStyleTask(1);
388 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
389
390 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
391 stateStyleMgr->PendingPressedState();
392 stateStyleMgr->ResetPressedCancelPendingState();
393 stateStyleMgr->PostPressCancelStyleTask(1);
394 EXPECT_EQ(true, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
395
396 stateStyleMgr->SetCurrentUIState(UI_STATE_PRESSED, true);
397 stateStyleMgr->ResetPressedPendingState();
398 stateStyleMgr->ResetPressedCancelPendingState();
399 stateStyleMgr->PostPressCancelStyleTask(1);
400 EXPECT_EQ(false, stateStyleMgr->IsCurrentStateOn(UI_STATE_PRESSED));
401 }
402 } // namespace OHOS::Ace::NG
403