• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
FilterKeyPress(CharacterComposer * character_composer,uint key,uint keycode,int flags)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.
ExpectKeyNotFilteredWithKeyCode(CharacterComposer * character_composer,uint key,uint keycode,int flags)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.
ExpectKeyFilteredWithKeycode(CharacterComposer * character_composer,uint key,uint keycode,int flags)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.
ExpectKeyNotFiltered(CharacterComposer * character_composer,uint key,int flags)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.
ExpectKeyFiltered(CharacterComposer * character_composer,uint key,int flags)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].
ExpectCharacterComposed(CharacterComposer * character_composer,uint key1,uint key2,int flags,const string16 & expected_character)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].
ExpectCharacterComposed(CharacterComposer * character_composer,uint key1,uint key2,uint key3,int flags,const string16 & expected_character)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].
ExpectCharacterComposed(CharacterComposer * character_composer,uint key1,uint key2,uint key3,uint key4,int flags,const string16 & expected_character)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].
ExpectCharacterComposed(CharacterComposer * character_composer,uint key1,uint key2,uint key3,uint key4,uint key5,int flags,const string16 & expected_character)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].
ExpectCharacterComposed(CharacterComposer * character_composer,uint key1,uint key2,uint key3,uint key4,uint key5,uint key6,int flags,const string16 & expected_character)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}].
ExpectCharacterComposedWithKeyCode(CharacterComposer * character_composer,uint key1,uint keycode1,int flags,const string16 & expected_character)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 
TEST_F(CharacterComposerTest,InitialState)137 TEST_F(CharacterComposerTest, InitialState) {
138   CharacterComposer character_composer;
139   EXPECT_TRUE(character_composer.composed_character().empty());
140 }
141 
TEST_F(CharacterComposerTest,NormalKeyIsNotFiltered)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 
TEST_F(CharacterComposerTest,PartiallyMatchingSequence)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 
TEST_F(CharacterComposerTest,FullyMatchingSequences)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 
TEST_F(CharacterComposerTest,FullyMatchingSequencesAfterMatchingFailure)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 
TEST_F(CharacterComposerTest,ComposedCharacterIsClearedAfterReset)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 
TEST_F(CharacterComposerTest,CompositionStateIsClearedAfterReset)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 
TEST_F(CharacterComposerTest,KeySequenceCompositionPreedit)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.
TEST_F(CharacterComposerTest,MainTableIsCorrectlyOrdered)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 
TEST_F(CharacterComposerTest,HexadecimalComposition)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 
TEST_F(CharacterComposerTest,HexadecimalCompositionPreedit)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 
TEST_F(CharacterComposerTest,HexadecimalCompositionWithNonHexKey)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 
TEST_F(CharacterComposerTest,HexadecimalCompositionWithAdditionalModifiers)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 
TEST_F(CharacterComposerTest,CancelHexadecimalComposition)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 
TEST_F(CharacterComposerTest,HexadecimalCompositionWithBackspace)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 
TEST_F(CharacterComposerTest,CancelHexadecimalCompositionWithBackspace)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 
TEST_F(CharacterComposerTest,HexadecimalCompositionPreeditWithModifierPressed)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 
TEST_F(CharacterComposerTest,InvalidHexadecimalSequence)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 
TEST_F(CharacterComposerTest,HexadecimalSequenceAndDeadKey)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 
TEST_F(CharacterComposerTest,BlacklistedKeyeventsTest)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