This source file includes following definitions.
- FilterKeyPress
- ExpectKeyNotFilteredWithKeyCode
- ExpectKeyFilteredWithKeycode
- ExpectKeyNotFiltered
- ExpectKeyFiltered
- ExpectCharacterComposed
- ExpectCharacterComposed
- ExpectCharacterComposed
- ExpectCharacterComposed
- ExpectCharacterComposed
- ExpectCharacterComposedWithKeyCode
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "ui/base/ime/chromeos/character_composer.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/gtk+/gdk/gdkkeysyms.h"
#include "ui/base/glib/glib_integers.h"
#include "ui/events/event_constants.h"
using base::ASCIIToUTF16;
namespace ui {
class CharacterComposerTest : public testing::Test {
protected:
bool FilterKeyPress(CharacterComposer* character_composer,
uint key,
uint keycode,
int flags) {
return character_composer->FilterKeyPressInternal(key, keycode, flags);
}
void ExpectKeyNotFilteredWithKeyCode(CharacterComposer* character_composer,
uint key,
uint keycode,
int flags) {
EXPECT_FALSE(character_composer->FilterKeyPressInternal(key, keycode,
flags));
EXPECT_TRUE(character_composer->composed_character().empty());
}
void ExpectKeyFilteredWithKeycode(CharacterComposer* character_composer,
uint key,
uint keycode,
int flags) {
EXPECT_TRUE(character_composer->FilterKeyPressInternal(key, keycode,
flags));
EXPECT_TRUE(character_composer->composed_character().empty());
}
void ExpectKeyNotFiltered(CharacterComposer* character_composer,
uint key,
int flags) {
ExpectKeyNotFilteredWithKeyCode(character_composer, key, 0, flags);
}
void ExpectKeyFiltered(CharacterComposer* character_composer,
uint key,
int flags) {
ExpectKeyFilteredWithKeycode(character_composer, key, 0, flags);
}
void ExpectCharacterComposed(CharacterComposer* character_composer,
uint key1,
uint key2,
int flags,
const base::string16& expected_character) {
ExpectKeyFiltered(character_composer, key1, flags);
EXPECT_TRUE(character_composer->FilterKeyPressInternal(key2, 0, flags));
EXPECT_EQ(expected_character, character_composer->composed_character());
}
void ExpectCharacterComposed(CharacterComposer* character_composer,
uint key1,
uint key2,
uint key3,
int flags,
const base::string16& expected_character) {
ExpectKeyFiltered(character_composer, key1, flags);
ExpectCharacterComposed(character_composer, key2, key3, flags,
expected_character);
}
void ExpectCharacterComposed(CharacterComposer* character_composer,
uint key1,
uint key2,
uint key3,
uint key4,
int flags,
const base::string16& expected_character) {
ExpectKeyFiltered(character_composer, key1, flags);
ExpectCharacterComposed(character_composer, key2, key3, key4, flags,
expected_character);
}
void ExpectCharacterComposed(CharacterComposer* character_composer,
uint key1,
uint key2,
uint key3,
uint key4,
uint key5,
int flags,
const base::string16& expected_character) {
ExpectKeyFiltered(character_composer, key1, flags);
ExpectCharacterComposed(character_composer, key2, key3, key4, key5, flags,
expected_character);
}
void ExpectCharacterComposed(CharacterComposer* character_composer,
uint key1,
uint key2,
uint key3,
uint key4,
uint key5,
uint key6,
int flags,
const base::string16& expected_character) {
ExpectKeyFiltered(character_composer, key1, flags);
ExpectCharacterComposed(character_composer, key2, key3, key4, key5, key6,
flags, expected_character);
}
void ExpectCharacterComposedWithKeyCode(
CharacterComposer* character_composer,
uint key1, uint keycode1,
int flags,
const base::string16& expected_character) {
EXPECT_TRUE(character_composer->FilterKeyPressInternal(key1, keycode1,
flags));
EXPECT_EQ(expected_character, character_composer->composed_character());
}
};
TEST_F(CharacterComposerTest, InitialState) {
CharacterComposer character_composer;
EXPECT_TRUE(character_composer.composed_character().empty());
}
TEST_F(CharacterComposerTest, NormalKeyIsNotFiltered) {
CharacterComposer character_composer;
ExpectKeyNotFiltered(&character_composer, GDK_KEY_B, 0);
ExpectKeyNotFiltered(&character_composer, GDK_KEY_Z, 0);
ExpectKeyNotFiltered(&character_composer, GDK_KEY_c, 0);
ExpectKeyNotFiltered(&character_composer, GDK_KEY_m, 0);
ExpectKeyNotFiltered(&character_composer, GDK_KEY_0, 0);
ExpectKeyNotFiltered(&character_composer, GDK_KEY_1, 0);
ExpectKeyNotFiltered(&character_composer, GDK_KEY_8, 0);
}
TEST_F(CharacterComposerTest, PartiallyMatchingSequence) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_dead_circumflex, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
}
TEST_F(CharacterComposerTest, FullyMatchingSequences) {
CharacterComposer character_composer;
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0,
base::string16(1, 0x00E1));
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_A, 0,
base::string16(1, 0x00C1));
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_grave,
GDK_KEY_dead_grave, 0, base::string16(1, 0x0060));
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute,
GDK_KEY_dead_circumflex, GDK_KEY_a, 0,
base::string16(1, 0x1EA5));
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_grave,
GDK_KEY_dead_horn, GDK_KEY_U, 0,
base::string16(1, 0x1EEA));
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_C, 0,
base::string16(1, 0x00C7));
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_c, 0,
base::string16(1, 0x00E7));
}
TEST_F(CharacterComposerTest, FullyMatchingSequencesAfterMatchingFailure) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_dead_circumflex, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute,
GDK_KEY_dead_circumflex, GDK_KEY_a, 0,
base::string16(1, 0x1EA5));
}
TEST_F(CharacterComposerTest, ComposedCharacterIsClearedAfterReset) {
CharacterComposer character_composer;
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0,
base::string16(1, 0x00E1));
character_composer.Reset();
EXPECT_TRUE(character_composer.composed_character().empty());
}
TEST_F(CharacterComposerTest, CompositionStateIsClearedAfterReset) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
character_composer.Reset();
ExpectKeyNotFiltered(&character_composer, GDK_KEY_a, 0);
}
TEST_F(CharacterComposerTest, KeySequenceCompositionPreedit) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
EXPECT_TRUE(character_composer.preedit_string().empty());
EXPECT_TRUE(FilterKeyPress(&character_composer, GDK_KEY_a, 0, 0));
EXPECT_EQ(base::string16(1, 0x00E1), character_composer.composed_character());
EXPECT_TRUE(character_composer.preedit_string().empty());
}
TEST_F(CharacterComposerTest, MainTableIsCorrectlyOrdered) {
#include "third_party/gtk+/gtk/gtkimcontextsimpleseqs.h"
const int index_size = 26;
const int index_stride = 6;
for (int i = 1; i < index_size; ++i) {
const int index_key_prev = gtk_compose_seqs_compact[(i - 1)*index_stride];
const int index_key = gtk_compose_seqs_compact[i*index_stride];
EXPECT_TRUE(index_key > index_key_prev);
}
struct {
int operator()(const uint16* l, const uint16* r, int length) const{
for (int i = 0; i < length; ++i) {
if (l[i] > r[i])
return 1;
if (l[i] < r[i])
return -1;
}
return 0;
}
} compare_sequence;
for (int i = 0; i < index_size; ++i) {
for (int length = 1; length < index_stride - 1; ++length) {
const int index_begin = gtk_compose_seqs_compact[i*index_stride + length];
const int index_end =
gtk_compose_seqs_compact[i*index_stride + length + 1];
const int stride = length + 1;
for (int index = index_begin + stride; index < index_end;
index += stride) {
const uint16* sequence = >k_compose_seqs_compact[index];
const uint16* sequence_prev = sequence - stride;
EXPECT_EQ(1, compare_sequence(sequence, sequence_prev, length));
}
}
}
}
TEST_F(CharacterComposerTest, HexadecimalComposition) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4,
GDK_KEY_2, GDK_KEY_space, 0,
base::string16(1, 0x3042));
const base::char16 kMusicalKeyboard[] = {0xd83c, 0xdfb9};
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectCharacterComposed(&character_composer, GDK_KEY_1, GDK_KEY_f, GDK_KEY_3,
GDK_KEY_b, GDK_KEY_9, GDK_KEY_Return, 0,
base::string16(kMusicalKeyboard,
kMusicalKeyboard +
arraysize(kMusicalKeyboard)));
}
TEST_F(CharacterComposerTest, HexadecimalCompositionPreedit) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0);
EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_4, 0);
EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_a, 0);
EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
ExpectCharacterComposed(&character_composer, GDK_KEY_2, GDK_KEY_Return, 0,
base::string16(1, 0x3042));
EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0);
EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_x, 0);
EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_4, 0);
EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_2, 0);
EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string());
ExpectKeyFiltered(&character_composer, GDK_KEY_Escape, 0);
EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string());
}
TEST_F(CharacterComposerTest, HexadecimalCompositionWithNonHexKey) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectKeyFiltered(&character_composer, GDK_KEY_x, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0);
EXPECT_TRUE(character_composer.composed_character().empty());
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_x,
GDK_KEY_4, GDK_KEY_2, GDK_KEY_space, 0,
base::string16(1, 0x3042));
}
TEST_F(CharacterComposerTest, HexadecimalCompositionWithAdditionalModifiers) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_ALT_DOWN);
ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4,
GDK_KEY_2, GDK_KEY_space, 0,
base::string16(1, 0x3042));
ExpectKeyNotFiltered(&character_composer, GDK_KEY_u,
EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_CAPS_LOCK_DOWN);
}
TEST_F(CharacterComposerTest, CancelHexadecimalComposition) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_Escape, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0, GDK_KEY_4,
GDK_KEY_2, GDK_KEY_space, 0,
base::string16(1, 0x3042));
}
TEST_F(CharacterComposerTest, HexadecimalCompositionWithBackspace) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
ExpectCharacterComposed(&character_composer, GDK_KEY_4, GDK_KEY_2,
GDK_KEY_space, 0, base::string16(1, 0x3042));
}
TEST_F(CharacterComposerTest, CancelHexadecimalCompositionWithBackspace) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
ExpectKeyNotFiltered(&character_composer, GDK_KEY_3, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectKeyFiltered(&character_composer, GDK_KEY_3, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_BackSpace, 0);
ExpectKeyNotFiltered(&character_composer, GDK_KEY_3, 0);
}
TEST_F(CharacterComposerTest, HexadecimalCompositionPreeditWithModifierPressed)
{
CharacterComposer character_composer;
const int control_shift = EF_CONTROL_DOWN | EF_SHIFT_DOWN;
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_U, 30, control_shift);
EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_numbersign, 12, control_shift);
EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_parenright, 19, control_shift);
EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_dollar, 13, control_shift);
EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_A, 38, control_shift);
EXPECT_EQ(ASCIIToUTF16("u304a"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_BackSpace, 22, control_shift);
EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_at, 11, control_shift);
EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string());
ExpectCharacterComposedWithKeyCode(&character_composer,
GDK_KEY_Return, 36,
control_shift,
base::string16(1, 0x3042));
EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_U, 30, control_shift);
EXPECT_EQ(ASCIIToUTF16("u"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_numbersign, 12, control_shift);
EXPECT_EQ(ASCIIToUTF16("u3"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_parenright, 19, control_shift);
EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_X, 53, control_shift);
EXPECT_EQ(ASCIIToUTF16("u30"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_dollar, 13, control_shift);
EXPECT_EQ(ASCIIToUTF16("u304"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_at, 11, control_shift);
EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer.preedit_string());
ExpectKeyFilteredWithKeycode(&character_composer,
GDK_KEY_Escape, 9, control_shift);
EXPECT_EQ(ASCIIToUTF16(""), character_composer.preedit_string());
}
TEST_F(CharacterComposerTest, InvalidHexadecimalSequence) {
CharacterComposer character_composer;
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
for (int i = 0; i < 8; ++i)
ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
for (int i = 0; i < 4; ++i)
ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
for (int i = 0; i < 4; ++i)
ExpectKeyFiltered(&character_composer, GDK_KEY_f, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_1, 0);
for (int i = 0; i < 4; ++i)
ExpectKeyFiltered(&character_composer, GDK_KEY_0, 0);
ExpectKeyFiltered(&character_composer, GDK_KEY_space, 0);
}
TEST_F(CharacterComposerTest, HexadecimalSequenceAndDeadKey) {
CharacterComposer character_composer;
ExpectCharacterComposed(&character_composer, GDK_KEY_dead_acute, GDK_KEY_a, 0,
base::string16(1, 0x00E1));
ExpectKeyFiltered(&character_composer, GDK_KEY_U,
EF_SHIFT_DOWN | EF_CONTROL_DOWN);
ExpectCharacterComposed(&character_composer, GDK_KEY_3, GDK_KEY_0,
GDK_KEY_dead_acute, GDK_KEY_4, GDK_KEY_2,
GDK_KEY_space, 0, base::string16(1, 0x3042));
ExpectKeyFiltered(&character_composer, GDK_KEY_dead_acute, 0);
EXPECT_TRUE(FilterKeyPress(&character_composer, GDK_KEY_U, 0,
EF_SHIFT_DOWN | EF_CONTROL_DOWN));
EXPECT_EQ(base::string16(1, 0x00DA), character_composer.composed_character());
}
TEST_F(CharacterComposerTest, BlacklistedKeyeventsTest) {
CharacterComposer character_composer;
EXPECT_TRUE(FilterKeyPress(&character_composer, GDK_KEY_dead_acute, 0, 0));
EXPECT_FALSE(FilterKeyPress(&character_composer, GDK_KEY_s, 0, 0));
ASSERT_EQ(1U, character_composer.composed_character().size());
EXPECT_EQ(GDK_KEY_apostrophe, character_composer.composed_character().at(0));
}
}