Add ICU message format support
[chromium-blink-merge.git] / ui / base / ime / chromeos / character_composer_unittest.cc
blobd9fc844a3147a6913733809b94959039affd6b8b
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.
5 #include "ui/base/ime/chromeos/character_composer.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "ui/events/event.h"
11 #include "ui/events/event_constants.h"
12 #include "ui/events/event_utils.h"
13 #include "ui/events/keycodes/dom/dom_code.h"
14 #include "ui/events/keycodes/dom/dom_key.h"
15 #include "ui/events/keycodes/keyboard_code_conversion.h"
16 #include "ui/events/keycodes/keyboard_codes.h"
18 using base::ASCIIToUTF16;
20 namespace ui {
22 namespace {
24 const base::char16 kCombiningGrave = 0x0300;
25 const base::char16 kCombiningAcute = 0x0301;
26 const base::char16 kCombiningCircumflex = 0x0302;
27 const base::char16 kCombiningHorn = 0x031B;
29 } // namespace
31 class CharacterComposerTest : public testing::Test {
32 protected:
33 // Returns a |KeyEvent| for a dead key press.
34 KeyEvent* DeadKeyPress(base::char16 combining_character) const {
35 KeyEvent* event =
36 new KeyEvent(ET_KEY_PRESSED, VKEY_UNKNOWN, DomCode::NONE, EF_NONE,
37 DomKey::DEAD, combining_character, EventTimeForNow());
38 return event;
41 // Expects key is filtered and no character is composed.
42 void ExpectDeadKeyFiltered(base::char16 combining_character) {
43 scoped_ptr<KeyEvent> event(DeadKeyPress(combining_character));
44 EXPECT_TRUE(character_composer_.FilterKeyPress(*event));
45 EXPECT_TRUE(character_composer_.composed_character().empty());
48 // Expects key is filtered and the given character is composed.
49 void ExpectDeadKeyComposed(base::char16 combining_character,
50 const base::string16& expected_character) {
51 scoped_ptr<KeyEvent> event(DeadKeyPress(combining_character));
52 EXPECT_TRUE(character_composer_.FilterKeyPress(*event));
53 EXPECT_EQ(expected_character, character_composer_.composed_character());
56 // Returns a |KeyEvent| for a character key press.
57 KeyEvent* UnicodeKeyPress(KeyboardCode vkey,
58 DomCode code,
59 int flags,
60 base::char16 character) const {
61 KeyEvent* event = new KeyEvent(ET_KEY_PRESSED, vkey, code, flags,
62 CharacterToDomKey(character), character,
63 EventTimeForNow());
64 return event;
67 // Expects key is not filtered and no character is composed.
68 void ExpectUnicodeKeyNotFiltered(KeyboardCode vkey,
69 DomCode code,
70 int flags,
71 base::char16 character) {
72 scoped_ptr<KeyEvent> event(UnicodeKeyPress(vkey, code, flags, character));
73 EXPECT_FALSE(character_composer_.FilterKeyPress(*event));
74 EXPECT_TRUE(character_composer_.composed_character().empty());
77 // Expects key is filtered and no character is composed.
78 void ExpectUnicodeKeyFiltered(KeyboardCode vkey,
79 DomCode code,
80 int flags,
81 base::char16 character) {
82 scoped_ptr<KeyEvent> event(UnicodeKeyPress(vkey, code, flags, character));
83 EXPECT_TRUE(character_composer_.FilterKeyPress(*event));
84 EXPECT_TRUE(character_composer_.composed_character().empty());
87 // Expects key is filtered and the given character is composed.
88 void ExpectUnicodeKeyComposed(KeyboardCode vkey,
89 DomCode code,
90 int flags,
91 base::char16 character,
92 const base::string16& expected_character) {
93 scoped_ptr<KeyEvent> event(UnicodeKeyPress(vkey, code, flags, character));
94 EXPECT_TRUE(character_composer_.FilterKeyPress(*event));
95 EXPECT_EQ(expected_character, character_composer_.composed_character());
98 CharacterComposer character_composer_;
101 TEST_F(CharacterComposerTest, InitialState) {
102 EXPECT_TRUE(character_composer_.composed_character().empty());
105 TEST_F(CharacterComposerTest, NormalKeyIsNotFiltered) {
106 ExpectUnicodeKeyNotFiltered(VKEY_B, DomCode::KEY_B, EF_NONE, 'B');
107 ExpectUnicodeKeyNotFiltered(VKEY_Z, DomCode::KEY_Z, EF_NONE, 'Z');
108 ExpectUnicodeKeyNotFiltered(VKEY_C, DomCode::KEY_C, EF_NONE, 'c');
109 ExpectUnicodeKeyNotFiltered(VKEY_M, DomCode::KEY_M, EF_NONE, 'm');
110 ExpectUnicodeKeyNotFiltered(VKEY_0, DomCode::DIGIT0, EF_NONE, '0');
111 ExpectUnicodeKeyNotFiltered(VKEY_1, DomCode::DIGIT1, EF_NONE, '1');
112 ExpectUnicodeKeyNotFiltered(VKEY_8, DomCode::DIGIT8, EF_NONE, '8');
115 TEST_F(CharacterComposerTest, PartiallyMatchingSequence) {
116 // Composition with sequence ['dead acute', '1'] will fail.
117 ExpectDeadKeyFiltered(kCombiningAcute);
118 ExpectUnicodeKeyFiltered(VKEY_1, DomCode::DIGIT1, 0, '1');
120 // Composition with sequence ['dead acute', 'dead circumflex', '1'] will fail.
121 ExpectDeadKeyFiltered(kCombiningAcute);
122 ExpectDeadKeyFiltered(kCombiningCircumflex);
123 ExpectUnicodeKeyFiltered(VKEY_1, DomCode::DIGIT1, 0, '1');
126 TEST_F(CharacterComposerTest, FullyMatchingSequences) {
127 // LATIN SMALL LETTER A WITH ACUTE
128 ExpectDeadKeyFiltered(kCombiningAcute);
129 ExpectUnicodeKeyComposed(VKEY_A, DomCode::KEY_A, EF_NONE, 'a',
130 base::string16(1, 0x00E1));
131 // LATIN CAPITAL LETTER A WITH ACUTE
132 ExpectDeadKeyFiltered(kCombiningAcute);
133 ExpectUnicodeKeyComposed(VKEY_A, DomCode::KEY_A, EF_NONE, 'A',
134 base::string16(1, 0x00C1));
135 // GRAVE ACCENT
136 ExpectDeadKeyFiltered(kCombiningGrave);
137 ExpectDeadKeyComposed(kCombiningGrave, base::string16(1, 0x0060));
138 // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
139 ExpectDeadKeyFiltered(kCombiningAcute);
140 ExpectDeadKeyFiltered(kCombiningCircumflex);
141 ExpectUnicodeKeyComposed(VKEY_A, DomCode::KEY_A, EF_NONE, 'a',
142 base::string16(1, 0x1EA5));
143 // LATIN CAPITAL LETTER U WITH HORN AND GRAVE
144 ExpectDeadKeyFiltered(kCombiningGrave);
145 ExpectDeadKeyFiltered(kCombiningHorn);
146 ExpectUnicodeKeyComposed(VKEY_U, DomCode::KEY_U, EF_NONE, 'U',
147 base::string16(1, 0x1EEA));
148 // LATIN CAPITAL LETTER C WITH CEDILLA
149 ExpectDeadKeyFiltered(kCombiningAcute);
150 ExpectUnicodeKeyComposed(VKEY_C, DomCode::KEY_C, EF_NONE, 'C',
151 base::string16(1, 0x00C7));
152 // LATIN SMALL LETTER C WITH CEDILLA
153 ExpectDeadKeyFiltered(kCombiningAcute);
154 ExpectUnicodeKeyComposed(VKEY_C, DomCode::KEY_C, EF_NONE, 'c',
155 base::string16(1, 0x00E7));
158 TEST_F(CharacterComposerTest, FullyMatchingSequencesAfterMatchingFailure) {
159 // Composition with sequence ['dead acute', 'dead circumflex', '1'] will fail.
160 ExpectDeadKeyFiltered(kCombiningAcute);
161 ExpectDeadKeyFiltered(kCombiningCircumflex);
162 ExpectUnicodeKeyFiltered(VKEY_1, DomCode::DIGIT1, 0, '1');
163 // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
164 ExpectDeadKeyFiltered(kCombiningAcute);
165 ExpectDeadKeyFiltered(kCombiningCircumflex);
166 ExpectUnicodeKeyComposed(VKEY_A, DomCode::KEY_A, EF_NONE, 'a',
167 base::string16(1, 0x1EA5));
170 TEST_F(CharacterComposerTest, ComposedCharacterIsClearedAfterReset) {
171 ExpectDeadKeyFiltered(kCombiningAcute);
172 ExpectUnicodeKeyComposed(VKEY_A, DomCode::KEY_A, EF_NONE, 'a',
173 base::string16(1, 0x00E1));
174 character_composer_.Reset();
175 EXPECT_TRUE(character_composer_.composed_character().empty());
178 TEST_F(CharacterComposerTest, CompositionStateIsClearedAfterReset) {
179 // Even though sequence ['dead acute', 'a'] will compose 'a with acute',
180 // no character is composed here because of reset.
181 ExpectDeadKeyFiltered(kCombiningAcute);
182 character_composer_.Reset();
183 ExpectUnicodeKeyNotFiltered(VKEY_A, DomCode::KEY_A, EF_NONE, 'a');
186 TEST_F(CharacterComposerTest, KeySequenceCompositionPreedit) {
187 // LATIN SMALL LETTER A WITH ACUTE
188 // preedit_string() is always empty in key sequence composition mode.
189 ExpectDeadKeyFiltered(kCombiningAcute);
190 EXPECT_TRUE(character_composer_.preedit_string().empty());
191 ExpectUnicodeKeyComposed(VKEY_A, DomCode::KEY_A, EF_NONE, 'a',
192 base::string16(1, 0x00E1));
193 EXPECT_TRUE(character_composer_.preedit_string().empty());
196 // Verify the structure of the primary |TreeComposeChecker| table.
197 TEST_F(CharacterComposerTest, MainTableIsCorrectlyOrdered) {
198 // This file is included here intentionally, instead of the top of the file,
199 // because including this file at the top of the file will define a
200 // global constant and contaminate the global namespace.
201 #include "ui/base/ime/chromeos/character_composer_data.h"
202 const int kTypes = 2;
204 // Record the subtree locations and check subtable sizes.
205 std::vector<uint16_t> subtrees;
206 uint16_t index = 0;
207 while (index < kCompositions.tree_entries) {
208 // Record the start of the subtree.
209 SCOPED_TRACE(index);
210 subtrees.push_back(index);
211 for (int t = 0; t < kTypes; ++t) {
212 // Skip the internal table and verify the next index is within the data.
213 index += 1 + 2 * kCompositions.tree[index];
214 EXPECT_GT(kCompositions.tree_entries, index);
215 // Skip the leaf table and verify that the next index is not past the
216 // end of the data.
217 index += 1 + 2 * kCompositions.tree[index];
218 EXPECT_GE(kCompositions.tree_entries, index);
221 // We should end up at the end of the data.
222 EXPECT_EQ(kCompositions.tree_entries, index);
224 // Check subtable structure.
225 index = 0;
226 while (index < kCompositions.tree_entries) {
227 SCOPED_TRACE(index);
228 for (int t = 0; t < kTypes; ++t) {
229 // Check the internal subtable.
230 uint16_t previous_key = 0;
231 uint16_t size = kCompositions.tree[index++];
232 for (uint16_t i = 0; i < size; ++i) {
233 // Verify that the subtable is sorted.
234 uint16_t key = kCompositions.tree[index];
235 uint16_t value = kCompositions.tree[index + 1];
236 if (i)
237 EXPECT_LT(previous_key, key) << index;
238 previous_key = key;
239 // Verify that the internal link is valid.
240 const auto it = std::find(subtrees.begin(), subtrees.end(), value);
241 EXPECT_FALSE(subtrees.end() == it) << index;
242 index += 2;
244 // Check the leaf subtable.
245 previous_key = 0;
246 size = kCompositions.tree[index++];
247 for (uint16_t i = 0; i < size; ++i) {
248 // Verify that the subtable is sorted.
249 uint16_t key = kCompositions.tree[index];
250 if (i)
251 EXPECT_LT(previous_key, key) << index;
252 previous_key = key;
253 index += 2;
259 TEST_F(CharacterComposerTest, HexadecimalComposition) {
260 // HIRAGANA LETTER A (U+3042)
261 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
262 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 'U');
263 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, EF_NONE, '3');
264 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, EF_NONE, '0');
265 ExpectUnicodeKeyFiltered(VKEY_4, DomCode::DIGIT4, EF_NONE, '4');
266 ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, EF_NONE, '2');
267 ExpectUnicodeKeyComposed(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ',
268 base::string16(1, 0x3042));
269 // MUSICAL KEYBOARD (U+1F3B9)
270 const base::char16 kMusicalKeyboard[] = {0xd83c, 0xdfb9};
271 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
272 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 'U');
273 ExpectUnicodeKeyFiltered(VKEY_1, DomCode::DIGIT1, EF_NONE, '1');
274 ExpectUnicodeKeyFiltered(VKEY_F, DomCode::KEY_F, EF_NONE, 'f');
275 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, EF_NONE, '3');
276 ExpectUnicodeKeyFiltered(VKEY_B, DomCode::KEY_B, EF_NONE, 'b');
277 ExpectUnicodeKeyFiltered(VKEY_9, DomCode::DIGIT9, EF_NONE, '9');
278 ExpectUnicodeKeyComposed(
279 VKEY_RETURN, DomCode::ENTER, EF_NONE, '\r',
280 base::string16(kMusicalKeyboard,
281 kMusicalKeyboard + arraysize(kMusicalKeyboard)));
284 TEST_F(CharacterComposerTest, HexadecimalCompositionPreedit) {
285 // HIRAGANA LETTER A (U+3042)
286 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
287 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 'U');
288 EXPECT_EQ(ASCIIToUTF16("u"), character_composer_.preedit_string());
289 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, 0, '3');
290 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer_.preedit_string());
291 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, 0, '0');
292 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer_.preedit_string());
293 ExpectUnicodeKeyFiltered(VKEY_4, DomCode::DIGIT4, 0, '4');
294 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer_.preedit_string());
295 ExpectUnicodeKeyFiltered(VKEY_A, DomCode::KEY_A, 0, 'a');
296 EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer_.preedit_string());
297 ExpectUnicodeKeyFiltered(VKEY_BACK, DomCode::BACKSPACE, EF_NONE, '\b');
298 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer_.preedit_string());
299 ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, EF_NONE, '2');
300 ExpectUnicodeKeyComposed(VKEY_RETURN, DomCode::ENTER, EF_NONE,
301 '\r',
302 base::string16(1, 0x3042));
303 EXPECT_EQ(ASCIIToUTF16(""), character_composer_.preedit_string());
305 // Sequence with an ignored character ('x') and Escape.
306 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
307 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 'U');
308 EXPECT_EQ(ASCIIToUTF16("u"), character_composer_.preedit_string());
309 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, 0, '3');
310 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer_.preedit_string());
311 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, 0, '0');
312 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer_.preedit_string());
313 ExpectUnicodeKeyFiltered(VKEY_X, DomCode::KEY_X, 0, 'x');
314 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer_.preedit_string());
315 ExpectUnicodeKeyFiltered(VKEY_4, DomCode::DIGIT4, 0, '4');
316 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer_.preedit_string());
317 ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, 0, '2');
318 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer_.preedit_string());
319 ExpectUnicodeKeyFiltered(VKEY_ESCAPE, DomCode::ESCAPE, EF_NONE, 0x1B);
320 EXPECT_EQ(ASCIIToUTF16(""), character_composer_.preedit_string());
323 TEST_F(CharacterComposerTest, HexadecimalCompositionWithNonHexKey) {
324 // Sequence [Ctrl+Shift+U, x, space] does not compose a character.
325 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
326 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
327 ExpectUnicodeKeyFiltered(VKEY_X, DomCode::KEY_X, 0, 'x');
328 ExpectUnicodeKeyFiltered(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ');
329 EXPECT_TRUE(character_composer_.composed_character().empty());
331 // HIRAGANA LETTER A (U+3042) with a sequence [3, 0, x, 4, 2].
332 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
333 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
334 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, EF_NONE, '3');
335 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, EF_NONE, '0');
336 ExpectUnicodeKeyFiltered(VKEY_X, DomCode::KEY_X, EF_NONE, 'x');
337 ExpectUnicodeKeyFiltered(VKEY_4, DomCode::DIGIT4, EF_NONE, '4');
338 ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, EF_NONE, '2');
339 ExpectUnicodeKeyComposed(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ',
340 base::string16(1, 0x3042));
343 TEST_F(CharacterComposerTest, HexadecimalCompositionWithAdditionalModifiers) {
344 // Ctrl+Shift+Alt+U
345 // HIRAGANA LETTER A (U+3042)
346 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
347 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_ALT_DOWN, 0x15);
348 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, EF_NONE, '3');
349 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, EF_NONE, '0');
350 ExpectUnicodeKeyFiltered(VKEY_4, DomCode::DIGIT4, EF_NONE, '4');
351 ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, EF_NONE, '2');
352 ExpectUnicodeKeyComposed(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ',
353 base::string16(1, 0x3042));
355 // Ctrl+Shift+u (CapsLock enabled)
356 ExpectUnicodeKeyNotFiltered(
357 VKEY_U, DomCode::KEY_U,
358 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_CAPS_LOCK_DOWN, 'u');
361 TEST_F(CharacterComposerTest, CancelHexadecimalComposition) {
362 // Cancel composition with ESC.
363 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
364 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
365 ExpectUnicodeKeyFiltered(VKEY_1, DomCode::DIGIT1, 0, '1');
366 ExpectUnicodeKeyFiltered(VKEY_ESCAPE, DomCode::ESCAPE, EF_NONE, 0x1B);
368 // Now we can start composition again since the last composition was
369 // cancelled.
370 // HIRAGANA LETTER A (U+3042)
371 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
372 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
373 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, EF_NONE, '3');
374 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, EF_NONE, '0');
375 ExpectUnicodeKeyFiltered(VKEY_4, DomCode::DIGIT4, EF_NONE, '4');
376 ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, EF_NONE, '2');
377 ExpectUnicodeKeyComposed(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ',
378 base::string16(1, 0x3042));
381 TEST_F(CharacterComposerTest, HexadecimalCompositionWithBackspace) {
382 // HIRAGANA LETTER A (U+3042)
383 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
384 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
385 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, 0, '3');
386 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, 0, '0');
387 ExpectUnicodeKeyFiltered(VKEY_F, DomCode::KEY_F, 0, 'f');
388 ExpectUnicodeKeyFiltered(VKEY_BACK, DomCode::BACKSPACE, EF_NONE, '\b');
389 ExpectUnicodeKeyFiltered(VKEY_4, DomCode::DIGIT4, EF_NONE, '4');
390 ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, EF_NONE, '2');
391 ExpectUnicodeKeyComposed(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ',
392 base::string16(1, 0x3042));
395 TEST_F(CharacterComposerTest, CancelHexadecimalCompositionWithBackspace) {
396 // Backspace just after Ctrl+Shift+U.
397 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
398 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
399 ExpectUnicodeKeyFiltered(VKEY_BACK, DomCode::BACKSPACE, EF_NONE, '\b');
400 ExpectUnicodeKeyNotFiltered(VKEY_3, DomCode::DIGIT3, EF_NONE, '3');
402 // Backspace twice after Ctrl+Shift+U and 3.
403 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
404 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
405 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, 0, '3');
406 ExpectUnicodeKeyFiltered(VKEY_BACK, DomCode::BACKSPACE, EF_NONE, '\b');
407 ExpectUnicodeKeyFiltered(VKEY_BACK, DomCode::BACKSPACE, EF_NONE, '\b');
408 ExpectUnicodeKeyNotFiltered(VKEY_3, DomCode::DIGIT3, EF_NONE, '3');
411 TEST_F(CharacterComposerTest,
412 HexadecimalCompositionPreeditWithModifierPressed) {
413 // This test case supposes X Window System uses 101 keyboard layout.
414 const int kControlShift = EF_CONTROL_DOWN | EF_SHIFT_DOWN;
415 // HIRAGANA LETTER A (U+3042)
416 ExpectUnicodeKeyFiltered(ui::VKEY_U, DomCode::KEY_U, kControlShift, 0x15);
417 EXPECT_EQ(ASCIIToUTF16("u"), character_composer_.preedit_string());
418 ExpectUnicodeKeyFiltered(ui::VKEY_3, DomCode::DIGIT3, kControlShift, '#');
419 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer_.preedit_string());
420 ExpectUnicodeKeyFiltered(ui::VKEY_0, DomCode::DIGIT0, kControlShift, ')');
421 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer_.preedit_string());
422 ExpectUnicodeKeyFiltered(ui::VKEY_4, DomCode::DIGIT4, kControlShift, '$');
423 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer_.preedit_string());
424 ExpectUnicodeKeyFiltered(ui::VKEY_A, DomCode::KEY_A, kControlShift, 0x01);
425 EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer_.preedit_string());
426 ExpectUnicodeKeyFiltered(ui::VKEY_BACK, DomCode::BACKSPACE, kControlShift,
427 '\b');
428 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer_.preedit_string());
429 ExpectUnicodeKeyFiltered(ui::VKEY_2, DomCode::DIGIT2, kControlShift, 0);
430 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer_.preedit_string());
431 ExpectUnicodeKeyComposed(VKEY_RETURN, DomCode::ENTER, kControlShift,
432 '\r',
433 base::string16(1, 0x3042));
434 EXPECT_EQ(ASCIIToUTF16(""), character_composer_.preedit_string());
436 // Sequence with an ignored character (control + shift + 'x') and Escape.
437 ExpectUnicodeKeyFiltered(ui::VKEY_U, DomCode::KEY_U, kControlShift, 'U');
438 EXPECT_EQ(ASCIIToUTF16("u"), character_composer_.preedit_string());
439 ExpectUnicodeKeyFiltered(ui::VKEY_3, DomCode::DIGIT3, kControlShift, '#');
440 EXPECT_EQ(ASCIIToUTF16("u3"), character_composer_.preedit_string());
441 ExpectUnicodeKeyFiltered(ui::VKEY_0, DomCode::DIGIT0, kControlShift, ')');
442 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer_.preedit_string());
443 ExpectUnicodeKeyFiltered(ui::VKEY_X, DomCode::KEY_X, kControlShift, 'X');
444 EXPECT_EQ(ASCIIToUTF16("u30"), character_composer_.preedit_string());
445 ExpectUnicodeKeyFiltered(ui::VKEY_4, DomCode::DIGIT4, kControlShift, '$');
446 EXPECT_EQ(ASCIIToUTF16("u304"), character_composer_.preedit_string());
447 ExpectUnicodeKeyFiltered(ui::VKEY_2, DomCode::DIGIT2, kControlShift, 0);
448 EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer_.preedit_string());
449 ExpectUnicodeKeyFiltered(ui::VKEY_ESCAPE, DomCode::ESCAPE, kControlShift,
450 0x1B);
451 EXPECT_EQ(ASCIIToUTF16(""), character_composer_.preedit_string());
454 TEST_F(CharacterComposerTest, InvalidHexadecimalSequence) {
455 // U+FFFFFFFF
456 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
457 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
458 for (int i = 0; i < 8; ++i)
459 ExpectUnicodeKeyFiltered(VKEY_F, DomCode::KEY_F, 0, 'f');
460 ExpectUnicodeKeyFiltered(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ');
462 // U+0000 (Actually, this is a valid unicode character, but we don't
463 // compose a string with a character '\0')
464 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
465 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
466 for (int i = 0; i < 4; ++i)
467 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, 0, '0');
468 ExpectUnicodeKeyFiltered(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ');
470 // U+10FFFF
471 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
472 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
473 ExpectUnicodeKeyFiltered(VKEY_1, DomCode::DIGIT1, 0, '1');
474 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, 0, '0');
475 for (int i = 0; i < 4; ++i)
476 ExpectUnicodeKeyFiltered(VKEY_F, DomCode::KEY_F, 0, 'f');
477 ExpectUnicodeKeyFiltered(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ');
479 // U+110000
480 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
481 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
482 ExpectUnicodeKeyFiltered(VKEY_1, DomCode::DIGIT1, 0, '1');
483 ExpectUnicodeKeyFiltered(VKEY_1, DomCode::DIGIT1, 0, '1');
484 for (int i = 0; i < 4; ++i)
485 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, 0, '0');
486 ExpectUnicodeKeyFiltered(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ');
489 TEST_F(CharacterComposerTest, HexadecimalSequenceAndDeadKey) {
490 // LATIN SMALL LETTER A WITH ACUTE
491 ExpectDeadKeyFiltered(kCombiningAcute);
492 ExpectUnicodeKeyComposed(VKEY_A, DomCode::KEY_A, EF_NONE, 'a',
493 base::string16(1, 0x00E1));
494 // HIRAGANA LETTER A (U+3042) with dead_acute ignored.
495 ExpectUnicodeKeyFiltered(VKEY_U, DomCode::KEY_U,
496 EF_SHIFT_DOWN | EF_CONTROL_DOWN, 0x15);
497 ExpectUnicodeKeyFiltered(VKEY_3, DomCode::DIGIT3, EF_NONE, '3');
498 ExpectUnicodeKeyFiltered(VKEY_0, DomCode::DIGIT0, EF_NONE, '0');
499 ExpectDeadKeyFiltered(kCombiningAcute);
500 ExpectUnicodeKeyFiltered(VKEY_4, DomCode::DIGIT4, EF_NONE, '4');
501 ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, EF_NONE, '2');
502 ExpectUnicodeKeyComposed(VKEY_SPACE, DomCode::SPACE, EF_NONE, ' ',
503 base::string16(1, 0x3042));
506 } // namespace ui