• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <cmath>
17 #include "gtest/gtest.h"
18 #include "ui_action.h"
19 
20 using namespace OHOS::uitest;
21 using namespace std;
22 
23 static constexpr uint32_t CUSTOM_CLICK_HOLD_MS = 100;
24 static constexpr uint32_t CUSTOM_LONGCLICK_HOLD_MS = 200;
25 static constexpr uint32_t CUSTOM_DOUBLECLICK_HOLD_MS = 300;
26 static constexpr uint32_t CUSTOM_KEY_HOLD_MS = 400;
27 static constexpr uint32_t CUSTOM_SWIPE_VELOCITY_PPS = 500;
28 static constexpr uint32_t CUSTOM_UI_STEADY_MS = 600;
29 static constexpr uint32_t CUSTOM_WAIT_UI_STEADY_MS = 700;
30 
31 class UiActionTest : public testing::Test {
32 public:
33     ~UiActionTest() override = default;
34 protected:
SetUp()35     void SetUp() override
36     {
37         Test::SetUp();
38         // use custom UiOperationOptions
39         customOptions_.clickHoldMs_ = CUSTOM_CLICK_HOLD_MS;
40         customOptions_.longClickHoldMs_ = CUSTOM_LONGCLICK_HOLD_MS;
41         customOptions_.doubleClickIntervalMs_ = CUSTOM_DOUBLECLICK_HOLD_MS;
42         customOptions_.keyHoldMs_ = CUSTOM_KEY_HOLD_MS;
43         customOptions_.swipeVelocityPps_ = CUSTOM_SWIPE_VELOCITY_PPS;
44         customOptions_.uiSteadyThresholdMs_ = CUSTOM_UI_STEADY_MS;
45         customOptions_.waitUiSteadyMaxMs_ = CUSTOM_WAIT_UI_STEADY_MS;
46     }
47     UiOpArgs customOptions_;
48 };
49 
TEST_F(UiActionTest,computeClickAction)50 TEST_F(UiActionTest, computeClickAction)
51 {
52     Point point {100, 200};
53     GenericClick action(TouchOp::CLICK, point);
54     PointerMatrix events;
55     action.Decompose(events, customOptions_);
56     ASSERT_EQ(2, events.GetSize()); // up & down
57     auto &event1 = events.At(0, 0);
58     auto &event2 = events.At(0, 1);
59     ASSERT_EQ(point.px_, event1.point_.px_);
60     ASSERT_EQ(point.py_, event1.point_.py_);
61     ASSERT_EQ(ActionStage::DOWN, event1.stage_);
62     ASSERT_EQ(0, event1.downTimeOffsetMs_);
63 
64     ASSERT_EQ(point.px_, event2.point_.px_);
65     ASSERT_EQ(point.py_, event2.point_.py_);
66     ASSERT_EQ(ActionStage::UP, event2.stage_);
67     ASSERT_EQ(customOptions_.clickHoldMs_, event2.downTimeOffsetMs_);
68 }
69 
TEST_F(UiActionTest,computeLongClickAction)70 TEST_F(UiActionTest, computeLongClickAction)
71 {
72     Point point {100, 200};
73     GenericClick action(TouchOp::LONG_CLICK, point);
74     PointerMatrix events;
75     action.Decompose(events, customOptions_);
76     ASSERT_EQ(2, events.GetSize()); // up & down
77     auto &event1 = events.At(0, 0);
78     auto &event2 = events.At(0, 1);
79     ASSERT_EQ(point.px_, event1.point_.px_);
80     ASSERT_EQ(point.py_, event1.point_.py_);
81     ASSERT_EQ(ActionStage::DOWN, event1.stage_);
82     ASSERT_EQ(0, event1.downTimeOffsetMs_);
83     // there should be a proper pause after touch down to make long-click
84     ASSERT_EQ(customOptions_.longClickHoldMs_, event1.holdMs_);
85 
86     ASSERT_EQ(point.px_, event2.point_.px_);
87     ASSERT_EQ(point.py_, event2.point_.py_);
88     ASSERT_EQ(ActionStage::UP, event2.stage_);
89     ASSERT_EQ(customOptions_.longClickHoldMs_, event2.downTimeOffsetMs_);
90 }
91 
TEST_F(UiActionTest,computeDoubleClickAction)92 TEST_F(UiActionTest, computeDoubleClickAction)
93 {
94     Point point {100, 200};
95     GenericClick action(TouchOp::DOUBLE_CLICK_P, point);
96     PointerMatrix events;
97     action.Decompose(events, customOptions_);
98     ASSERT_EQ(4, events.GetSize()); // up-down-interval-up-down
99     auto &event1 = events.At(0, 0);
100     auto &event2 = events.At(0, 1);
101     auto &event3 = events.At(0, 2);
102     auto &event4 = events.At(0, 3);
103     ASSERT_EQ(point.px_, event1.point_.px_);
104     ASSERT_EQ(point.py_, event1.point_.py_);
105     ASSERT_EQ(ActionStage::DOWN, event1.stage_);
106     ASSERT_EQ(0, event1.downTimeOffsetMs_);
107 
108     ASSERT_EQ(point.px_, event2.point_.px_);
109     ASSERT_EQ(point.py_, event2.point_.py_);
110     ASSERT_EQ(ActionStage::UP, event2.stage_);
111     ASSERT_EQ(customOptions_.clickHoldMs_, event2.downTimeOffsetMs_);
112     // there should be a proper pause after first click
113     ASSERT_EQ(customOptions_.doubleClickIntervalMs_, event2.holdMs_);
114 
115     ASSERT_EQ(point.px_, event3.point_.px_);
116     ASSERT_EQ(point.py_, event3.point_.py_);
117     ASSERT_EQ(ActionStage::DOWN, event3.stage_);
118     ASSERT_EQ(0, event3.downTimeOffsetMs_);
119 
120     ASSERT_EQ(point.px_, event4.point_.px_);
121     ASSERT_EQ(point.py_, event4.point_.py_);
122     ASSERT_EQ(ActionStage::UP, event4.stage_);
123     ASSERT_EQ(customOptions_.clickHoldMs_, event4.downTimeOffsetMs_);
124 }
125 
TEST_F(UiActionTest,computeSwipeAction)126 TEST_F(UiActionTest, computeSwipeAction)
127 {
128     UiOpArgs opt {};
129     opt.swipeVelocityPps_ = 50; // specify the swipe velocity
130     Point point0(0, 0);
131     Point point1(100, 200);
132     GenericSwipe action(TouchOp::SWIPE, point0, point1);
133     PointerMatrix events;
134     action.Decompose(events, opt);
135     // there should be more than 1 touches
136     const int32_t steps = events.GetSize() - 1;
137     ASSERT_TRUE(steps > 1);
138 
139     const int32_t disX = point1.px_ - point0.px_;
140     const int32_t disY = point1.py_ - point0.py_;
141     const uint32_t distance = sqrt(disX * disX + disY * disY);
142     const uint32_t totalCostMs = distance * 1000 / opt.swipeVelocityPps_;
143 
144     uint32_t step = 0;
145     // check the TouchEvent of each step
146     for (uint32_t event = 0; event < events.GetSize(); event++) {
147         int32_t expectedPointerX = point0.px_ + (disX * step) / steps;
148         int32_t expectedPointerY = point0.py_ + (disY * step) / steps;
149         uint32_t expectedTimeOffset = (totalCostMs * step) / steps;
150         ASSERT_NEAR(expectedPointerX, events.At(0, event).point_.px_, 5);
151         ASSERT_NEAR(expectedPointerY, events.At(0, event).point_.py_, 5);
152         ASSERT_NEAR(expectedTimeOffset, events.At(0, event).downTimeOffsetMs_, 5);
153         if (step == 0) {
154             // should start with Action.DOWN
155             ASSERT_EQ(ActionStage::DOWN, events.At(0, event).stage_);
156         } else if (step == events.GetSize() - 1) {
157             // should end with Action.UP
158             ASSERT_EQ(ActionStage::UP, events.At(0, event).stage_);
159         } else {
160             // middle events should all be action-MOVE
161             ASSERT_EQ(ActionStage::MOVE, events.At(0, event).stage_);
162         }
163         step++;
164     }
165 }
166 
TEST_F(UiActionTest,computeFlingAction)167 TEST_F(UiActionTest, computeFlingAction)
168 {
169     UiOpArgs opt {};
170     opt.swipeVelocityPps_ = 800; // specify the swipe velocity
171     Point point0(0, 0);
172     Point point1(200, 200);
173 
174     const uint32_t stepLen = 2;
175     const int32_t disX = point1.px_ - point0.px_;
176     const int32_t disY = point1.py_ - point0.py_;
177     const uint32_t distance = sqrt(disX * disX + disY * disY);
178     const uint32_t totalCostMs = distance * 1000 / opt.swipeVelocityPps_;
179     opt.swipeStepsCounts_ = distance / stepLen;
180 
181     GenericSwipe action(TouchOp::SWIPE, point0, point1);
182     PointerMatrix events;
183     action.Decompose(events, opt);
184     // there should be more than 1 touches
185     const uint16_t steps = opt.swipeStepsCounts_;
186     ASSERT_TRUE(steps > 1);
187     ASSERT_EQ(steps, 141);
188 
189     uint32_t step = 0;
190     // check the TouchEvent of each step
191     for (uint32_t event = 0; event < events.GetSize(); event++) {
192         int32_t expectedPointerX = point0.px_ + (disX * step) / steps;
193         int32_t expectedPointerY = point0.py_ + (disY * step) / steps;
194         uint32_t expectedTimeOffset = (totalCostMs * step) / steps;
195         ASSERT_NEAR(expectedPointerX, events.At(0, event).point_.px_, 5);
196         ASSERT_NEAR(expectedPointerY, events.At(0, event).point_.py_, 5);
197         ASSERT_NEAR(expectedTimeOffset, events.At(0, event).downTimeOffsetMs_, 5);
198         if (step == 0) {
199             // should start with Action.DOWN
200             ASSERT_EQ(ActionStage::DOWN, events.At(0, event).stage_);
201         } else if (step == events.GetSize() - 1) {
202             // should end with Action.UP
203             ASSERT_EQ(ActionStage::UP, events.At(0, event).stage_);
204         } else {
205             // middle events should all be action-MOVE
206             ASSERT_EQ(ActionStage::MOVE, events.At(0, event).stage_);
207         }
208         step++;
209     }
210 }
211 
TEST_F(UiActionTest,computePinchInAction)212 TEST_F(UiActionTest, computePinchInAction)
213 {
214     UiOpArgs opt {};
215     opt.swipeVelocityPps_ = 50; // specify the swipe velocity
216     Rect rect(210, 510, 30, 330);
217     float_t scale = 0.5;
218     GenericPinch action(rect, scale);
219     PointerMatrix events;
220     action.Decompose(events, opt);
221     // there should be more than 1 touches
222     const int32_t steps = events.GetSteps() - 1;
223     ASSERT_TRUE(steps > 1);
224     ASSERT_EQ(102, events.GetSize());
225     ASSERT_EQ(51, events.GetSteps());
226 
227     const int32_t disX0 = abs(rect.left_ - rect.GetCenterX()) * abs(scale - 1);
228     ASSERT_EQ(75, disX0);
229 
230     uint32_t step = 0;
231     // check the TouchEvent of each step
232     for (uint32_t eventStep = 0; eventStep < events.GetSteps(); eventStep++) {
233         uint32_t eventFinger = 0;
234         int32_t expectedPointerX0 = rect.left_ + (disX0 * step) / steps;
235         uint32_t x0 = events.At(eventFinger, eventStep).point_.px_;
236         ASSERT_NEAR(expectedPointerX0, x0, 20);
237         if (eventStep == 0) {
238         // should start with Action.DOWN
239         ASSERT_EQ(ActionStage::DOWN, events.At(eventFinger, eventStep).stage_);
240         ASSERT_EQ(0, events.At(eventFinger, eventStep).downTimeOffsetMs_);
241         } else if (eventStep == events.GetSteps() - 1) {
242             // should end with Action.UP
243             ASSERT_EQ(ActionStage::UP, events.At(eventFinger, eventStep).stage_);
244         } else {
245             // middle events should all be action-MOVE
246             ASSERT_EQ(ActionStage::MOVE, events.At(eventFinger, eventStep).stage_);
247         }
248         step++;
249     }
250     step = 0;
251     for (uint32_t eventStep = 0; eventStep < events.GetSteps(); eventStep++) {
252         uint32_t eventFinger = 1;
253         int32_t expectedPointerX0 = rect.right_ - (disX0 * step) / steps;
254         ASSERT_NEAR(expectedPointerX0, events.At(eventFinger, eventStep).point_.px_, 20);
255         if (eventStep == 0) {
256         // should start with Action.DOWN
257         ASSERT_EQ(ActionStage::DOWN, events.At(eventFinger, eventStep).stage_);
258         } else if (eventStep == events.GetSteps() - 1) {
259             // should end with Action.UP
260             ASSERT_EQ(ActionStage::UP, events.At(eventFinger, eventStep).stage_);
261         } else {
262             // middle events should all be action-MOVE
263             ASSERT_EQ(ActionStage::MOVE, events.At(eventFinger, eventStep).stage_);
264         }
265         step++;
266     }
267 }
268 
TEST_F(UiActionTest,computeMultiPointerMatrixAction)269 TEST_F(UiActionTest, computeMultiPointerMatrixAction)
270 {
271     UiOpArgs opt {};
272     opt.swipeVelocityPps_ = 50; // specify the swipe velocity
273     const uint32_t finger = 2;
274     const uint32_t step = 4;
275     PointerMatrix pointer(finger, step);
276     for (uint32_t stepIndex = 0; stepIndex < step; stepIndex++) {
277         pointer.At(0, stepIndex).point_.px_ = 245 + 20 * stepIndex;
278         pointer.At(0, stepIndex).point_.py_ = 480;
279     }
280     for (uint32_t stepIndex = 0; stepIndex < step; stepIndex++) {
281         pointer.At(1, stepIndex).point_.px_ = 505 - 20 * stepIndex;
282         pointer.At(1, stepIndex).point_.py_ = 480;
283     }
284     MultiPointerAction action(pointer);
285     ASSERT_EQ(2, pointer.GetFingers());
286     ASSERT_EQ(4, pointer.GetSteps());
287     ASSERT_EQ(245, pointer.At(0, 0).point_.px_);
288     PointerMatrix events;
289     action.Decompose(events, opt);
290     // there should be more than 1 touches
291     ASSERT_EQ(8, events.GetSize());
292     ASSERT_EQ(4, events.GetSteps());
293     for (uint32_t eventStep = 0; eventStep < events.GetSteps(); eventStep++) {
294         for (uint32_t eventFinger = 0; eventFinger < events.GetFingers(); eventFinger++) {
295             if (eventStep == 0) {
296                 ASSERT_EQ(ActionStage::DOWN, events.At(eventFinger, eventStep).stage_);
297             } else if (eventStep == events.GetSteps() - 1) {
298                 ASSERT_EQ(ActionStage::UP, events.At(eventFinger, eventStep).stage_);
299             } else {
300                 ASSERT_EQ(ActionStage::MOVE, events.At(eventFinger, eventStep).stage_);
301             }
302         }
303     }
304 }
305 
TEST_F(UiActionTest,computeMultiPointerMatrixAction1)306 TEST_F(UiActionTest, computeMultiPointerMatrixAction1)
307 {
308     UiOpArgs opt {};
309     opt.swipeVelocityPps_ = 600; // specify the swipe velocity
310     const uint32_t finger = 4;
311     const uint32_t step = 4;
312     PointerMatrix pointer(finger, step);
313     for (uint32_t stepIndex = 0; stepIndex < step; stepIndex++) {
314         pointer.At(0, stepIndex).point_.px_ = 245 + 20 * stepIndex;
315         pointer.At(0, stepIndex).point_.py_ = 480;
316     }
317     for (uint32_t stepIndex = 0; stepIndex < step; stepIndex++) {
318         pointer.At(1, stepIndex).point_.px_ = 505 - 20 * stepIndex;
319         pointer.At(1, stepIndex).point_.py_ = 480;
320     }
321     for (uint32_t stepIndex = 0; stepIndex < step; stepIndex++) {
322         pointer.At(2, stepIndex).point_.px_ = 375;
323         pointer.At(2, stepIndex).point_.py_ = 350 + 20 * stepIndex;
324     }
325     for (uint32_t stepIndex = 0; stepIndex < step; stepIndex++) {
326         pointer.At(3, stepIndex).point_.px_ = 375;
327         pointer.At(3, stepIndex).point_.py_ = 610 - 20 * stepIndex;
328     }
329     MultiPointerAction action(pointer);
330     ASSERT_EQ(4, pointer.GetFingers());
331     ASSERT_EQ(4, pointer.GetSteps());
332     ASSERT_EQ(245, pointer.At(0, 0).point_.px_);
333     ASSERT_EQ(590, pointer.At(3, 1).point_.py_);
334     PointerMatrix events;
335     action.Decompose(events, opt);
336     // there should be more than 1 touches
337     ASSERT_EQ(16, events.GetSize());
338     ASSERT_EQ(4, events.GetSteps());
339     for (uint32_t eventStep = 0; eventStep < events.GetSteps(); eventStep++) {
340         for (uint32_t eventFinger = 0; eventFinger < events.GetFingers(); eventFinger++) {
341             if (eventStep == 0) {
342                 ASSERT_EQ(ActionStage::DOWN, events.At(eventFinger, eventStep).stage_);
343             } else if (eventStep == events.GetSteps() - 1) {
344                 ASSERT_EQ(ActionStage::UP, events.At(eventFinger, eventStep).stage_);
345             } else {
346                 ASSERT_EQ(ActionStage::MOVE, events.At(eventFinger, eventStep).stage_);
347             }
348         }
349     }
350 }
351 
TEST_F(UiActionTest,computePinchOutAction)352 TEST_F(UiActionTest, computePinchOutAction)
353 {
354     UiOpArgs opt {};
355     opt.swipeVelocityPps_ = 50; // specify the swipe velocity
356     Rect rect(210, 510, 30, 330);
357     float_t scale = 1.5;
358     GenericPinch action(rect, scale);
359     PointerMatrix events;
360     action.Decompose(events, opt);
361     // there should be more than 1 touches
362     const int32_t steps = events.GetSteps() - 1;
363     ASSERT_TRUE(steps > 1);
364     ASSERT_EQ(102, events.GetSize());
365     ASSERT_EQ(51, events.GetSteps());
366 
367     const int32_t disX0 = abs(rect.left_ - rect.GetCenterX()) * abs(scale - 1);
368     ASSERT_EQ(75, disX0);
369 
370     uint32_t step = 0;
371     // check the TouchEvent of each step
372     for (uint32_t eventStep = 0; eventStep < events.GetSteps(); eventStep++) {
373         uint32_t eventFinger = 0;
374         int32_t expectedPointerX0 = rect.GetCenterX() - (disX0 * step) / steps;
375         uint32_t x0 = events.At(eventFinger, eventStep).point_.px_;
376         ASSERT_NEAR(expectedPointerX0, x0, 20);
377         if (eventStep == 0) {
378         // should start with Action.DOWN
379         ASSERT_EQ(ActionStage::DOWN, events.At(eventFinger, eventStep).stage_);
380         ASSERT_EQ(0, events.At(eventFinger, eventStep).downTimeOffsetMs_);
381         } else if (eventStep == events.GetSteps() - 1) {
382             // should end with Action.UP
383             ASSERT_EQ(ActionStage::UP, events.At(eventFinger, eventStep).stage_);
384         } else {
385             // middle events should all be action-MOVE
386             ASSERT_EQ(ActionStage::MOVE, events.At(eventFinger, eventStep).stage_);
387         }
388         step++;
389     }
390     step = 0;
391     for (uint32_t eventStep = 0; eventStep < events.GetSteps(); eventStep++) {
392         uint32_t eventFinger = 1;
393         int32_t expectedPointerX0 = rect.GetCenterX() + (disX0 * step) / steps;
394         ASSERT_NEAR(expectedPointerX0, events.At(eventFinger, eventStep).point_.px_, 20);
395         if (eventStep == 0) {
396         // should start with Action.DOWN
397         ASSERT_EQ(ActionStage::DOWN, events.At(eventFinger, eventStep).stage_);
398         } else if (eventStep == events.GetSteps() - 1) {
399             // should end with Action.UP
400             ASSERT_EQ(ActionStage::UP, events.At(eventFinger, eventStep).stage_);
401         } else {
402             // middle events should all be action-MOVE
403             ASSERT_EQ(ActionStage::MOVE, events.At(eventFinger, eventStep).stage_);
404         }
405         step++;
406     }
407 }
408 
TEST_F(UiActionTest,computeDragAction)409 TEST_F(UiActionTest, computeDragAction)
410 {
411     UiOpArgs opt {};
412     opt.longClickHoldMs_ = 2000; // specify the long-click duration
413     Point point0(0, 0);
414     Point point1(100, 200);
415     GenericSwipe swipeAction(TouchOp::SWIPE, point0, point1);
416     GenericSwipe dragAction(TouchOp::DRAG, point0, point1);
417     PointerMatrix swipeEvents;
418     PointerMatrix dragEvents;
419     swipeAction.Decompose(swipeEvents, opt);
420     dragAction.Decompose(dragEvents, opt);
421 
422     ASSERT_TRUE(swipeEvents.GetSize() > 1);
423     ASSERT_EQ(swipeEvents.GetSize(), dragEvents.GetSize());
424 
425     // check the hold time of each event
426     for (uint32_t step = 0; step < swipeEvents.GetSize(); step++) {
427         auto &swipeEvent = swipeEvents.At(0, step);
428         auto &dragEvent = dragEvents.At(0, step);
429         ASSERT_EQ(swipeEvent.stage_, dragEvent.stage_);
430         // drag needs longPressDown firstly, the downOffSet of following event should be delayed
431         if (step == 0) {
432             ASSERT_EQ(swipeEvent.downTimeOffsetMs_, dragEvent.downTimeOffsetMs_);
433             ASSERT_EQ(swipeEvent.holdMs_ + opt.longClickHoldMs_, dragEvent.holdMs_);
434         } else {
435             ASSERT_EQ(swipeEvent.downTimeOffsetMs_ + opt.longClickHoldMs_, dragEvent.downTimeOffsetMs_);
436             ASSERT_EQ(swipeEvent.holdMs_, dragEvent.holdMs_);
437         }
438     }
439 }
440 
TEST_F(UiActionTest,computeBackKeyAction)441 TEST_F(UiActionTest, computeBackKeyAction)
442 {
443     Back keyAction;
444     vector<KeyEvent> events;
445     keyAction.ComputeEvents(events, customOptions_);
446     ASSERT_EQ(2, events.size()); // up & down
447     auto event1 = *events.begin();
448     auto event2 = *(events.begin() + 1);
449     ASSERT_EQ(KEYCODE_BACK, event1.code_);
450     ASSERT_EQ(ActionStage::DOWN, event1.stage_);
451 
452     ASSERT_EQ(KEYCODE_BACK, event2.code_);
453     ASSERT_EQ(ActionStage::UP, event2.stage_);
454 }
455 
TEST_F(UiActionTest,computePasteAction)456 TEST_F(UiActionTest, computePasteAction)
457 {
458     Paste keyAction;
459     vector<KeyEvent> events;
460     keyAction.ComputeEvents(events, customOptions_);
461     ASSERT_EQ(4, events.size()); // ctrl_down/key_down/key_up/ctrl_up
462     auto event1 = *events.begin();
463     auto event2 = *(events.begin() + 1);
464     auto event3 = *(events.begin() + 2);
465     auto event4 = *(events.begin() + 3);
466 
467     ASSERT_EQ(KEYCODE_CTRL, event1.code_);
468     ASSERT_EQ(ActionStage::DOWN, event1.stage_);
469     ASSERT_EQ(KEYCODE_V, event2.code_);
470     ASSERT_EQ(ActionStage::DOWN, event2.stage_);
471 
472     ASSERT_EQ(KEYCODE_V, event3.code_);
473     ASSERT_EQ(ActionStage::UP, event3.stage_);
474     ASSERT_EQ(KEYCODE_CTRL, event4.code_);
475     ASSERT_EQ(ActionStage::UP, event4.stage_);
476 }
477 
TEST_F(UiActionTest,anonymousSignleKey)478 TEST_F(UiActionTest, anonymousSignleKey)
479 {
480     static constexpr uint32_t keyCode = 1234;
481     static const string expectedDesc = "key_" + to_string(keyCode);
482     AnonymousSingleKey anonymousKey(keyCode);
483     vector<KeyEvent> events;
484     anonymousKey.ComputeEvents(events, customOptions_);
485     ASSERT_EQ(2, events.size()); // up & down
486     auto event1 = *events.begin();
487     auto event2 = *(events.begin() + 1);
488     ASSERT_EQ(keyCode, event1.code_);
489     ASSERT_EQ(ActionStage::DOWN, event1.stage_);
490 
491     ASSERT_EQ(keyCode, event2.code_);
492     ASSERT_EQ(ActionStage::UP, event2.stage_);
493 }
494