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. 4 5 #include "ui/base/ime/chromeos/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 #include "ui/events/keycodes/keyboard_codes.h" 13 14 using base::ASCIIToUTF16; 15 16 namespace ui { 17 18 class CharacterComposerTest : public testing::Test { 19 protected: 20 bool FilterKeyPress(CharacterComposer* character_composer, 21 uint key, 22 uint keycode, 23 int flags) { 24 return character_composer->FilterKeyPressInternal(key, keycode, flags); 25 } 26 27 // Expects key is not filtered and no character is composed. 28 void ExpectKeyNotFilteredWithKeyCode(CharacterComposer* character_composer, 29 uint key, 30 uint keycode, 31 int flags) { 32 EXPECT_FALSE(character_composer->FilterKeyPressInternal(key, keycode, 33 flags)); 34 EXPECT_TRUE(character_composer->composed_character().empty()); 35 } 36 37 // Expects key is filtered and no character is composed. 38 void ExpectKeyFilteredWithKeycode(CharacterComposer* character_composer, 39 uint key, 40 uint keycode, 41 int flags) { 42 EXPECT_TRUE(character_composer->FilterKeyPressInternal(key, keycode, 43 flags)); 44 EXPECT_TRUE(character_composer->composed_character().empty()); 45 } 46 47 // Expects key is not filtered and no character is composed. 48 void ExpectKeyNotFiltered(CharacterComposer* character_composer, 49 uint key, 50 int flags) { 51 ExpectKeyNotFilteredWithKeyCode(character_composer, key, 0, flags); 52 } 53 54 // Expects key is filtered and no character is composed. 55 void ExpectKeyFiltered(CharacterComposer* character_composer, 56 uint key, 57 int flags) { 58 ExpectKeyFilteredWithKeycode(character_composer, key, 0, flags); 59 } 60 61 // Expects |expected_character| is composed after sequence [key1, key2]. 62 void ExpectCharacterComposed(CharacterComposer* character_composer, 63 uint key1, 64 uint key2, 65 int flags, 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()); 70 } 71 72 // Expects |expected_character| is composed after sequence [key1, key2, key3]. 73 void ExpectCharacterComposed(CharacterComposer* character_composer, 74 uint key1, 75 uint key2, 76 uint key3, 77 int flags, 78 const base::string16& expected_character) { 79 ExpectKeyFiltered(character_composer, key1, flags); 80 ExpectCharacterComposed(character_composer, key2, key3, flags, 81 expected_character); 82 } 83 84 // Expects |expected_character| is composed after sequence [key1, key2, key3, 85 // key 4]. 86 void ExpectCharacterComposed(CharacterComposer* character_composer, 87 uint key1, 88 uint key2, 89 uint key3, 90 uint key4, 91 int flags, 92 const base::string16& expected_character) { 93 ExpectKeyFiltered(character_composer, key1, flags); 94 ExpectCharacterComposed(character_composer, key2, key3, key4, flags, 95 expected_character); 96 } 97 98 // Expects |expected_character| is composed after sequence [key1, key2, key3, 99 // key 4, key5]. 100 void ExpectCharacterComposed(CharacterComposer* character_composer, 101 uint key1, 102 uint key2, 103 uint key3, 104 uint key4, 105 uint key5, 106 int flags, 107 const base::string16& expected_character) { 108 ExpectKeyFiltered(character_composer, key1, flags); 109 ExpectCharacterComposed(character_composer, key2, key3, key4, key5, flags, 110 expected_character); 111 } 112 113 // Expects |expected_character| is composed after sequence [key1, key2, key3, 114 // key 4, key5, key6]. 115 void ExpectCharacterComposed(CharacterComposer* character_composer, 116 uint key1, 117 uint key2, 118 uint key3, 119 uint key4, 120 uint key5, 121 uint key6, 122 int flags, 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); 127 } 128 129 // Expects |expected_character| is composed after sequence [{key1, keycode1}]. 130 void ExpectCharacterComposedWithKeyCode( 131 CharacterComposer* character_composer, 132 uint key1, uint keycode1, 133 int flags, 134 const base::string16& expected_character) { 135 EXPECT_TRUE(character_composer->FilterKeyPressInternal(key1, keycode1, 136 flags)); 137 EXPECT_EQ(expected_character, character_composer->composed_character()); 138 } 139 }; 140 141 TEST_F(CharacterComposerTest, InitialState) { 142 CharacterComposer character_composer; 143 EXPECT_TRUE(character_composer.composed_character().empty()); 144 } 145 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); 155 } 156 157 TEST_F(CharacterComposerTest, PartiallyMatchingSequence) { 158 CharacterComposer character_composer; 159 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); 163 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); 168 } 169 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)); 178 // GRAVE ACCENT 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)); 195 } 196 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)); 207 } 208 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()); 215 } 216 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); 224 } 225 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()); 235 } 236 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; 246 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); 252 } 253 254 // Verify that the sequenes are correctly ordered 255 struct { 256 int operator()(const uint16* l, const uint16* r, int length) const{ 257 for (int i = 0; i < length; ++i) { 258 if (l[i] > r[i]) 259 return 1; 260 if (l[i] < r[i]) 261 return -1; 262 } 263 return 0; 264 } 265 } compare_sequence; 266 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; 274 index += stride) { 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)); 278 } 279 } 280 } 281 } 282 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, 298 kMusicalKeyboard + 299 arraysize(kMusicalKeyboard))); 300 } 301 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()); 321 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()); 338 } 339 340 TEST_F(CharacterComposerTest, HexadecimalCompositionWithNonHexKey) { 341 CharacterComposer character_composer; 342 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()); 349 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)); 356 } 357 358 TEST_F(CharacterComposerTest, HexadecimalCompositionWithAdditionalModifiers) { 359 CharacterComposer character_composer; 360 361 // Ctrl+Shift+Alt+U 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)); 368 369 // Ctrl+Shift+u (CapsLock enabled) 370 ExpectKeyNotFiltered(&character_composer, GDK_KEY_u, 371 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_CAPS_LOCK_DOWN); 372 } 373 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); 381 382 // Now we can start composition again since the last composition was 383 // cancelled. 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)); 390 } 391 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)); 403 } 404 405 TEST_F(CharacterComposerTest, CancelHexadecimalCompositionWithBackspace) { 406 CharacterComposer character_composer; 407 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); 413 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); 421 } 422 423 TEST_F(CharacterComposerTest, HexadecimalCompositionPreeditWithModifierPressed) 424 { 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, 452 control_shift, 453 base::string16(1, 0x3042)); 454 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string()); 455 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()); 478 } 479 480 TEST_F(CharacterComposerTest, InvalidHexadecimalSequence) { 481 CharacterComposer character_composer; 482 // U+FFFFFFFF 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); 488 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); 496 497 // U+10FFFF 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); 505 506 // U+110000 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); 514 } 515 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()); 532 } 533 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)); 540 } 541 542 } // namespace ui 543