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