1 // Copyright 2013 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 "ui/base/ime/chromeos/character_composer.h"
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 #include "ui/events/keycodes/keyboard_codes.h"
14 using base::ASCIIToUTF16
;
18 class CharacterComposerTest
: public testing::Test
{
20 bool FilterKeyPress(CharacterComposer
* character_composer
,
24 return character_composer
->FilterKeyPressInternal(key
, keycode
, flags
);
27 // Expects key is not filtered and no character is composed.
28 void ExpectKeyNotFilteredWithKeyCode(CharacterComposer
* character_composer
,
32 EXPECT_FALSE(character_composer
->FilterKeyPressInternal(key
, keycode
,
34 EXPECT_TRUE(character_composer
->composed_character().empty());
37 // Expects key is filtered and no character is composed.
38 void ExpectKeyFilteredWithKeycode(CharacterComposer
* character_composer
,
42 EXPECT_TRUE(character_composer
->FilterKeyPressInternal(key
, keycode
,
44 EXPECT_TRUE(character_composer
->composed_character().empty());
47 // Expects key is not filtered and no character is composed.
48 void ExpectKeyNotFiltered(CharacterComposer
* character_composer
,
51 ExpectKeyNotFilteredWithKeyCode(character_composer
, key
, 0, flags
);
54 // Expects key is filtered and no character is composed.
55 void ExpectKeyFiltered(CharacterComposer
* character_composer
,
58 ExpectKeyFilteredWithKeycode(character_composer
, key
, 0, flags
);
61 // Expects |expected_character| is composed after sequence [key1, key2].
62 void ExpectCharacterComposed(CharacterComposer
* character_composer
,
66 const base::string16
& expected_character
) {
67 ExpectKeyFiltered(character_composer
, key1
, flags
);
68 EXPECT_TRUE(character_composer
->FilterKeyPressInternal(key2
, 0, flags
));
69 EXPECT_EQ(expected_character
, character_composer
->composed_character());
72 // Expects |expected_character| is composed after sequence [key1, key2, key3].
73 void ExpectCharacterComposed(CharacterComposer
* character_composer
,
78 const base::string16
& expected_character
) {
79 ExpectKeyFiltered(character_composer
, key1
, flags
);
80 ExpectCharacterComposed(character_composer
, key2
, key3
, flags
,
84 // Expects |expected_character| is composed after sequence [key1, key2, key3,
86 void ExpectCharacterComposed(CharacterComposer
* character_composer
,
92 const base::string16
& expected_character
) {
93 ExpectKeyFiltered(character_composer
, key1
, flags
);
94 ExpectCharacterComposed(character_composer
, key2
, key3
, key4
, flags
,
98 // Expects |expected_character| is composed after sequence [key1, key2, key3,
100 void ExpectCharacterComposed(CharacterComposer
* character_composer
,
107 const base::string16
& expected_character
) {
108 ExpectKeyFiltered(character_composer
, key1
, flags
);
109 ExpectCharacterComposed(character_composer
, key2
, key3
, key4
, key5
, flags
,
113 // Expects |expected_character| is composed after sequence [key1, key2, key3,
114 // key 4, key5, key6].
115 void ExpectCharacterComposed(CharacterComposer
* character_composer
,
123 const base::string16
& expected_character
) {
124 ExpectKeyFiltered(character_composer
, key1
, flags
);
125 ExpectCharacterComposed(character_composer
, key2
, key3
, key4
, key5
, key6
,
126 flags
, expected_character
);
129 // Expects |expected_character| is composed after sequence [{key1, keycode1}].
130 void ExpectCharacterComposedWithKeyCode(
131 CharacterComposer
* character_composer
,
132 uint key1
, uint keycode1
,
134 const base::string16
& expected_character
) {
135 EXPECT_TRUE(character_composer
->FilterKeyPressInternal(key1
, keycode1
,
137 EXPECT_EQ(expected_character
, character_composer
->composed_character());
141 TEST_F(CharacterComposerTest
, InitialState
) {
142 CharacterComposer character_composer
;
143 EXPECT_TRUE(character_composer
.composed_character().empty());
146 TEST_F(CharacterComposerTest
, NormalKeyIsNotFiltered
) {
147 CharacterComposer character_composer
;
148 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_B
, 0);
149 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_Z
, 0);
150 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_c
, 0);
151 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_m
, 0);
152 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_0
, 0);
153 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_1
, 0);
154 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_8
, 0);
157 TEST_F(CharacterComposerTest
, PartiallyMatchingSequence
) {
158 CharacterComposer character_composer
;
160 // Composition with sequence ['dead acute', '1'] will fail.
161 ExpectKeyFiltered(&character_composer
, GDK_KEY_dead_acute
, 0);
162 ExpectKeyFiltered(&character_composer
, GDK_KEY_1
, 0);
164 // Composition with sequence ['dead acute', 'dead circumflex', '1'] will fail.
165 ExpectKeyFiltered(&character_composer
, GDK_KEY_dead_acute
, 0);
166 ExpectKeyFiltered(&character_composer
, GDK_KEY_dead_circumflex
, 0);
167 ExpectKeyFiltered(&character_composer
, GDK_KEY_1
, 0);
170 TEST_F(CharacterComposerTest
, FullyMatchingSequences
) {
171 CharacterComposer character_composer
;
172 // LATIN SMALL LETTER A WITH ACUTE
173 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_acute
, GDK_KEY_a
, 0,
174 base::string16(1, 0x00E1));
175 // LATIN CAPITAL LETTER A WITH ACUTE
176 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_acute
, GDK_KEY_A
, 0,
177 base::string16(1, 0x00C1));
179 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_grave
,
180 GDK_KEY_dead_grave
, 0, base::string16(1, 0x0060));
181 // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
182 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_acute
,
183 GDK_KEY_dead_circumflex
, GDK_KEY_a
, 0,
184 base::string16(1, 0x1EA5));
185 // LATIN CAPITAL LETTER U WITH HORN AND GRAVE
186 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_grave
,
187 GDK_KEY_dead_horn
, GDK_KEY_U
, 0,
188 base::string16(1, 0x1EEA));
189 // LATIN CAPITAL LETTER C WITH CEDILLA
190 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_acute
, GDK_KEY_C
, 0,
191 base::string16(1, 0x00C7));
192 // LATIN SMALL LETTER C WITH CEDILLA
193 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_acute
, GDK_KEY_c
, 0,
194 base::string16(1, 0x00E7));
197 TEST_F(CharacterComposerTest
, FullyMatchingSequencesAfterMatchingFailure
) {
198 CharacterComposer character_composer
;
199 // Composition with sequence ['dead acute', 'dead circumflex', '1'] will fail.
200 ExpectKeyFiltered(&character_composer
, GDK_KEY_dead_acute
, 0);
201 ExpectKeyFiltered(&character_composer
, GDK_KEY_dead_circumflex
, 0);
202 ExpectKeyFiltered(&character_composer
, GDK_KEY_1
, 0);
203 // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
204 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_acute
,
205 GDK_KEY_dead_circumflex
, GDK_KEY_a
, 0,
206 base::string16(1, 0x1EA5));
209 TEST_F(CharacterComposerTest
, ComposedCharacterIsClearedAfterReset
) {
210 CharacterComposer character_composer
;
211 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_acute
, GDK_KEY_a
, 0,
212 base::string16(1, 0x00E1));
213 character_composer
.Reset();
214 EXPECT_TRUE(character_composer
.composed_character().empty());
217 TEST_F(CharacterComposerTest
, CompositionStateIsClearedAfterReset
) {
218 CharacterComposer character_composer
;
219 // Even though sequence ['dead acute', 'a'] will compose 'a with acute',
220 // no character is composed here because of reset.
221 ExpectKeyFiltered(&character_composer
, GDK_KEY_dead_acute
, 0);
222 character_composer
.Reset();
223 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_a
, 0);
226 TEST_F(CharacterComposerTest
, KeySequenceCompositionPreedit
) {
227 CharacterComposer character_composer
;
228 // LATIN SMALL LETTER A WITH ACUTE
229 // preedit_string() is always empty in key sequence composition mode.
230 ExpectKeyFiltered(&character_composer
, GDK_KEY_dead_acute
, 0);
231 EXPECT_TRUE(character_composer
.preedit_string().empty());
232 EXPECT_TRUE(FilterKeyPress(&character_composer
, GDK_KEY_a
, 0, 0));
233 EXPECT_EQ(base::string16(1, 0x00E1), character_composer
.composed_character());
234 EXPECT_TRUE(character_composer
.preedit_string().empty());
237 // ComposeCheckerWithCompactTable in character_composer.cc is depending on the
238 // assumption that the data in gtkimcontextsimpleseqs.h is correctly ordered.
239 TEST_F(CharacterComposerTest
, MainTableIsCorrectlyOrdered
) {
240 // This file is included here intentionally, instead of the top of the file,
241 // because including this file at the top of the file will define a
242 // global constant and contaminate the global namespace.
243 #include "third_party/gtk+/gtk/gtkimcontextsimpleseqs.h"
244 const int index_size
= 26;
245 const int index_stride
= 6;
247 // Verify that the index is correctly ordered
248 for (int i
= 1; i
< index_size
; ++i
) {
249 const int index_key_prev
= gtk_compose_seqs_compact
[(i
- 1)*index_stride
];
250 const int index_key
= gtk_compose_seqs_compact
[i
*index_stride
];
251 EXPECT_TRUE(index_key
> index_key_prev
);
254 // Verify that the sequenes are correctly ordered
256 int operator()(const uint16
* l
, const uint16
* r
, int length
) const{
257 for (int i
= 0; i
< length
; ++i
) {
267 for (int i
= 0; i
< index_size
; ++i
) {
268 for (int length
= 1; length
< index_stride
- 1; ++length
) {
269 const int index_begin
= gtk_compose_seqs_compact
[i
*index_stride
+ length
];
270 const int index_end
=
271 gtk_compose_seqs_compact
[i
*index_stride
+ length
+ 1];
272 const int stride
= length
+ 1;
273 for (int index
= index_begin
+ stride
; index
< index_end
;
275 const uint16
* sequence
= >k_compose_seqs_compact
[index
];
276 const uint16
* sequence_prev
= sequence
- stride
;
277 EXPECT_EQ(1, compare_sequence(sequence
, sequence_prev
, length
));
283 TEST_F(CharacterComposerTest
, HexadecimalComposition
) {
284 CharacterComposer character_composer
;
285 // HIRAGANA LETTER A (U+3042)
286 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
287 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
288 ExpectCharacterComposed(&character_composer
, GDK_KEY_3
, GDK_KEY_0
, GDK_KEY_4
,
289 GDK_KEY_2
, GDK_KEY_space
, 0,
290 base::string16(1, 0x3042));
291 // MUSICAL KEYBOARD (U+1F3B9)
292 const base::char16 kMusicalKeyboard
[] = {0xd83c, 0xdfb9};
293 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
294 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
295 ExpectCharacterComposed(&character_composer
, GDK_KEY_1
, GDK_KEY_f
, GDK_KEY_3
,
296 GDK_KEY_b
, GDK_KEY_9
, GDK_KEY_Return
, 0,
297 base::string16(kMusicalKeyboard
,
299 arraysize(kMusicalKeyboard
)));
302 TEST_F(CharacterComposerTest
, HexadecimalCompositionPreedit
) {
303 CharacterComposer character_composer
;
304 // HIRAGANA LETTER A (U+3042)
305 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
306 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
307 EXPECT_EQ(ASCIIToUTF16("u"), character_composer
.preedit_string());
308 ExpectKeyFiltered(&character_composer
, GDK_KEY_3
, 0);
309 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer
.preedit_string());
310 ExpectKeyFiltered(&character_composer
, GDK_KEY_0
, 0);
311 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer
.preedit_string());
312 ExpectKeyFiltered(&character_composer
, GDK_KEY_4
, 0);
313 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer
.preedit_string());
314 ExpectKeyFiltered(&character_composer
, GDK_KEY_a
, 0);
315 EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer
.preedit_string());
316 ExpectKeyFiltered(&character_composer
, GDK_KEY_BackSpace
, 0);
317 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer
.preedit_string());
318 ExpectCharacterComposed(&character_composer
, GDK_KEY_2
, GDK_KEY_Return
, 0,
319 base::string16(1, 0x3042));
320 EXPECT_EQ(ASCIIToUTF16(""), character_composer
.preedit_string());
322 // Sequence with an ignored character ('x') and Escape.
323 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
324 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
325 EXPECT_EQ(ASCIIToUTF16("u"), character_composer
.preedit_string());
326 ExpectKeyFiltered(&character_composer
, GDK_KEY_3
, 0);
327 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer
.preedit_string());
328 ExpectKeyFiltered(&character_composer
, GDK_KEY_0
, 0);
329 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer
.preedit_string());
330 ExpectKeyFiltered(&character_composer
, GDK_KEY_x
, 0);
331 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer
.preedit_string());
332 ExpectKeyFiltered(&character_composer
, GDK_KEY_4
, 0);
333 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer
.preedit_string());
334 ExpectKeyFiltered(&character_composer
, GDK_KEY_2
, 0);
335 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer
.preedit_string());
336 ExpectKeyFiltered(&character_composer
, GDK_KEY_Escape
, 0);
337 EXPECT_EQ(ASCIIToUTF16(""), character_composer
.preedit_string());
340 TEST_F(CharacterComposerTest
, HexadecimalCompositionWithNonHexKey
) {
341 CharacterComposer character_composer
;
343 // Sequence [Ctrl+Shift+U, x, space] does not compose a character.
344 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
345 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
346 ExpectKeyFiltered(&character_composer
, GDK_KEY_x
, 0);
347 ExpectKeyFiltered(&character_composer
, GDK_KEY_space
, 0);
348 EXPECT_TRUE(character_composer
.composed_character().empty());
350 // HIRAGANA LETTER A (U+3042) with a sequence [3, 0, x, 4, 2].
351 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
352 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
353 ExpectCharacterComposed(&character_composer
, GDK_KEY_3
, GDK_KEY_0
, GDK_KEY_x
,
354 GDK_KEY_4
, GDK_KEY_2
, GDK_KEY_space
, 0,
355 base::string16(1, 0x3042));
358 TEST_F(CharacterComposerTest
, HexadecimalCompositionWithAdditionalModifiers
) {
359 CharacterComposer character_composer
;
362 // HIRAGANA LETTER A (U+3042)
363 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
364 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
| EF_ALT_DOWN
);
365 ExpectCharacterComposed(&character_composer
, GDK_KEY_3
, GDK_KEY_0
, GDK_KEY_4
,
366 GDK_KEY_2
, GDK_KEY_space
, 0,
367 base::string16(1, 0x3042));
369 // Ctrl+Shift+u (CapsLock enabled)
370 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_u
,
371 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
| EF_CAPS_LOCK_DOWN
);
374 TEST_F(CharacterComposerTest
, CancelHexadecimalComposition
) {
375 CharacterComposer character_composer
;
376 // Cancel composition with ESC.
377 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
378 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
379 ExpectKeyFiltered(&character_composer
, GDK_KEY_1
, 0);
380 ExpectKeyFiltered(&character_composer
, GDK_KEY_Escape
, 0);
382 // Now we can start composition again since the last composition was
384 // HIRAGANA LETTER A (U+3042)
385 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
386 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
387 ExpectCharacterComposed(&character_composer
, GDK_KEY_3
, GDK_KEY_0
, GDK_KEY_4
,
388 GDK_KEY_2
, GDK_KEY_space
, 0,
389 base::string16(1, 0x3042));
392 TEST_F(CharacterComposerTest
, HexadecimalCompositionWithBackspace
) {
393 CharacterComposer character_composer
;
394 // HIRAGANA LETTER A (U+3042)
395 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
396 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
397 ExpectKeyFiltered(&character_composer
, GDK_KEY_3
, 0);
398 ExpectKeyFiltered(&character_composer
, GDK_KEY_0
, 0);
399 ExpectKeyFiltered(&character_composer
, GDK_KEY_f
, 0);
400 ExpectKeyFiltered(&character_composer
, GDK_KEY_BackSpace
, 0);
401 ExpectCharacterComposed(&character_composer
, GDK_KEY_4
, GDK_KEY_2
,
402 GDK_KEY_space
, 0, base::string16(1, 0x3042));
405 TEST_F(CharacterComposerTest
, CancelHexadecimalCompositionWithBackspace
) {
406 CharacterComposer character_composer
;
408 // Backspace just after Ctrl+Shift+U.
409 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
410 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
411 ExpectKeyFiltered(&character_composer
, GDK_KEY_BackSpace
, 0);
412 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_3
, 0);
414 // Backspace twice after Ctrl+Shift+U and 3.
415 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
416 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
417 ExpectKeyFiltered(&character_composer
, GDK_KEY_3
, 0);
418 ExpectKeyFiltered(&character_composer
, GDK_KEY_BackSpace
, 0);
419 ExpectKeyFiltered(&character_composer
, GDK_KEY_BackSpace
, 0);
420 ExpectKeyNotFiltered(&character_composer
, GDK_KEY_3
, 0);
423 TEST_F(CharacterComposerTest
, HexadecimalCompositionPreeditWithModifierPressed
)
425 // This test case supposes X Window System uses 101 keyboard layout.
426 CharacterComposer character_composer
;
427 const int control_shift
= EF_CONTROL_DOWN
| EF_SHIFT_DOWN
;
428 // HIRAGANA LETTER A (U+3042)
429 ExpectKeyFilteredWithKeycode(&character_composer
,
430 GDK_KEY_U
, ui::VKEY_U
, control_shift
);
431 EXPECT_EQ(ASCIIToUTF16("u"), character_composer
.preedit_string());
432 ExpectKeyFilteredWithKeycode(&character_composer
,
433 GDK_KEY_numbersign
, ui::VKEY_3
, control_shift
);
434 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer
.preedit_string());
435 ExpectKeyFilteredWithKeycode(&character_composer
,
436 GDK_KEY_parenright
, ui::VKEY_0
, control_shift
);
437 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer
.preedit_string());
438 ExpectKeyFilteredWithKeycode(&character_composer
,
439 GDK_KEY_dollar
, ui::VKEY_4
, control_shift
);
440 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer
.preedit_string());
441 ExpectKeyFilteredWithKeycode(&character_composer
,
442 GDK_KEY_A
, ui::VKEY_A
, control_shift
);
443 EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer
.preedit_string());
444 ExpectKeyFilteredWithKeycode(&character_composer
,
445 GDK_KEY_BackSpace
, ui::VKEY_BACK
, control_shift
);
446 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer
.preedit_string());
447 ExpectKeyFilteredWithKeycode(&character_composer
,
448 GDK_KEY_at
, ui::VKEY_2
, control_shift
);
449 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer
.preedit_string());
450 ExpectCharacterComposedWithKeyCode(&character_composer
,
451 GDK_KEY_Return
, ui::VKEY_RETURN
,
453 base::string16(1, 0x3042));
454 EXPECT_EQ(ASCIIToUTF16(""), character_composer
.preedit_string());
456 // Sequence with an ignored character (control + shift + 'x') and Escape.
457 ExpectKeyFilteredWithKeycode(&character_composer
,
458 GDK_KEY_U
, ui::VKEY_U
, control_shift
);
459 EXPECT_EQ(ASCIIToUTF16("u"), character_composer
.preedit_string());
460 ExpectKeyFilteredWithKeycode(&character_composer
,
461 GDK_KEY_numbersign
, ui::VKEY_3
, control_shift
);
462 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer
.preedit_string());
463 ExpectKeyFilteredWithKeycode(&character_composer
,
464 GDK_KEY_parenright
, ui::VKEY_0
, control_shift
);
465 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer
.preedit_string());
466 ExpectKeyFilteredWithKeycode(&character_composer
,
467 GDK_KEY_X
, ui::VKEY_X
, control_shift
);
468 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer
.preedit_string());
469 ExpectKeyFilteredWithKeycode(&character_composer
,
470 GDK_KEY_dollar
, ui::VKEY_4
, control_shift
);
471 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer
.preedit_string());
472 ExpectKeyFilteredWithKeycode(&character_composer
,
473 GDK_KEY_at
, ui::VKEY_2
, control_shift
);
474 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer
.preedit_string());
475 ExpectKeyFilteredWithKeycode(&character_composer
,
476 GDK_KEY_Escape
, ui::VKEY_ESCAPE
, control_shift
);
477 EXPECT_EQ(ASCIIToUTF16(""), character_composer
.preedit_string());
480 TEST_F(CharacterComposerTest
, InvalidHexadecimalSequence
) {
481 CharacterComposer character_composer
;
483 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
484 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
485 for (int i
= 0; i
< 8; ++i
)
486 ExpectKeyFiltered(&character_composer
, GDK_KEY_f
, 0);
487 ExpectKeyFiltered(&character_composer
, GDK_KEY_space
, 0);
489 // U+0000 (Actually, this is a valid unicode character, but we don't
490 // compose a string with a character '\0')
491 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
492 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
493 for (int i
= 0; i
< 4; ++i
)
494 ExpectKeyFiltered(&character_composer
, GDK_KEY_0
, 0);
495 ExpectKeyFiltered(&character_composer
, GDK_KEY_space
, 0);
498 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
499 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
500 ExpectKeyFiltered(&character_composer
, GDK_KEY_1
, 0);
501 ExpectKeyFiltered(&character_composer
, GDK_KEY_0
, 0);
502 for (int i
= 0; i
< 4; ++i
)
503 ExpectKeyFiltered(&character_composer
, GDK_KEY_f
, 0);
504 ExpectKeyFiltered(&character_composer
, GDK_KEY_space
, 0);
507 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
508 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
509 ExpectKeyFiltered(&character_composer
, GDK_KEY_1
, 0);
510 ExpectKeyFiltered(&character_composer
, GDK_KEY_1
, 0);
511 for (int i
= 0; i
< 4; ++i
)
512 ExpectKeyFiltered(&character_composer
, GDK_KEY_0
, 0);
513 ExpectKeyFiltered(&character_composer
, GDK_KEY_space
, 0);
516 TEST_F(CharacterComposerTest
, HexadecimalSequenceAndDeadKey
) {
517 CharacterComposer character_composer
;
518 // LATIN SMALL LETTER A WITH ACUTE
519 ExpectCharacterComposed(&character_composer
, GDK_KEY_dead_acute
, GDK_KEY_a
, 0,
520 base::string16(1, 0x00E1));
521 // HIRAGANA LETTER A (U+3042) with dead_acute ignored.
522 ExpectKeyFiltered(&character_composer
, GDK_KEY_U
,
523 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
);
524 ExpectCharacterComposed(&character_composer
, GDK_KEY_3
, GDK_KEY_0
,
525 GDK_KEY_dead_acute
, GDK_KEY_4
, GDK_KEY_2
,
526 GDK_KEY_space
, 0, base::string16(1, 0x3042));
527 // LATIN CAPITAL LETTER U WITH ACUTE while 'U' is pressed with Ctrl+Shift.
528 ExpectKeyFiltered(&character_composer
, GDK_KEY_dead_acute
, 0);
529 EXPECT_TRUE(FilterKeyPress(&character_composer
, GDK_KEY_U
, 0,
530 EF_SHIFT_DOWN
| EF_CONTROL_DOWN
));
531 EXPECT_EQ(base::string16(1, 0x00DA), character_composer
.composed_character());
534 TEST_F(CharacterComposerTest
, BlacklistedKeyeventsTest
) {
535 CharacterComposer character_composer
;
536 EXPECT_TRUE(FilterKeyPress(&character_composer
, GDK_KEY_dead_acute
, 0, 0));
537 EXPECT_FALSE(FilterKeyPress(&character_composer
, GDK_KEY_s
, 0, 0));
538 ASSERT_EQ(1U, character_composer
.composed_character().size());
539 EXPECT_EQ(GDK_KEY_apostrophe
, character_composer
.composed_character().at(0));