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 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 535