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 "ui/base/ime/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"
17 // Expects key is not filtered and no character is composed.
18 void ExpectKeyNotFiltered(CharacterComposer* character_composer,
21 EXPECT_FALSE(character_composer->FilterKeyPress(key, 0, flags));
22 EXPECT_TRUE(character_composer->composed_character().empty());
25 // Expects key is filtered and no character is composed.
26 void ExpectKeyFiltered(CharacterComposer* character_composer,
29 EXPECT_TRUE(character_composer->FilterKeyPress(key, 0, flags));
30 EXPECT_TRUE(character_composer->composed_character().empty());
33 // Expects key is filtered and no character is composed.
34 void ExpectKeyFilteredWithKeycode(CharacterComposer* character_composer,
38 EXPECT_TRUE(character_composer->FilterKeyPress(key, keycode, flags));
39 EXPECT_TRUE(character_composer->composed_character().empty());
42 // Expects |expected_character| is composed after sequence [key1, key2].
43 void ExpectCharacterComposed(CharacterComposer* character_composer,
47 const string16& expected_character) {
48 ExpectKeyFiltered(character_composer, key1, flags);
49 EXPECT_TRUE(character_composer->FilterKeyPress(key2, 0, flags));
50 EXPECT_EQ(expected_character, character_composer->composed_character());
53 // Expects |expected_character| is composed after sequence [key1, key2, key3].
54 void ExpectCharacterComposed(CharacterComposer* character_composer,
59 const string16& expected_character) {
60 ExpectKeyFiltered(character_composer, key1, flags);
61 ExpectCharacterComposed(character_composer, key2, key3, flags,
65 // Expects |expected_character| is composed after sequence [key1, key2, key3,
67 void ExpectCharacterComposed(CharacterComposer* character_composer,
73 const string16& expected_character) {
74 ExpectKeyFiltered(character_composer, key1, flags);
75 ExpectCharacterComposed(character_composer, key2, key3, key4, flags,
79 // Expects |expected_character| is composed after sequence [key1, key2, key3,
81 void ExpectCharacterComposed(CharacterComposer* character_composer,
88 const string16& expected_character) {
89 ExpectKeyFiltered(character_composer, key1, flags);
90 ExpectCharacterComposed(character_composer, key2, key3, key4, key5, flags,
94 // Expects |expected_character| is composed after sequence [key1, key2, key3,
95 // key 4, key5, key6].
96 void ExpectCharacterComposed(CharacterComposer* character_composer,
104 const string16& expected_character) {
105 ExpectKeyFiltered(character_composer, key1, flags);
106 ExpectCharacterComposed(character_composer, key2, key3, key4, key5, key6,
107 flags, expected_character);
110 // Expects |expected_character| is composed after sequence [{key1, keycode1}].
111 void ExpectCharacterComposedWithKeyCode(CharacterComposer* character_composer,
112 uint key1, uint keycode1,
114 const string16& expected_character) {
115 EXPECT_TRUE(character_composer->FilterKeyPress(key1, keycode1, flags));
116 EXPECT_EQ(expected_character, character_composer->composed_character());
121 TEST(CharacterComposerTest, InitialState) {
122 CharacterComposer character_composer;
123 EXPECT_TRUE(character_composer.composed_character().empty());
126 TEST(CharacterComposerTest, NormalKeyIsNotFiltered) {
127 CharacterComposer character_composer;
128 ExpectKeyNotFiltered(&character_composer, GDK_KEY_B, 0);
129 ExpectKeyNotFiltered(&character_composer, GDK_KEY_Z, 0);
130 ExpectKeyNotFiltered(&character_composer, GDK_KEY_c, 0);
131 ExpectKeyNotFiltered(&character_composer, GDK_KEY_m, 0);
132 ExpectKeyNotFiltered(&character_composer, GDK_KEY_0, 0);
133 ExpectKeyNotFiltered(&character_composer, GDK_KEY_1, 0);
134 ExpectKeyNotFiltered(&character_composer, GDK_KEY_8, 0);
137 TEST(CharacterComposerTest, PartiallyMatchingSequence) {
138 CharacterComposer character_composer;
140 // Composition with sequence ['dead acute', '1'] will fail.
141 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
142 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_1, 0, 0));
143 EXPECT_TRUE(character_composer.composed_character().empty());
145 // Composition with sequence ['dead acute', 'dead circumflex', '1'] will fail.
146 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
147 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_circumflex, 0);
148 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_1, 0, 0));
149 EXPECT_TRUE(character_composer.composed_character().empty());
152 TEST(CharacterComposerTest, FullyMatchingSequences) {
153 CharacterComposer character_composer;
154 // LATIN SMALL LETTER A WITH ACUTE
155 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0,
156 string16(1, 0x00E1));
157 // LATIN CAPITAL LETTER A WITH ACUTE
158 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_A, 0,
159 string16(1, 0x00C1));
161 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_grave,
162 GDK_KEY_dead_grave, 0, string16(1, 0x0060));
163 // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
164 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute,
165 GDK_KEY_dead_circumflex, GDK_KEY_a, 0,
166 string16(1, 0x1EA5));
167 // LATIN CAPITAL LETTER U WITH HORN AND GRAVE
168 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_grave,
169 GDK_KEY_dead_horn, GDK_KEY_U, 0, string16(1, 0x1EEA));
170 // LATIN CAPITAL LETTER C WITH CEDILLA
171 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_C, 0,
172 string16(1, 0x00C7));
173 // LATIN SMALL LETTER C WITH CEDILLA
174 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_c, 0,
175 string16(1, 0x00E7));
178 TEST(CharacterComposerTest, FullyMatchingSequencesAfterMatchingFailure) {
179 CharacterComposer character_composer;
180 // Composition with sequence ['dead acute', 'dead circumflex', '1'] will fail.
181 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
182 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_circumflex, 0);
183 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_1, 0, 0));
184 EXPECT_TRUE(character_composer.composed_character().empty());
185 // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
186 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute,
187 GDK_KEY_dead_circumflex, GDK_KEY_a, 0,
188 string16(1, 0x1EA5));
191 TEST(CharacterComposerTest, ComposedCharacterIsClearedAfterReset) {
192 CharacterComposer character_composer;
193 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0,
194 string16(1, 0x00E1));
195 character_composer.Reset();
196 EXPECT_TRUE(character_composer.composed_character().empty());
199 TEST(CharacterComposerTest, CompositionStateIsClearedAfterReset) {
200 CharacterComposer character_composer;
201 // Even though sequence ['dead acute', 'a'] will compose 'a with acute',
202 // no character is composed here because of reset.
203 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
204 character_composer.Reset();
205 EXPECT_FALSE(character_composer.FilterKeyPress(GDK_KEY_a, 0, 0));
206 EXPECT_TRUE(character_composer.composed_character().empty());
209 TEST(CharacterComposerTest, KeySequenceCompositionPreedit) {
210 CharacterComposer character_composer;
211 // LATIN SMALL LETTER A WITH ACUTE
212 // preedit_string() is always empty in key sequence composition mode.
213 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
214 EXPECT_TRUE(character_composer.preedit_string().empty());
215 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_a, 0, 0));
216 EXPECT_EQ(string16(1, 0x00E1), character_composer.composed_character());
217 EXPECT_TRUE(character_composer.preedit_string().empty());
220 // ComposeCheckerWithCompactTable in character_composer.cc is depending on the
221 // assumption that the data in gtkimcontextsimpleseqs.h is correctly ordered.
222 TEST(CharacterComposerTest, MainTableIsCorrectlyOrdered) {
223 // This file is included here intentionally, instead of the top of the file,
224 // because including this file at the top of the file will define a
225 // global constant and contaminate the global namespace.
226 #include "third_party/gtk+/gtk/gtkimcontextsimpleseqs.h"
227 const int index_size = 26;
228 const int index_stride = 6;
230 // Verify that the index is correctly ordered
231 for (int i = 1; i < index_size; ++i) {
232 const int index_key_prev = gtk_compose_seqs_compact[(i - 1)*index_stride];
233 const int index_key = gtk_compose_seqs_compact[i*index_stride];
234 EXPECT_TRUE(index_key > index_key_prev);
237 // Verify that the sequenes are correctly ordered
239 int operator()(const uint16* l, const uint16* r, int length) const{
240 for (int i = 0; i < length; ++i) {
250 for (int i = 0; i < index_size; ++i) {
251 for (int length = 1; length < index_stride - 1; ++length) {
252 const int index_begin = gtk_compose_seqs_compact[i*index_stride + length];
253 const int index_end =
254 gtk_compose_seqs_compact[i*index_stride + length + 1];
255 const int stride = length + 1;
256 for (int index = index_begin + stride; index < index_end;
258 const uint16* sequence = >k_compose_seqs_compact[index];
259 const uint16* sequence_prev = sequence - stride;
260 EXPECT_EQ(1, compare_sequence(sequence, sequence_prev, length));
266 TEST(CharacterComposerTest, HexadecimalComposition) {
267 CharacterComposer character_composer;
268 // HIRAGANA LETTER A (U+3042)
269 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
270 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
271 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4,
272 GDK_KEY_2, GDK_KEY_space, 0, string16(1, 0x3042));
273 // MUSICAL KEYBOARD (U+1F3B9)
274 const char16 kMusicalKeyboard[] = {0xd83c, 0xdfb9};
275 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
276 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
277 ExpectCharacterComposed(&character_composer, GDK_KEY_1, GDK_KEY_f, GDK_KEY_3,
278 GDK_KEY_b, GDK_KEY_9, GDK_KEY_Return, 0,
279 string16(kMusicalKeyboard,
281 arraysize(kMusicalKeyboard)));
284 TEST(CharacterComposerTest, HexadecimalCompositionPreedit) {
285 CharacterComposer character_composer;
286 // HIRAGANA LETTER A (U+3042)
287 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
288 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
289 EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string());
290 ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0);
291 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string());
292 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
293 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
294 ExpectKeyFiltered(&character_composer, GDK_KEY_4, 0);
295 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
296 ExpectKeyFiltered(&character_composer, GDK_KEY_a, 0);
297 EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer.preedit_string());
298 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
299 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
300 ExpectCharacterComposed(&character_composer, GDK_KEY_2, GDK_KEY_Return, 0,
301 string16(1, 0x3042));
302 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string());
304 // Sequence with an ignored character ('x') and Escape.
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_x, 0);
313 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
314 ExpectKeyFiltered(&character_composer, GDK_KEY_4, 0);
315 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
316 ExpectKeyFiltered(&character_composer, GDK_KEY_2, 0);
317 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string());
318 ExpectKeyFiltered(&character_composer, GDK_KEY_Escape, 0);
319 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string());
322 TEST(CharacterComposerTest, HexadecimalCompositionWithNonHexKey) {
323 CharacterComposer character_composer;
325 // Sequence [Ctrl+Shift+U, x, space] does not compose a character.
326 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
327 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
328 ExpectKeyFiltered(&character_composer, GDK_KEY_x, 0);
329 ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0);
330 EXPECT_TRUE(character_composer.composed_character().empty());
332 // HIRAGANA LETTER A (U+3042) with a sequence [3, 0, x, 4, 2].
333 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
334 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
335 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_x,
336 GDK_KEY_4, GDK_KEY_2, GDK_KEY_space, 0,
337 string16(1, 0x3042));
340 TEST(CharacterComposerTest, HexadecimalCompositionWithAdditionalModifiers) {
341 CharacterComposer character_composer;
344 // HIRAGANA LETTER A (U+3042)
345 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
346 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_ALT_DOWN);
347 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4,
348 GDK_KEY_2, GDK_KEY_space, 0, string16(1, 0x3042));
350 // Ctrl+Shift+u (CapsLock enabled)
351 ExpectKeyNotFiltered(&character_composer, GDK_KEY_u,
352 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_CAPS_LOCK_DOWN);
355 TEST(CharacterComposerTest, CancelHexadecimalComposition) {
356 CharacterComposer character_composer;
357 // Cancel composition with ESC.
358 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
359 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
360 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
361 ExpectKeyFiltered(&character_composer, GDK_KEY_Escape, 0);
363 // Now we can start composition again since the last composition was
365 // HIRAGANA LETTER A (U+3042)
366 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
367 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
368 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4,
369 GDK_KEY_2, GDK_KEY_space, 0, string16(1, 0x3042));
372 TEST(CharacterComposerTest, HexadecimalCompositionWithBackspace) {
373 CharacterComposer character_composer;
374 // HIRAGANA LETTER A (U+3042)
375 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
376 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
377 ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0);
378 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
379 ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0);
380 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
381 ExpectCharacterComposed(&character_composer, GDK_KEY_4, GDK_KEY_2,
382 GDK_KEY_space, 0, string16(1, 0x3042));
385 TEST(CharacterComposerTest, CancelHexadecimalCompositionWithBackspace) {
386 CharacterComposer character_composer;
388 // Backspace just after Ctrl+Shift+U.
389 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
390 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
391 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
392 ExpectKeyNotFiltered(&character_composer, GDK_KEY_3, 0);
394 // Backspace twice after Ctrl+Shift+U and 3.
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_BackSpace, 0);
399 ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
400 ExpectKeyNotFiltered(&character_composer, GDK_KEY_3, 0);
403 TEST(CharacterComposerTest, HexadecimalCompositionPreeditWithModifierPressed) {
404 // This test case supposes X Window System uses 101 keyboard layout.
405 CharacterComposer character_composer;
406 const int control_shift = EF_CONTROL_DOWN | EF_SHIFT_DOWN;
407 // HIRAGANA LETTER A (U+3042)
408 ExpectKeyFilteredWithKeycode(&character_composer,
409 GDK_KEY_U, 30, control_shift);
410 EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string());
411 ExpectKeyFilteredWithKeycode(&character_composer,
412 GDK_KEY_numbersign, 12, control_shift);
413 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string());
414 ExpectKeyFilteredWithKeycode(&character_composer,
415 GDK_KEY_parenright, 19, control_shift);
416 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
417 ExpectKeyFilteredWithKeycode(&character_composer,
418 GDK_KEY_dollar, 13, control_shift);
419 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
420 ExpectKeyFilteredWithKeycode(&character_composer,
421 GDK_KEY_A, 38, control_shift);
422 EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer.preedit_string());
423 ExpectKeyFilteredWithKeycode(&character_composer,
424 GDK_KEY_BackSpace, 22, control_shift);
425 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
426 ExpectKeyFilteredWithKeycode(&character_composer,
427 GDK_KEY_at, 11, control_shift);
428 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string());
429 ExpectCharacterComposedWithKeyCode(&character_composer,
432 string16(1, 0x3042));
433 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string());
435 // Sequence with an ignored character (control + shift + 'x') and Escape.
436 ExpectKeyFilteredWithKeycode(&character_composer,
437 GDK_KEY_U, 30, control_shift);
438 EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string());
439 ExpectKeyFilteredWithKeycode(&character_composer,
440 GDK_KEY_numbersign, 12, control_shift);
441 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string());
442 ExpectKeyFilteredWithKeycode(&character_composer,
443 GDK_KEY_parenright, 19, control_shift);
444 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
445 ExpectKeyFilteredWithKeycode(&character_composer,
446 GDK_KEY_X, 53, control_shift);
447 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
448 ExpectKeyFilteredWithKeycode(&character_composer,
449 GDK_KEY_dollar, 13, control_shift);
450 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
451 ExpectKeyFilteredWithKeycode(&character_composer,
452 GDK_KEY_at, 11, control_shift);
453 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string());
454 ExpectKeyFilteredWithKeycode(&character_composer,
455 GDK_KEY_Escape, 9, control_shift);
456 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string());
459 TEST(CharacterComposerTest, InvalidHexadecimalSequence) {
460 CharacterComposer character_composer;
462 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
463 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
464 for (int i = 0; i < 8; ++i)
465 ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0);
466 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_space, 0, 0));
467 EXPECT_TRUE(character_composer.composed_character().empty());
469 // U+0000 (Actually, this is a valid unicode character, but we don't
470 // compose a string with a character '\0')
471 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
472 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
473 for (int i = 0; i < 4; ++i)
474 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
475 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_space, 0, 0));
476 EXPECT_TRUE(character_composer.composed_character().empty());
479 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
480 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
481 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
482 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
483 for (int i = 0; i < 4; ++i)
484 ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0);
485 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_space, 0, 0));
486 EXPECT_TRUE(character_composer.composed_character().empty());
489 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
490 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
491 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
492 ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
493 for (int i = 0; i < 4; ++i)
494 ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
495 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_space, 0, 0));
496 EXPECT_TRUE(character_composer.composed_character().empty());
499 TEST(CharacterComposerTest, HexadecimalSequenceAndDeadKey) {
500 CharacterComposer character_composer;
501 // LATIN SMALL LETTER A WITH ACUTE
502 ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0,
503 string16(1, 0x00E1));
504 // HIRAGANA LETTER A (U+3042) with dead_acute ignored.
505 ExpectKeyFiltered(&character_composer, GDK_KEY_U,
506 EF_SHIFT_DOWN | EF_CONTROL_DOWN);
507 ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0,
508 GDK_KEY_dead_acute, GDK_KEY_4, GDK_KEY_2,
509 GDK_KEY_space, 0, string16(1, 0x3042));
510 // LATIN CAPITAL LETTER U WITH ACUTE while 'U' is pressed with Ctrl+Shift.
511 ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
512 EXPECT_TRUE(character_composer.FilterKeyPress(
513 GDK_KEY_U, 0, EF_SHIFT_DOWN | EF_CONTROL_DOWN));
514 EXPECT_EQ(string16(1, 0x00DA), character_composer.composed_character());
517 TEST(CharacterComposerTest, BlacklistedKeyeventsTest) {
518 CharacterComposer character_composer;
519 EXPECT_TRUE(character_composer.FilterKeyPress(GDK_KEY_dead_acute, 0, 0));
520 EXPECT_FALSE(character_composer.FilterKeyPress(GDK_KEY_s, 0, 0));
521 ASSERT_EQ(1U, character_composer.composed_character().size());
522 EXPECT_EQ(GDK_KEY_apostrophe, character_composer.composed_character().at(0));