40bfa9611f0374c8b69924190e19c5f3facc730c
[platform/framework/web/crosswalk.git] / src / ui / events / event_unittest.cc
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.
4
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"
11
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
17
18 namespace ui {
19
20 TEST(EventTest, NoNativeEvent) {
21   KeyEvent keyev(ET_KEY_PRESSED, VKEY_SPACE, 0, false);
22   EXPECT_FALSE(keyev.HasNativeEvent());
23 }
24
25 TEST(EventTest, NativeEvent) {
26 #if defined(OS_WIN)
27   MSG native_event = { NULL, WM_KEYUP, VKEY_A, 0 };
28   KeyEvent keyev(native_event, false);
29   EXPECT_TRUE(keyev.HasNativeEvent());
30 #elif defined(USE_X11)
31   ScopedXI2Event event;
32   event.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, 0);
33   KeyEvent keyev(event, false);
34   EXPECT_TRUE(keyev.HasNativeEvent());
35 #endif
36 }
37
38 TEST(EventTest, GetCharacter) {
39   // Check if Control+Enter returns 10.
40   KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN, false);
41   EXPECT_EQ(10, keyev1.GetCharacter());
42   // Check if Enter returns 13.
43   KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, 0, false);
44   EXPECT_EQ(13, keyev2.GetCharacter());
45
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, false);
51   EXPECT_EQ(10, keyev3.GetCharacter());
52
53   event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, 0);
54   KeyEvent keyev4(event, false);
55   EXPECT_EQ(13, keyev4.GetCharacter());
56 #endif
57 }
58
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());
65   }
66 }
67
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);
74
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);
78
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));
85
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));
92
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));
99 }
100
101 TEST(EventTest, KeyEvent) {
102   static const struct {
103     KeyboardCode key_code;
104     int flags;
105     uint16 character;
106   } kTestData[] = {
107     { VKEY_A, 0, 'a' },
108     { VKEY_A, EF_SHIFT_DOWN, 'A' },
109     { VKEY_A, EF_CAPS_LOCK_DOWN, 'A' },
110     { VKEY_A, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, 'a' },
111     { VKEY_A, EF_CONTROL_DOWN, 0x01 },
112     { VKEY_A, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x01' },
113     { VKEY_Z, 0, 'z' },
114     { VKEY_Z, EF_SHIFT_DOWN, 'Z' },
115     { VKEY_Z, EF_CAPS_LOCK_DOWN, 'Z' },
116     { VKEY_Z, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, 'z' },
117     { VKEY_Z, EF_CONTROL_DOWN, '\x1A' },
118     { VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1A' },
119
120     { VKEY_2, EF_CONTROL_DOWN, '\0' },
121     { VKEY_2, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
122     { VKEY_6, EF_CONTROL_DOWN, '\0' },
123     { VKEY_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1E' },
124     { VKEY_OEM_MINUS, EF_CONTROL_DOWN, '\0' },
125     { VKEY_OEM_MINUS, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1F' },
126     { VKEY_OEM_4, EF_CONTROL_DOWN, '\x1B' },
127     { VKEY_OEM_4, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
128     { VKEY_OEM_5, EF_CONTROL_DOWN, '\x1C' },
129     { VKEY_OEM_5, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
130     { VKEY_OEM_6, EF_CONTROL_DOWN, '\x1D' },
131     { VKEY_OEM_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
132     { VKEY_RETURN, EF_CONTROL_DOWN, '\x0A' },
133
134     { VKEY_0, 0, '0' },
135     { VKEY_0, EF_SHIFT_DOWN, ')' },
136     { VKEY_0, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, ')' },
137     { VKEY_0, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
138
139     { VKEY_9, 0, '9' },
140     { VKEY_9, EF_SHIFT_DOWN, '(' },
141     { VKEY_9, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, '(' },
142     { VKEY_9, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
143
144     { VKEY_NUMPAD0, EF_CONTROL_DOWN, '\0' },
145     { VKEY_NUMPAD0, EF_SHIFT_DOWN, '0' },
146
147     { VKEY_NUMPAD9, EF_CONTROL_DOWN, '\0' },
148     { VKEY_NUMPAD9, EF_SHIFT_DOWN, '9' },
149
150     { VKEY_TAB, EF_CONTROL_DOWN, '\0' },
151     { VKEY_TAB, EF_SHIFT_DOWN, '\t' },
152
153     { VKEY_MULTIPLY, EF_CONTROL_DOWN, '\0' },
154     { VKEY_MULTIPLY, EF_SHIFT_DOWN, '*' },
155     { VKEY_ADD, EF_CONTROL_DOWN, '\0' },
156     { VKEY_ADD, EF_SHIFT_DOWN, '+' },
157     { VKEY_SUBTRACT, EF_CONTROL_DOWN, '\0' },
158     { VKEY_SUBTRACT, EF_SHIFT_DOWN, '-' },
159     { VKEY_DECIMAL, EF_CONTROL_DOWN, '\0' },
160     { VKEY_DECIMAL, EF_SHIFT_DOWN, '.' },
161     { VKEY_DIVIDE, EF_CONTROL_DOWN, '\0' },
162     { VKEY_DIVIDE, EF_SHIFT_DOWN, '/' },
163
164     { VKEY_OEM_1, EF_CONTROL_DOWN, '\0' },
165     { VKEY_OEM_1, EF_SHIFT_DOWN, ':' },
166     { VKEY_OEM_PLUS, EF_CONTROL_DOWN, '\0' },
167     { VKEY_OEM_PLUS, EF_SHIFT_DOWN, '+' },
168     { VKEY_OEM_COMMA, EF_CONTROL_DOWN, '\0' },
169     { VKEY_OEM_COMMA, EF_SHIFT_DOWN, '<' },
170     { VKEY_OEM_PERIOD, EF_CONTROL_DOWN, '\0' },
171     { VKEY_OEM_PERIOD, EF_SHIFT_DOWN, '>' },
172     { VKEY_OEM_3, EF_CONTROL_DOWN, '\0' },
173     { VKEY_OEM_3, EF_SHIFT_DOWN, '~' },
174   };
175
176   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestData); ++i) {
177     KeyEvent key(ET_KEY_PRESSED,
178                  kTestData[i].key_code,
179                  kTestData[i].flags,
180                  false);
181     EXPECT_EQ(kTestData[i].character, key.GetCharacter())
182         << " Index:" << i << " key_code:" << kTestData[i].key_code;
183   }
184 }
185
186 TEST(EventTest, KeyEventDirectUnicode) {
187   KeyEvent key(ET_KEY_PRESSED, VKEY_UNKNOWN, EF_SHIFT_DOWN, false);
188   key.set_character(0x1234U);
189   EXPECT_EQ(0x1234U, key.GetCharacter());
190   KeyEvent key2(ET_KEY_RELEASED, VKEY_UNKNOWN, EF_CONTROL_DOWN, false);
191   key2.set_character(0x4321U);
192   EXPECT_EQ(0x4321U, key2.GetCharacter());
193 }
194
195 TEST(EventTest, NormalizeKeyEventFlags) {
196 #if defined(USE_X11)
197   // Normalize flags when KeyEvent is created from XEvent.
198   ScopedXI2Event event;
199   {
200     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
201     KeyEvent keyev(event, false);
202     EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
203   }
204   {
205     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
206     KeyEvent keyev(event, false);
207     EXPECT_EQ(EF_NONE, keyev.flags());
208   }
209   {
210     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
211     KeyEvent keyev(event, false);
212     EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
213   }
214   {
215     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
216     KeyEvent keyev(event, false);
217     EXPECT_EQ(EF_NONE, keyev.flags());
218   }
219   {
220     event.InitKeyEvent(ET_KEY_PRESSED, VKEY_MENU,  EF_ALT_DOWN);
221     KeyEvent keyev(event, false);
222     EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
223   }
224   {
225     event.InitKeyEvent(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
226     KeyEvent keyev(event, false);
227     EXPECT_EQ(EF_NONE, keyev.flags());
228   }
229 #endif
230
231   // Do not normalize flags for synthesized events without
232   // KeyEvent::NormalizeFlags called explicitly.
233   {
234     KeyEvent keyev(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN, false);
235     EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
236   }
237   {
238     KeyEvent keyev(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN, false);
239     EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
240     keyev.NormalizeFlags();
241     EXPECT_EQ(EF_NONE, keyev.flags());
242   }
243   {
244     KeyEvent keyev(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN, false);
245     EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
246   }
247   {
248     KeyEvent keyev(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN, false);
249     EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
250     keyev.NormalizeFlags();
251     EXPECT_EQ(EF_NONE, keyev.flags());
252   }
253   {
254     KeyEvent keyev(ET_KEY_PRESSED, VKEY_MENU,  EF_ALT_DOWN, false);
255     EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
256   }
257   {
258     KeyEvent keyev(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN, false);
259     EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
260     keyev.NormalizeFlags();
261     EXPECT_EQ(EF_NONE, keyev.flags());
262   }
263 }
264
265 TEST(EventTest, KeyEventCopy) {
266   KeyEvent key(ET_KEY_PRESSED, VKEY_A, EF_NONE, false);
267   scoped_ptr<KeyEvent> copied_key(new KeyEvent(key));
268   EXPECT_EQ(copied_key->type(), key.type());
269   EXPECT_EQ(copied_key->key_code(), key.key_code());
270 }
271
272 TEST(EventTest, KeyEventCode) {
273   KeycodeConverter* conv = KeycodeConverter::GetInstance();
274
275   const char kCodeForSpace[] = "Space";
276   const uint16 kNativeCodeSpace = conv->CodeToNativeKeycode(kCodeForSpace);
277   ASSERT_NE(conv->InvalidNativeKeycode(), kNativeCodeSpace);
278
279   {
280     KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, kCodeForSpace, EF_NONE, false);
281     EXPECT_EQ(kCodeForSpace, key.code());
282   }
283   {
284     // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be
285     // the specified value.
286     KeyEvent key(ET_KEY_PRESSED, VKEY_RETURN, kCodeForSpace, EF_NONE, false);
287     EXPECT_EQ(kCodeForSpace, key.code());
288   }
289   {
290     // If the synthetic event is initialized without code, it returns
291     // an empty string.
292     // TODO(komatsu): Fill a fallback value assuming the US keyboard layout.
293     KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE, false);
294     EXPECT_TRUE(key.code().empty());
295   }
296 #if defined(USE_X11)
297   {
298     // KeyEvent converts from the native keycode (XKB) to the code.
299     ScopedXI2Event xevent;
300     xevent.InitKeyEvent(ET_KEY_PRESSED, VKEY_SPACE, kNativeCodeSpace);
301     KeyEvent key(xevent, false);
302     EXPECT_EQ(kCodeForSpace, key.code());
303   }
304 #endif  // USE_X11
305 #if defined(OS_WIN)
306   {
307     // Test a non extended key.
308     ASSERT_EQ((kNativeCodeSpace & 0xFF), kNativeCodeSpace);
309
310     const LPARAM lParam = GetLParamFromScanCode(kNativeCodeSpace);
311     MSG native_event = { NULL, WM_KEYUP, VKEY_SPACE, lParam };
312     KeyEvent key(native_event, false);
313
314     // KeyEvent converts from the native keycode (scan code) to the code.
315     EXPECT_EQ(kCodeForSpace, key.code());
316   }
317   {
318     const char kCodeForHome[]  = "Home";
319     const uint16 kNativeCodeHome  = 0xe047;
320
321     // 'Home' is an extended key with 0xe000 bits.
322     ASSERT_NE((kNativeCodeHome & 0xFF), kNativeCodeHome);
323     const LPARAM lParam = GetLParamFromScanCode(kNativeCodeHome);
324
325     MSG native_event = { NULL, WM_KEYUP, VKEY_HOME, lParam };
326     KeyEvent key(native_event, false);
327
328     // KeyEvent converts from the native keycode (scan code) to the code.
329     EXPECT_EQ(kCodeForHome, key.code());
330   }
331 #endif  // OS_WIN
332 }
333
334 #if defined(USE_X11) || defined(OS_WIN)
335 TEST(EventTest, AutoRepeat) {
336   KeycodeConverter* conv = KeycodeConverter::GetInstance();
337
338   const uint16 kNativeCodeA = conv->CodeToNativeKeycode("KeyA");
339   const uint16 kNativeCodeB = conv->CodeToNativeKeycode("KeyB");
340 #if defined(USE_X11)
341   ScopedXI2Event native_event_a_pressed;
342   native_event_a_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
343   ScopedXI2Event native_event_a_released;
344   native_event_a_released.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, kNativeCodeA);
345   ScopedXI2Event native_event_b_pressed;
346   native_event_b_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_B, kNativeCodeB);
347 #elif defined(OS_WIN)
348   const LPARAM lParam_a = GetLParamFromScanCode(kNativeCodeA);
349   const LPARAM lParam_b = GetLParamFromScanCode(kNativeCodeB);
350   MSG native_event_a_pressed = { NULL, WM_KEYDOWN, VKEY_A, lParam_a };
351   MSG native_event_a_released = { NULL, WM_KEYUP, VKEY_A, lParam_a };
352   MSG native_event_b_pressed = { NULL, WM_KEYUP, VKEY_B, lParam_b };
353 #endif
354   KeyEvent key_a1(native_event_a_pressed, false);
355   DCHECK(!key_a1.IsRepeat());
356   KeyEvent key_a1_released(native_event_a_released, false);
357   DCHECK(!key_a1_released.IsRepeat());
358
359   KeyEvent key_a2(native_event_a_pressed, false);
360   DCHECK(!key_a2.IsRepeat());
361   KeyEvent key_a2_repeated(native_event_a_pressed, false);
362   DCHECK(key_a2_repeated.IsRepeat());
363   KeyEvent key_a2_released(native_event_a_released, false);
364   DCHECK(!key_a2_released.IsRepeat());
365
366   KeyEvent key_a3(native_event_a_pressed, false);
367   DCHECK(!key_a3.IsRepeat());
368   KeyEvent key_b(native_event_b_pressed, false);
369   DCHECK(!key_b.IsRepeat());
370   KeyEvent key_a3_again(native_event_a_pressed, false);
371   DCHECK(!key_a3_again.IsRepeat());
372   KeyEvent key_a3_repeated(native_event_a_pressed, false);
373   DCHECK(key_a3_repeated.IsRepeat());
374   KeyEvent key_a3_repeated2(native_event_a_pressed, false);
375   DCHECK(key_a3_repeated2.IsRepeat());
376   KeyEvent key_a3_released(native_event_a_released, false);
377   DCHECK(!key_a3_released.IsRepeat());
378 }
379 #endif  // USE_X11 || OS_WIN
380
381 }  // namespace ui