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 
     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 = &gtk_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