OLD | NEW |
| (Empty) |
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 "ui/base/ime/character_composer.h" | |
6 | |
7 #include "base/strings/utf_string_conversions.h" | |
8 #include "testing/gtest/include/gtest/gtest.h" | |
9 #include "third_party/gtk+/gdk/gdkkeysyms.h" | |
10 #include "ui/base/glib/glib_integers.h" | |
11 #include "ui/events/event_constants.h" | |
12 | |
13 namespace ui { | |
14 | |
15 class CharacterComposerTest : public testing::Test { | |
16 protected: | |
17 bool FilterKeyPress(CharacterComposer* character_composer, | |
18 uint key, | |
19 uint keycode, | |
20 int flags) { | |
21 return character_composer->FilterKeyPressInternal(key, keycode, flags); | |
22 } | |
23 | |
24 // Expects key is not filtered and no character is composed. | |
25 void ExpectKeyNotFilteredWithKeyCode(CharacterComposer* character_composer, | |
26 uint key, | |
27 uint keycode, | |
28 int flags) { | |
29 EXPECT_FALSE(character_composer->FilterKeyPressInternal(key, keycode, | |
30 flags)); | |
31 EXPECT_TRUE(character_composer->composed_character().empty()); | |
32 } | |
33 | |
34 // Expects key is filtered and no character is composed. | |
35 void ExpectKeyFilteredWithKeycode(CharacterComposer* character_composer, | |
36 uint key, | |
37 uint keycode, | |
38 int flags) { | |
39 EXPECT_TRUE(character_composer->FilterKeyPressInternal(key, keycode, | |
40 flags)); | |
41 EXPECT_TRUE(character_composer->composed_character().empty()); | |
42 } | |
43 | |
44 // Expects key is not filtered and no character is composed. | |
45 void ExpectKeyNotFiltered(CharacterComposer* character_composer, | |
46 uint key, | |
47 int flags) { | |
48 ExpectKeyNotFilteredWithKeyCode(character_composer, key, 0, flags); | |
49 } | |
50 | |
51 // Expects key is filtered and no character is composed. | |
52 void ExpectKeyFiltered(CharacterComposer* character_composer, | |
53 uint key, | |
54 int flags) { | |
55 ExpectKeyFilteredWithKeycode(character_composer, key, 0, flags); | |
56 } | |
57 | |
58 // Expects |expected_character| is composed after sequence [key1, key2]. | |
59 void ExpectCharacterComposed(CharacterComposer* character_composer, | |
60 uint key1, | |
61 uint key2, | |
62 int flags, | |
63 const string16& expected_character) { | |
64 ExpectKeyFiltered(character_composer, key1, flags); | |
65 EXPECT_TRUE(character_composer->FilterKeyPressInternal(key2, 0, flags)); | |
66 EXPECT_EQ(expected_character, character_composer->composed_character()); | |
67 } | |
68 | |
69 // Expects |expected_character| is composed after sequence [key1, key2, key3]. | |
70 void ExpectCharacterComposed(CharacterComposer* character_composer, | |
71 uint key1, | |
72 uint key2, | |
73 uint key3, | |
74 int flags, | |
75 const string16& expected_character) { | |
76 ExpectKeyFiltered(character_composer, key1, flags); | |
77 ExpectCharacterComposed(character_composer, key2, key3, flags, | |
78 expected_character); | |
79 } | |
80 | |
81 // Expects |expected_character| is composed after sequence [key1, key2, key3, | |
82 // key 4]. | |
83 void ExpectCharacterComposed(CharacterComposer* character_composer, | |
84 uint key1, | |
85 uint key2, | |
86 uint key3, | |
87 uint key4, | |
88 int flags, | |
89 const string16& expected_character) { | |
90 ExpectKeyFiltered(character_composer, key1, flags); | |
91 ExpectCharacterComposed(character_composer, key2, key3, key4, flags, | |
92 expected_character); | |
93 } | |
94 | |
95 // Expects |expected_character| is composed after sequence [key1, key2, key3, | |
96 // key 4, key5]. | |
97 void ExpectCharacterComposed(CharacterComposer* character_composer, | |
98 uint key1, | |
99 uint key2, | |
100 uint key3, | |
101 uint key4, | |
102 uint key5, | |
103 int flags, | |
104 const string16& expected_character) { | |
105 ExpectKeyFiltered(character_composer, key1, flags); | |
106 ExpectCharacterComposed(character_composer, key2, key3, key4, key5, flags, | |
107 expected_character); | |
108 } | |
109 | |
110 // Expects |expected_character| is composed after sequence [key1, key2, key3, | |
111 // key 4, key5, key6]. | |
112 void ExpectCharacterComposed(CharacterComposer* character_composer, | |
113 uint key1, | |
114 uint key2, | |
115 uint key3, | |
116 uint key4, | |
117 uint key5, | |
118 uint key6, | |
119 int flags, | |
120 const string16& expected_character) { | |
121 ExpectKeyFiltered(character_composer, key1, flags); | |
122 ExpectCharacterComposed(character_composer, key2, key3, key4, key5, key6, | |
123 flags, expected_character); | |
124 } | |
125 | |
126 // Expects |expected_character| is composed after sequence [{key1, keycode1}]. | |
127 void ExpectCharacterComposedWithKeyCode(CharacterComposer* character_composer, | |
128 uint key1, uint keycode1, | |
129 int flags, | |
130 const string16& expected_character) { | |
131 EXPECT_TRUE(character_composer->FilterKeyPressInternal(key1, keycode1, | |
132 flags)); | |
133 EXPECT_EQ(expected_character, character_composer->composed_character()); | |
134 } | |
135 }; | |
136 | |
137 TEST_F(CharacterComposerTest, InitialState) { | |
138 CharacterComposer character_composer; | |
139 EXPECT_TRUE(character_composer.composed_character().empty()); | |
140 } | |
141 | |
142 TEST_F(CharacterComposerTest, NormalKeyIsNotFiltered) { | |
143 CharacterComposer character_composer; | |
144 ExpectKeyNotFiltered(&character_composer, GDK_KEY_B, 0); | |
145 ExpectKeyNotFiltered(&character_composer, GDK_KEY_Z, 0); | |
146 ExpectKeyNotFiltered(&character_composer, GDK_KEY_c, 0); | |
147 ExpectKeyNotFiltered(&character_composer, GDK_KEY_m, 0); | |
148 ExpectKeyNotFiltered(&character_composer, GDK_KEY_0, 0); | |
149 ExpectKeyNotFiltered(&character_composer, GDK_KEY_1, 0); | |
150 ExpectKeyNotFiltered(&character_composer, GDK_KEY_8, 0); | |
151 } | |
152 | |
153 TEST_F(CharacterComposerTest, PartiallyMatchingSequence) { | |
154 CharacterComposer character_composer; | |
155 | |
156 // Composition with sequence ['dead acute', '1'] will fail. | |
157 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0); | |
158 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0); | |
159 | |
160 // Composition with sequence ['dead acute', 'dead circumflex', '1'] will fail. | |
161 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0); | |
162 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_circumflex, 0); | |
163 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0); | |
164 } | |
165 | |
166 TEST_F(CharacterComposerTest, FullyMatchingSequences) { | |
167 CharacterComposer character_composer; | |
168 // LATIN SMALL LETTER A WITH ACUTE | |
169 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0, | |
170 string16(1, 0x00E1)); | |
171 // LATIN CAPITAL LETTER A WITH ACUTE | |
172 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_A, 0, | |
173 string16(1, 0x00C1)); | |
174 // GRAVE ACCENT | |
175 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_grave, | |
176 GDK_KEY_dead_grave, 0, string16(1, 0x0060)); | |
177 // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE | |
178 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, | |
179 GDK_KEY_dead_circumflex, GDK_KEY_a, 0, | |
180 string16(1, 0x1EA5)); | |
181 // LATIN CAPITAL LETTER U WITH HORN AND GRAVE | |
182 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_grave, | |
183 GDK_KEY_dead_horn, GDK_KEY_U, 0, string16(1, 0x1EEA)); | |
184 // LATIN CAPITAL LETTER C WITH CEDILLA | |
185 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_C, 0, | |
186 string16(1, 0x00C7)); | |
187 // LATIN SMALL LETTER C WITH CEDILLA | |
188 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_c, 0, | |
189 string16(1, 0x00E7)); | |
190 } | |
191 | |
192 TEST_F(CharacterComposerTest, FullyMatchingSequencesAfterMatchingFailure) { | |
193 CharacterComposer character_composer; | |
194 // Composition with sequence ['dead acute', 'dead circumflex', '1'] will fail. | |
195 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0); | |
196 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_circumflex, 0); | |
197 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0); | |
198 // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE | |
199 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, | |
200 GDK_KEY_dead_circumflex, GDK_KEY_a, 0, | |
201 string16(1, 0x1EA5)); | |
202 } | |
203 | |
204 TEST_F(CharacterComposerTest, ComposedCharacterIsClearedAfterReset) { | |
205 CharacterComposer character_composer; | |
206 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0, | |
207 string16(1, 0x00E1)); | |
208 character_composer.Reset(); | |
209 EXPECT_TRUE(character_composer.composed_character().empty()); | |
210 } | |
211 | |
212 TEST_F(CharacterComposerTest, CompositionStateIsClearedAfterReset) { | |
213 CharacterComposer character_composer; | |
214 // Even though sequence ['dead acute', 'a'] will compose 'a with acute', | |
215 // no character is composed here because of reset. | |
216 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0); | |
217 character_composer.Reset(); | |
218 ExpectKeyNotFiltered(&character_composer, GDK_KEY_a, 0); | |
219 } | |
220 | |
221 TEST_F(CharacterComposerTest, KeySequenceCompositionPreedit) { | |
222 CharacterComposer character_composer; | |
223 // LATIN SMALL LETTER A WITH ACUTE | |
224 // preedit_string() is always empty in key sequence composition mode. | |
225 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0); | |
226 EXPECT_TRUE(character_composer.preedit_string().empty()); | |
227 EXPECT_TRUE(FilterKeyPress(&character_composer, GDK_KEY_a, 0, 0)); | |
228 EXPECT_EQ(string16(1, 0x00E1), character_composer.composed_character()); | |
229 EXPECT_TRUE(character_composer.preedit_string().empty()); | |
230 } | |
231 | |
232 // ComposeCheckerWithCompactTable in character_composer.cc is depending on the | |
233 // assumption that the data in gtkimcontextsimpleseqs.h is correctly ordered. | |
234 TEST_F(CharacterComposerTest, MainTableIsCorrectlyOrdered) { | |
235 // This file is included here intentionally, instead of the top of the file, | |
236 // because including this file at the top of the file will define a | |
237 // global constant and contaminate the global namespace. | |
238 #include "third_party/gtk+/gtk/gtkimcontextsimpleseqs.h" | |
239 const int index_size = 26; | |
240 const int index_stride = 6; | |
241 | |
242 // Verify that the index is correctly ordered | |
243 for (int i = 1; i < index_size; ++i) { | |
244 const int index_key_prev = gtk_compose_seqs_compact[(i - 1)*index_stride]; | |
245 const int index_key = gtk_compose_seqs_compact[i*index_stride]; | |
246 EXPECT_TRUE(index_key > index_key_prev); | |
247 } | |
248 | |
249 // Verify that the sequenes are correctly ordered | |
250 struct { | |
251 int operator()(const uint16* l, const uint16* r, int length) const{ | |
252 for (int i = 0; i < length; ++i) { | |
253 if (l[i] > r[i]) | |
254 return 1; | |
255 if (l[i] < r[i]) | |
256 return -1; | |
257 } | |
258 return 0; | |
259 } | |
260 } compare_sequence; | |
261 | |
262 for (int i = 0; i < index_size; ++i) { | |
263 for (int length = 1; length < index_stride - 1; ++length) { | |
264 const int index_begin = gtk_compose_seqs_compact[i*index_stride + length]; | |
265 const int index_end = | |
266 gtk_compose_seqs_compact[i*index_stride + length + 1]; | |
267 const int stride = length + 1; | |
268 for (int index = index_begin + stride; index < index_end; | |
269 index += stride) { | |
270 const uint16* sequence = >k_compose_seqs_compact[index]; | |
271 const uint16* sequence_prev = sequence - stride; | |
272 EXPECT_EQ(1, compare_sequence(sequence, sequence_prev, length)); | |
273 } | |
274 } | |
275 } | |
276 } | |
277 | |
278 TEST_F(CharacterComposerTest, HexadecimalComposition) { | |
279 CharacterComposer character_composer; | |
280 // HIRAGANA LETTER A (U+3042) | |
281 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
282 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
283 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4, | |
284 GDK_KEY_2, GDK_KEY_space, 0, string16(1, 0x3042)); | |
285 // MUSICAL KEYBOARD (U+1F3B9) | |
286 const char16 kMusicalKeyboard[] = {0xd83c, 0xdfb9}; | |
287 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
288 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
289 ExpectCharacterComposed(&character_composer, GDK_KEY_1, GDK_KEY_f, GDK_KEY_3, | |
290 GDK_KEY_b, GDK_KEY_9, GDK_KEY_Return, 0, | |
291 string16(kMusicalKeyboard, | |
292 kMusicalKeyboard + | |
293 arraysize(kMusicalKeyboard))); | |
294 } | |
295 | |
296 TEST_F(CharacterComposerTest, HexadecimalCompositionPreedit) { | |
297 CharacterComposer character_composer; | |
298 // HIRAGANA LETTER A (U+3042) | |
299 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
300 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
301 EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string()); | |
302 ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0); | |
303 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string()); | |
304 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0); | |
305 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string()); | |
306 ExpectKeyFiltered(&character_composer, GDK_KEY_4, 0); | |
307 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string()); | |
308 ExpectKeyFiltered(&character_composer, GDK_KEY_a, 0); | |
309 EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer.preedit_string()); | |
310 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0); | |
311 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string()); | |
312 ExpectCharacterComposed(&character_composer, GDK_KEY_2, GDK_KEY_Return, 0, | |
313 string16(1, 0x3042)); | |
314 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string()); | |
315 | |
316 // Sequence with an ignored character ('x') and Escape. | |
317 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
318 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
319 EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string()); | |
320 ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0); | |
321 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string()); | |
322 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0); | |
323 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string()); | |
324 ExpectKeyFiltered(&character_composer, GDK_KEY_x, 0); | |
325 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string()); | |
326 ExpectKeyFiltered(&character_composer, GDK_KEY_4, 0); | |
327 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string()); | |
328 ExpectKeyFiltered(&character_composer, GDK_KEY_2, 0); | |
329 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string()); | |
330 ExpectKeyFiltered(&character_composer, GDK_KEY_Escape, 0); | |
331 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string()); | |
332 } | |
333 | |
334 TEST_F(CharacterComposerTest, HexadecimalCompositionWithNonHexKey) { | |
335 CharacterComposer character_composer; | |
336 | |
337 // Sequence [Ctrl+Shift+U, x, space] does not compose a character. | |
338 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
339 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
340 ExpectKeyFiltered(&character_composer, GDK_KEY_x, 0); | |
341 ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0); | |
342 EXPECT_TRUE(character_composer.composed_character().empty()); | |
343 | |
344 // HIRAGANA LETTER A (U+3042) with a sequence [3, 0, x, 4, 2]. | |
345 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
346 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
347 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_x, | |
348 GDK_KEY_4, GDK_KEY_2, GDK_KEY_space, 0, | |
349 string16(1, 0x3042)); | |
350 } | |
351 | |
352 TEST_F(CharacterComposerTest, HexadecimalCompositionWithAdditionalModifiers) { | |
353 CharacterComposer character_composer; | |
354 | |
355 // Ctrl+Shift+Alt+U | |
356 // HIRAGANA LETTER A (U+3042) | |
357 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
358 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_ALT_DOWN); | |
359 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4, | |
360 GDK_KEY_2, GDK_KEY_space, 0, string16(1, 0x3042)); | |
361 | |
362 // Ctrl+Shift+u (CapsLock enabled) | |
363 ExpectKeyNotFiltered(&character_composer, GDK_KEY_u, | |
364 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_CAPS_LOCK_DOWN); | |
365 } | |
366 | |
367 TEST_F(CharacterComposerTest, CancelHexadecimalComposition) { | |
368 CharacterComposer character_composer; | |
369 // Cancel composition with ESC. | |
370 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
371 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
372 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0); | |
373 ExpectKeyFiltered(&character_composer, GDK_KEY_Escape, 0); | |
374 | |
375 // Now we can start composition again since the last composition was | |
376 // cancelled. | |
377 // HIRAGANA LETTER A (U+3042) | |
378 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
379 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
380 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4, | |
381 GDK_KEY_2, GDK_KEY_space, 0, string16(1, 0x3042)); | |
382 } | |
383 | |
384 TEST_F(CharacterComposerTest, HexadecimalCompositionWithBackspace) { | |
385 CharacterComposer character_composer; | |
386 // HIRAGANA LETTER A (U+3042) | |
387 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
388 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
389 ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0); | |
390 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0); | |
391 ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0); | |
392 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0); | |
393 ExpectCharacterComposed(&character_composer, GDK_KEY_4, GDK_KEY_2, | |
394 GDK_KEY_space, 0, string16(1, 0x3042)); | |
395 } | |
396 | |
397 TEST_F(CharacterComposerTest, CancelHexadecimalCompositionWithBackspace) { | |
398 CharacterComposer character_composer; | |
399 | |
400 // Backspace just after Ctrl+Shift+U. | |
401 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
402 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
403 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0); | |
404 ExpectKeyNotFiltered(&character_composer, GDK_KEY_3, 0); | |
405 | |
406 // Backspace twice after Ctrl+Shift+U and 3. | |
407 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
408 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
409 ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0); | |
410 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0); | |
411 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0); | |
412 ExpectKeyNotFiltered(&character_composer, GDK_KEY_3, 0); | |
413 } | |
414 | |
415 TEST_F(CharacterComposerTest, HexadecimalCompositionPreeditWithModifierPressed) | |
416 { | |
417 // This test case supposes X Window System uses 101 keyboard layout. | |
418 CharacterComposer character_composer; | |
419 const int control_shift = EF_CONTROL_DOWN | EF_SHIFT_DOWN; | |
420 // HIRAGANA LETTER A (U+3042) | |
421 ExpectKeyFilteredWithKeycode(&character_composer, | |
422 GDK_KEY_U, 30, control_shift); | |
423 EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string()); | |
424 ExpectKeyFilteredWithKeycode(&character_composer, | |
425 GDK_KEY_numbersign, 12, control_shift); | |
426 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string()); | |
427 ExpectKeyFilteredWithKeycode(&character_composer, | |
428 GDK_KEY_parenright, 19, control_shift); | |
429 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string()); | |
430 ExpectKeyFilteredWithKeycode(&character_composer, | |
431 GDK_KEY_dollar, 13, control_shift); | |
432 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string()); | |
433 ExpectKeyFilteredWithKeycode(&character_composer, | |
434 GDK_KEY_A, 38, control_shift); | |
435 EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer.preedit_string()); | |
436 ExpectKeyFilteredWithKeycode(&character_composer, | |
437 GDK_KEY_BackSpace, 22, control_shift); | |
438 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string()); | |
439 ExpectKeyFilteredWithKeycode(&character_composer, | |
440 GDK_KEY_at, 11, control_shift); | |
441 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string()); | |
442 ExpectCharacterComposedWithKeyCode(&character_composer, | |
443 GDK_KEY_Return, 36, | |
444 control_shift, | |
445 string16(1, 0x3042)); | |
446 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string()); | |
447 | |
448 // Sequence with an ignored character (control + shift + 'x') and Escape. | |
449 ExpectKeyFilteredWithKeycode(&character_composer, | |
450 GDK_KEY_U, 30, control_shift); | |
451 EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string()); | |
452 ExpectKeyFilteredWithKeycode(&character_composer, | |
453 GDK_KEY_numbersign, 12, control_shift); | |
454 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string()); | |
455 ExpectKeyFilteredWithKeycode(&character_composer, | |
456 GDK_KEY_parenright, 19, control_shift); | |
457 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string()); | |
458 ExpectKeyFilteredWithKeycode(&character_composer, | |
459 GDK_KEY_X, 53, control_shift); | |
460 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string()); | |
461 ExpectKeyFilteredWithKeycode(&character_composer, | |
462 GDK_KEY_dollar, 13, control_shift); | |
463 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string()); | |
464 ExpectKeyFilteredWithKeycode(&character_composer, | |
465 GDK_KEY_at, 11, control_shift); | |
466 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string()); | |
467 ExpectKeyFilteredWithKeycode(&character_composer, | |
468 GDK_KEY_Escape, 9, control_shift); | |
469 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string()); | |
470 } | |
471 | |
472 TEST_F(CharacterComposerTest, InvalidHexadecimalSequence) { | |
473 CharacterComposer character_composer; | |
474 // U+FFFFFFFF | |
475 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
476 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
477 for (int i = 0; i < 8; ++i) | |
478 ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0); | |
479 ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0); | |
480 | |
481 // U+0000 (Actually, this is a valid unicode character, but we don't | |
482 // compose a string with a character '\0') | |
483 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
484 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
485 for (int i = 0; i < 4; ++i) | |
486 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0); | |
487 ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0); | |
488 | |
489 // U+10FFFF | |
490 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
491 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
492 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0); | |
493 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0); | |
494 for (int i = 0; i < 4; ++i) | |
495 ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0); | |
496 ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0); | |
497 | |
498 // U+110000 | |
499 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
500 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
501 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0); | |
502 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0); | |
503 for (int i = 0; i < 4; ++i) | |
504 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0); | |
505 ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0); | |
506 } | |
507 | |
508 TEST_F(CharacterComposerTest, HexadecimalSequenceAndDeadKey) { | |
509 CharacterComposer character_composer; | |
510 // LATIN SMALL LETTER A WITH ACUTE | |
511 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0, | |
512 string16(1, 0x00E1)); | |
513 // HIRAGANA LETTER A (U+3042) with dead_acute ignored. | |
514 ExpectKeyFiltered(&character_composer, GDK_KEY_U, | |
515 EF_SHIFT_DOWN | EF_CONTROL_DOWN); | |
516 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, | |
517 GDK_KEY_dead_acute, GDK_KEY_4, GDK_KEY_2, | |
518 GDK_KEY_space, 0, string16(1, 0x3042)); | |
519 // LATIN CAPITAL LETTER U WITH ACUTE while 'U' is pressed with Ctrl+Shift. | |
520 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0); | |
521 EXPECT_TRUE(FilterKeyPress(&character_composer, GDK_KEY_U, 0, | |
522 EF_SHIFT_DOWN | EF_CONTROL_DOWN)); | |
523 EXPECT_EQ(string16(1, 0x00DA), character_composer.composed_character()); | |
524 } | |
525 | |
526 TEST_F(CharacterComposerTest, BlacklistedKeyeventsTest) { | |
527 CharacterComposer character_composer; | |
528 EXPECT_TRUE(FilterKeyPress(&character_composer, GDK_KEY_dead_acute, 0, 0)); | |
529 EXPECT_FALSE(FilterKeyPress(&character_composer, GDK_KEY_s, 0, 0)); | |
530 ASSERT_EQ(1U, character_composer.composed_character().size()); | |
531 EXPECT_EQ(GDK_KEY_apostrophe, character_composer.composed_character().at(0)); | |
532 } | |
533 | |
534 } // namespace ui | |
OLD | NEW |