Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ui / events / event_unittest.cc
blob46c2f6375929ad4690fb00da1ae60c4e4b585391
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/memory/scoped_ptr.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7 #include "ui/events/event.h"
8 #include "ui/events/event_utils.h"
9 #include "ui/events/keycodes/dom4/keycode_converter.h"
10 #include "ui/events/test/events_test_utils.h"
12 #if defined(USE_X11)
13 #include <X11/Xlib.h>
14 #include "ui/events/test/events_test_utils_x11.h"
15 #include "ui/gfx/x/x11_types.h"
16 #endif
18 namespace ui {
20 TEST(EventTest, NoNativeEvent) {
21 KeyEvent keyev(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
22 EXPECT_FALSE(keyev.HasNativeEvent());
25 TEST(EventTest, NativeEvent) {
26 #if defined(OS_WIN)
27 MSG native_event = { NULL, WM_KEYUP, VKEY_A, 0 };
28 KeyEvent keyev(native_event);
29 EXPECT_TRUE(keyev.HasNativeEvent());
30 #elif defined(USE_X11)
31 ScopedXI2Event event;
32 event.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, EF_NONE);
33 KeyEvent keyev(event);
34 EXPECT_TRUE(keyev.HasNativeEvent());
35 #endif
38 TEST(EventTest, GetCharacter) {
39 // Check if Control+Enter returns 10.
40 KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
41 EXPECT_EQ(10, keyev1.GetCharacter());
42 // Check if Enter returns 13.
43 KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE);
44 EXPECT_EQ(13, keyev2.GetCharacter());
46 #if defined(USE_X11)
47 // For X11, test the functions with native_event() as well. crbug.com/107837
48 ScopedXI2Event event;
49 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
50 KeyEvent keyev3(event);
51 EXPECT_EQ(10, keyev3.GetCharacter());
53 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE);
54 KeyEvent keyev4(event);
55 EXPECT_EQ(13, keyev4.GetCharacter());
56 #endif
59 TEST(EventTest, ClickCount) {
60 const gfx::Point origin(0, 0);
61 MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, 0, 0);
62 for (int i = 1; i <=3 ; ++i) {
63 mouseev.SetClickCount(i);
64 EXPECT_EQ(i, mouseev.GetClickCount());
68 TEST(EventTest, RepeatedClick) {
69 const gfx::Point origin(0, 0);
70 MouseEvent mouse_ev1(ET_MOUSE_PRESSED, origin, origin, 0, 0);
71 MouseEvent mouse_ev2(ET_MOUSE_PRESSED, origin, origin, 0, 0);
72 LocatedEventTestApi test_ev1(&mouse_ev1);
73 LocatedEventTestApi test_ev2(&mouse_ev2);
75 base::TimeDelta start = base::TimeDelta::FromMilliseconds(0);
76 base::TimeDelta soon = start + base::TimeDelta::FromMilliseconds(1);
77 base::TimeDelta later = start + base::TimeDelta::FromMilliseconds(1000);
79 // Close point.
80 test_ev1.set_location(gfx::Point(0, 0));
81 test_ev2.set_location(gfx::Point(1, 0));
82 test_ev1.set_time_stamp(start);
83 test_ev2.set_time_stamp(soon);
84 EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
86 // Too far.
87 test_ev1.set_location(gfx::Point(0, 0));
88 test_ev2.set_location(gfx::Point(10, 0));
89 test_ev1.set_time_stamp(start);
90 test_ev2.set_time_stamp(soon);
91 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
93 // Too long a time between clicks.
94 test_ev1.set_location(gfx::Point(0, 0));
95 test_ev2.set_location(gfx::Point(0, 0));
96 test_ev1.set_time_stamp(start);
97 test_ev2.set_time_stamp(later);
98 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
101 // Tests that an event only increases the click count and gets marked as a
102 // double click if a release event was seen for the previous click. This
103 // prevents the same PRESSED event from being processed twice:
104 // http://crbug.com/389162
105 TEST(EventTest, DoubleClickRequiresRelease) {
106 const gfx::Point origin1(0, 0);
107 const gfx::Point origin2(100, 0);
108 scoped_ptr<MouseEvent> ev;
109 base::TimeDelta start = base::TimeDelta::FromMilliseconds(0);
111 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin1, origin1, 0, 0));
112 ev->set_time_stamp(start);
113 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev));
114 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin1, origin1, 0, 0));
115 ev->set_time_stamp(start);
116 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev));
118 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin2, origin2, 0, 0));
119 ev->set_time_stamp(start);
120 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev));
121 ev.reset(new MouseEvent(ET_MOUSE_RELEASED, origin2, origin2, 0, 0));
122 ev->set_time_stamp(start);
123 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev));
124 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin2, origin2, 0, 0));
125 ev->set_time_stamp(start);
126 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev));
127 ev.reset(new MouseEvent(ET_MOUSE_RELEASED, origin2, origin2, 0, 0));
128 ev->set_time_stamp(start);
129 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev));
130 MouseEvent::ResetLastClickForTest();
133 // Tests that clicking right and then left clicking does not generate a double
134 // click.
135 TEST(EventTest, SingleClickRightLeft) {
136 const gfx::Point origin(0, 0);
137 scoped_ptr<MouseEvent> ev;
138 base::TimeDelta start = base::TimeDelta::FromMilliseconds(0);
140 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin, origin,
141 ui::EF_RIGHT_MOUSE_BUTTON,
142 ui::EF_RIGHT_MOUSE_BUTTON));
143 ev->set_time_stamp(start);
144 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev));
145 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin, origin,
146 ui::EF_LEFT_MOUSE_BUTTON,
147 ui::EF_LEFT_MOUSE_BUTTON));
148 ev->set_time_stamp(start);
149 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev));
150 ev.reset(new MouseEvent(ET_MOUSE_RELEASED, origin, origin,
151 ui::EF_LEFT_MOUSE_BUTTON,
152 ui::EF_LEFT_MOUSE_BUTTON));
153 ev->set_time_stamp(start);
154 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev));
155 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin, origin,
156 ui::EF_LEFT_MOUSE_BUTTON,
157 ui::EF_LEFT_MOUSE_BUTTON));
158 ev->set_time_stamp(start);
159 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev));
160 MouseEvent::ResetLastClickForTest();
163 TEST(EventTest, KeyEvent) {
164 static const struct {
165 KeyboardCode key_code;
166 int flags;
167 uint16 character;
168 } kTestData[] = {
169 { VKEY_A, 0, 'a' },
170 { VKEY_A, EF_SHIFT_DOWN, 'A' },
171 { VKEY_A, EF_CAPS_LOCK_DOWN, 'A' },
172 { VKEY_A, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, 'a' },
173 { VKEY_A, EF_CONTROL_DOWN, 0x01 },
174 { VKEY_A, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x01' },
175 { VKEY_Z, 0, 'z' },
176 { VKEY_Z, EF_SHIFT_DOWN, 'Z' },
177 { VKEY_Z, EF_CAPS_LOCK_DOWN, 'Z' },
178 { VKEY_Z, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, 'z' },
179 { VKEY_Z, EF_CONTROL_DOWN, '\x1A' },
180 { VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1A' },
182 { VKEY_2, EF_CONTROL_DOWN, '\0' },
183 { VKEY_2, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
184 { VKEY_6, EF_CONTROL_DOWN, '\0' },
185 { VKEY_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1E' },
186 { VKEY_OEM_MINUS, EF_CONTROL_DOWN, '\0' },
187 { VKEY_OEM_MINUS, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1F' },
188 { VKEY_OEM_4, EF_CONTROL_DOWN, '\x1B' },
189 { VKEY_OEM_4, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
190 { VKEY_OEM_5, EF_CONTROL_DOWN, '\x1C' },
191 { VKEY_OEM_5, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
192 { VKEY_OEM_6, EF_CONTROL_DOWN, '\x1D' },
193 { VKEY_OEM_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
194 { VKEY_RETURN, EF_CONTROL_DOWN, '\x0A' },
196 { VKEY_0, 0, '0' },
197 { VKEY_0, EF_SHIFT_DOWN, ')' },
198 { VKEY_0, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, ')' },
199 { VKEY_0, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
201 { VKEY_9, 0, '9' },
202 { VKEY_9, EF_SHIFT_DOWN, '(' },
203 { VKEY_9, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, '(' },
204 { VKEY_9, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
206 { VKEY_NUMPAD0, EF_CONTROL_DOWN, '\0' },
207 { VKEY_NUMPAD0, EF_SHIFT_DOWN, '0' },
209 { VKEY_NUMPAD9, EF_CONTROL_DOWN, '\0' },
210 { VKEY_NUMPAD9, EF_SHIFT_DOWN, '9' },
212 { VKEY_TAB, EF_CONTROL_DOWN, '\0' },
213 { VKEY_TAB, EF_SHIFT_DOWN, '\t' },
215 { VKEY_MULTIPLY, EF_CONTROL_DOWN, '\0' },
216 { VKEY_MULTIPLY, EF_SHIFT_DOWN, '*' },
217 { VKEY_ADD, EF_CONTROL_DOWN, '\0' },
218 { VKEY_ADD, EF_SHIFT_DOWN, '+' },
219 { VKEY_SUBTRACT, EF_CONTROL_DOWN, '\0' },
220 { VKEY_SUBTRACT, EF_SHIFT_DOWN, '-' },
221 { VKEY_DECIMAL, EF_CONTROL_DOWN, '\0' },
222 { VKEY_DECIMAL, EF_SHIFT_DOWN, '.' },
223 { VKEY_DIVIDE, EF_CONTROL_DOWN, '\0' },
224 { VKEY_DIVIDE, EF_SHIFT_DOWN, '/' },
226 { VKEY_OEM_1, EF_CONTROL_DOWN, '\0' },
227 { VKEY_OEM_1, EF_SHIFT_DOWN, ':' },
228 { VKEY_OEM_PLUS, EF_CONTROL_DOWN, '\0' },
229 { VKEY_OEM_PLUS, EF_SHIFT_DOWN, '+' },
230 { VKEY_OEM_COMMA, EF_CONTROL_DOWN, '\0' },
231 { VKEY_OEM_COMMA, EF_SHIFT_DOWN, '<' },
232 { VKEY_OEM_PERIOD, EF_CONTROL_DOWN, '\0' },
233 { VKEY_OEM_PERIOD, EF_SHIFT_DOWN, '>' },
234 { VKEY_OEM_3, EF_CONTROL_DOWN, '\0' },
235 { VKEY_OEM_3, EF_SHIFT_DOWN, '~' },
238 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestData); ++i) {
239 KeyEvent key(ET_KEY_PRESSED,
240 kTestData[i].key_code,
241 kTestData[i].flags);
242 EXPECT_EQ(kTestData[i].character, key.GetCharacter())
243 << " Index:" << i << " key_code:" << kTestData[i].key_code;
247 TEST(EventTest, KeyEventDirectUnicode) {
248 KeyEvent key(0x1234U, ui::VKEY_UNKNOWN, ui::EF_NONE);
249 EXPECT_EQ(0x1234U, key.GetCharacter());
250 EXPECT_EQ(ET_KEY_PRESSED, key.type());
251 EXPECT_TRUE(key.is_char());
254 TEST(EventTest, NormalizeKeyEventFlags) {
255 #if defined(USE_X11)
256 // Normalize flags when KeyEvent is created from XEvent.
257 ScopedXI2Event event;
259 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
260 KeyEvent keyev(event);
261 EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
264 event.InitKeyEvent(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
265 KeyEvent keyev(event);
266 EXPECT_EQ(EF_NONE, keyev.flags());
269 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
270 KeyEvent keyev(event);
271 EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
274 event.InitKeyEvent(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
275 KeyEvent keyev(event);
276 EXPECT_EQ(EF_NONE, keyev.flags());
279 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_MENU, EF_ALT_DOWN);
280 KeyEvent keyev(event);
281 EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
284 event.InitKeyEvent(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
285 KeyEvent keyev(event);
286 EXPECT_EQ(EF_NONE, keyev.flags());
288 #endif
290 // Do not normalize flags for synthesized events without
291 // KeyEvent::NormalizeFlags called explicitly.
293 KeyEvent keyev(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
294 EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
297 KeyEvent keyev(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
298 EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
299 keyev.NormalizeFlags();
300 EXPECT_EQ(EF_NONE, keyev.flags());
303 KeyEvent keyev(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
304 EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
307 KeyEvent keyev(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
308 EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
309 keyev.NormalizeFlags();
310 EXPECT_EQ(EF_NONE, keyev.flags());
313 KeyEvent keyev(ET_KEY_PRESSED, VKEY_MENU, EF_ALT_DOWN);
314 EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
317 KeyEvent keyev(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
318 EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
319 keyev.NormalizeFlags();
320 EXPECT_EQ(EF_NONE, keyev.flags());
324 TEST(EventTest, KeyEventCopy) {
325 KeyEvent key(ET_KEY_PRESSED, VKEY_A, EF_NONE);
326 scoped_ptr<KeyEvent> copied_key(new KeyEvent(key));
327 EXPECT_EQ(copied_key->type(), key.type());
328 EXPECT_EQ(copied_key->key_code(), key.key_code());
331 TEST(EventTest, KeyEventCode) {
332 const char kCodeForSpace[] = "Space";
333 const uint16 kNativeCodeSpace =
334 ui::KeycodeConverter::CodeToNativeKeycode(kCodeForSpace);
335 ASSERT_NE(ui::KeycodeConverter::InvalidNativeKeycode(), kNativeCodeSpace);
338 KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, kCodeForSpace, EF_NONE);
339 EXPECT_EQ(kCodeForSpace, key.code());
342 // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be
343 // the specified value.
344 KeyEvent key(ET_KEY_PRESSED, VKEY_RETURN, kCodeForSpace, EF_NONE);
345 EXPECT_EQ(kCodeForSpace, key.code());
348 // If the synthetic event is initialized without code, it returns
349 // an empty string.
350 // TODO(komatsu): Fill a fallback value assuming the US keyboard layout.
351 KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
352 EXPECT_TRUE(key.code().empty());
354 #if defined(USE_X11)
356 // KeyEvent converts from the native keycode (XKB) to the code.
357 ScopedXI2Event xevent;
358 xevent.InitKeyEvent(ET_KEY_PRESSED, VKEY_SPACE, kNativeCodeSpace);
359 KeyEvent key(xevent);
360 EXPECT_EQ(kCodeForSpace, key.code());
362 #endif // USE_X11
363 #if defined(OS_WIN)
365 // Test a non extended key.
366 ASSERT_EQ((kNativeCodeSpace & 0xFF), kNativeCodeSpace);
368 const LPARAM lParam = GetLParamFromScanCode(kNativeCodeSpace);
369 MSG native_event = { NULL, WM_KEYUP, VKEY_SPACE, lParam };
370 KeyEvent key(native_event);
372 // KeyEvent converts from the native keycode (scan code) to the code.
373 EXPECT_EQ(kCodeForSpace, key.code());
376 const char kCodeForHome[] = "Home";
377 const uint16 kNativeCodeHome = 0xe047;
379 // 'Home' is an extended key with 0xe000 bits.
380 ASSERT_NE((kNativeCodeHome & 0xFF), kNativeCodeHome);
381 const LPARAM lParam = GetLParamFromScanCode(kNativeCodeHome);
383 MSG native_event = { NULL, WM_KEYUP, VKEY_HOME, lParam };
384 KeyEvent key(native_event);
386 // KeyEvent converts from the native keycode (scan code) to the code.
387 EXPECT_EQ(kCodeForHome, key.code());
389 #endif // OS_WIN
392 #if defined(USE_X11) || defined(OS_WIN)
393 TEST(EventTest, AutoRepeat) {
394 const uint16 kNativeCodeA = ui::KeycodeConverter::CodeToNativeKeycode("KeyA");
395 const uint16 kNativeCodeB = ui::KeycodeConverter::CodeToNativeKeycode("KeyB");
396 #if defined(USE_X11)
397 ScopedXI2Event native_event_a_pressed;
398 native_event_a_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
399 ScopedXI2Event native_event_a_released;
400 native_event_a_released.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, kNativeCodeA);
401 ScopedXI2Event native_event_b_pressed;
402 native_event_b_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_B, kNativeCodeB);
403 ScopedXI2Event native_event_a_pressed_nonstandard_state;
404 native_event_a_pressed_nonstandard_state.InitKeyEvent(
405 ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
406 // IBUS-GTK uses the mask (1 << 25) to detect reposted event.
407 static_cast<XEvent*>(native_event_a_pressed_nonstandard_state)->xkey.state |=
408 1 << 25;
409 #elif defined(OS_WIN)
410 const LPARAM lParam_a = GetLParamFromScanCode(kNativeCodeA);
411 const LPARAM lParam_b = GetLParamFromScanCode(kNativeCodeB);
412 MSG native_event_a_pressed = { NULL, WM_KEYDOWN, VKEY_A, lParam_a };
413 MSG native_event_a_released = { NULL, WM_KEYUP, VKEY_A, lParam_a };
414 MSG native_event_b_pressed = { NULL, WM_KEYUP, VKEY_B, lParam_b };
415 #endif
416 KeyEvent key_a1(native_event_a_pressed);
417 EXPECT_FALSE(key_a1.IsRepeat());
418 KeyEvent key_a1_released(native_event_a_released);
419 EXPECT_FALSE(key_a1_released.IsRepeat());
421 KeyEvent key_a2(native_event_a_pressed);
422 EXPECT_FALSE(key_a2.IsRepeat());
423 KeyEvent key_a2_repeated(native_event_a_pressed);
424 EXPECT_TRUE(key_a2_repeated.IsRepeat());
425 KeyEvent key_a2_released(native_event_a_released);
426 EXPECT_FALSE(key_a2_released.IsRepeat());
428 KeyEvent key_a3(native_event_a_pressed);
429 EXPECT_FALSE(key_a3.IsRepeat());
430 KeyEvent key_b(native_event_b_pressed);
431 EXPECT_FALSE(key_b.IsRepeat());
432 KeyEvent key_a3_again(native_event_a_pressed);
433 EXPECT_FALSE(key_a3_again.IsRepeat());
434 KeyEvent key_a3_repeated(native_event_a_pressed);
435 EXPECT_TRUE(key_a3_repeated.IsRepeat());
436 KeyEvent key_a3_repeated2(native_event_a_pressed);
437 EXPECT_TRUE(key_a3_repeated2.IsRepeat());
438 KeyEvent key_a3_released(native_event_a_released);
439 EXPECT_FALSE(key_a3_released.IsRepeat());
441 #if defined(USE_X11)
442 KeyEvent key_a4_pressed(native_event_a_pressed);
443 EXPECT_FALSE(key_a4_pressed.IsRepeat());
445 KeyEvent key_a4_pressed_nonstandard_state(
446 native_event_a_pressed_nonstandard_state);
447 EXPECT_FALSE(key_a4_pressed_nonstandard_state.IsRepeat());
448 #endif
450 #endif // USE_X11 || OS_WIN
452 } // namespace ui