Home | History | Annotate | Download | only in chromeos
      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 = &gtk_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