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/events/event_constants.h" 11 #include "ui/base/glib/glib_integers.h" 12 13 namespace ui { 14 15 namespace { 16 17 // Expects key is not filtered and no character is composed. 18 void ExpectKeyNotFiltered(CharacterComposer* character_composer, 19 uint key, 20 int flags) { 21 EXPECT_FALSE(character_composer->FilterKeyPress(key, 0, flags)); 22 EXPECT_TRUE(character_composer->composed_character().empty()); 23 } 24 25 // Expects key is filtered and no character is composed. 26 void ExpectKeyFiltered(CharacterComposer* character_composer, 27 uint key, 28 int flags) { 29 EXPECT_TRUE(character_composer->FilterKeyPress(key, 0, flags)); 30 EXPECT_TRUE(character_composer->composed_character().empty()); 31 } 32 33 // Expects key is filtered and no character is composed. 34 void ExpectKeyFilteredWithKeycode(CharacterComposer* character_composer, 35 uint key, 36 uint keycode, 37 int flags) { 38 EXPECT_TRUE(character_composer->FilterKeyPress(key, keycode, flags)); 39 EXPECT_TRUE(character_composer->composed_character().empty()); 40 } 41 42 // Expects |expected_character| is composed after sequence [key1, key2]. 43 void ExpectCharacterComposed(CharacterComposer* character_composer, 44 uint key1, 45 uint key2, 46 int flags, 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()); 51 } 52 53 // Expects |expected_character| is composed after sequence [key1, key2, key3]. 54 void ExpectCharacterComposed(CharacterComposer* character_composer, 55 uint key1, 56 uint key2, 57 uint key3, 58 int flags, 59 const string16& expected_character) { 60 ExpectKeyFiltered(character_composer, key1, flags); 61 ExpectCharacterComposed(character_composer, key2, key3, flags, 62 expected_character); 63 } 64 65 // Expects |expected_character| is composed after sequence [key1, key2, key3, 66 // key 4]. 67 void ExpectCharacterComposed(CharacterComposer* character_composer, 68 uint key1, 69 uint key2, 70 uint key3, 71 uint key4, 72 int flags, 73 const string16& expected_character) { 74 ExpectKeyFiltered(character_composer, key1, flags); 75 ExpectCharacterComposed(character_composer, key2, key3, key4, flags, 76 expected_character); 77 } 78 79 // Expects |expected_character| is composed after sequence [key1, key2, key3, 80 // key 4, key5]. 81 void ExpectCharacterComposed(CharacterComposer* character_composer, 82 uint key1, 83 uint key2, 84 uint key3, 85 uint key4, 86 uint key5, 87 int flags, 88 const string16& expected_character) { 89 ExpectKeyFiltered(character_composer, key1, flags); 90 ExpectCharacterComposed(character_composer, key2, key3, key4, key5, flags, 91 expected_character); 92 } 93 94 // Expects |expected_character| is composed after sequence [key1, key2, key3, 95 // key 4, key5, key6]. 96 void ExpectCharacterComposed(CharacterComposer* character_composer, 97 uint key1, 98 uint key2, 99 uint key3, 100 uint key4, 101 uint key5, 102 uint key6, 103 int flags, 104 const string16& expected_character) { 105 ExpectKeyFiltered(character_composer, key1, flags); 106 ExpectCharacterComposed(character_composer, key2, key3, key4, key5, key6, 107 flags, expected_character); 108 } 109 110 // Expects |expected_character| is composed after sequence [{key1, keycode1}]. 111 void ExpectCharacterComposedWithKeyCode(CharacterComposer* character_composer, 112 uint key1, uint keycode1, 113 int flags, 114 const string16& expected_character) { 115 EXPECT_TRUE(character_composer->FilterKeyPress(key1, keycode1, flags)); 116 EXPECT_EQ(expected_character, character_composer->composed_character()); 117 } 118 119 } // namespace 120 121 TEST(CharacterComposerTest, InitialState) { 122 CharacterComposer character_composer; 123 EXPECT_TRUE(character_composer.composed_character().empty()); 124 } 125 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); 135 } 136 137 TEST(CharacterComposerTest, PartiallyMatchingSequence) { 138 CharacterComposer character_composer; 139 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()); 144 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()); 150 } 151 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)); 160 // GRAVE ACCENT 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)); 176 } 177 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)); 189 } 190 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()); 197 } 198 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()); 207 } 208 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()); 218 } 219 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; 229 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); 235 } 236 237 // Verify that the sequenes are correctly ordered 238 struct { 239 int operator()(const uint16* l, const uint16* r, int length) const{ 240 for (int i = 0; i < length; ++i) { 241 if (l[i] > r[i]) 242 return 1; 243 if (l[i] < r[i]) 244 return -1; 245 } 246 return 0; 247 } 248 } compare_sequence; 249 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; 257 index += stride) { 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)); 261 } 262 } 263 } 264 } 265 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, 280 kMusicalKeyboard + 281 arraysize(kMusicalKeyboard))); 282 } 283 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()); 303 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()); 320 } 321 322 TEST(CharacterComposerTest, HexadecimalCompositionWithNonHexKey) { 323 CharacterComposer character_composer; 324 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()); 331 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)); 338 } 339 340 TEST(CharacterComposerTest, HexadecimalCompositionWithAdditionalModifiers) { 341 CharacterComposer character_composer; 342 343 // Ctrl+Shift+Alt+U 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)); 349 350 // Ctrl+Shift+u (CapsLock enabled) 351 ExpectKeyNotFiltered(&character_composer, GDK_KEY_u, 352 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_CAPS_LOCK_DOWN); 353 } 354 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); 362 363 // Now we can start composition again since the last composition was 364 // cancelled. 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)); 370 } 371 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)); 383 } 384 385 TEST(CharacterComposerTest, CancelHexadecimalCompositionWithBackspace) { 386 CharacterComposer character_composer; 387 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); 393 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); 401 } 402 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, 430 GDK_KEY_Return, 36, 431 control_shift, 432 string16(1, 0x3042)); 433 EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string()); 434 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()); 457 } 458 459 TEST(CharacterComposerTest, InvalidHexadecimalSequence) { 460 CharacterComposer character_composer; 461 // U+FFFFFFFF 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()); 468 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()); 477 478 // U+10FFFF 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()); 487 488 // U+110000 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()); 497 } 498 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()); 515 } 516 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)); 523 } 524 525 } // namespace ui 526