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/events/keycodes/dom/keycode_converter.h"
9 #include "base/basictypes.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/events/keycodes/dom/dom_code.h"
12 #include "ui/events/keycodes/dom/dom_key.h"
14 using ui::KeycodeConverter
;
19 const size_t kExpectedMappedKeyCount
= 138;
20 #elif defined(OS_LINUX)
21 const size_t kExpectedMappedKeyCount
= 168;
22 #elif defined(OS_MACOSX)
23 const size_t kExpectedMappedKeyCount
= 118;
24 #elif defined(OS_ANDROID)
25 const size_t kExpectedMappedKeyCount
= 168;
27 const size_t kExpectedMappedKeyCount
= 0;
30 const uint32_t kUsbNonExistentKeycode
= 0xffffff;
31 const uint32_t kUsbUsBackslash
= 0x070031;
32 const uint32_t kUsbNonUsHash
= 0x070032;
34 TEST(UsbKeycodeMap
, Basic
) {
35 // Verify that the first element in the table is the "invalid" code.
36 const ui::KeycodeMapEntry
* keycode_map
=
37 ui::KeycodeConverter::GetKeycodeMapForTest();
38 EXPECT_EQ(ui::KeycodeConverter::InvalidUsbKeycode(),
39 keycode_map
[0].usb_keycode
);
40 EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
41 keycode_map
[0].native_keycode
);
42 EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
43 ui::KeycodeConverter::DomCodeToNativeKeycode(ui::DomCode::NONE
));
45 // Verify that there are no duplicate entries in the mapping.
46 std::map
<uint32_t, uint16_t> usb_to_native
;
47 std::map
<uint16_t, uint32_t> native_to_usb
;
48 size_t numEntries
= ui::KeycodeConverter::NumKeycodeMapEntriesForTest();
49 for (size_t i
= 0; i
< numEntries
; ++i
) {
50 const ui::KeycodeMapEntry
* entry
= &keycode_map
[i
];
51 // Don't test keys with no native keycode mapping on this platform.
52 if (entry
->native_keycode
== ui::KeycodeConverter::InvalidNativeKeycode())
55 // Verify UsbKeycodeToNativeKeycode works for this key.
57 entry
->native_keycode
,
58 ui::KeycodeConverter::UsbKeycodeToNativeKeycode(entry
->usb_keycode
));
60 // Verify DomCodeToNativeKeycode works correctly.
61 ui::DomCode dom_code
=
62 ui::KeycodeConverter::CodeStringToDomCode(entry
->code
);
64 EXPECT_EQ(entry
->native_keycode
,
65 ui::KeycodeConverter::DomCodeToNativeKeycode(dom_code
));
67 EXPECT_EQ(ui::DomCode::NONE
, dom_code
);
70 // Verify that the USB or native codes aren't duplicated.
71 EXPECT_EQ(0U, usb_to_native
.count(entry
->usb_keycode
))
72 << " duplicate of USB code 0x" << std::hex
<< std::setfill('0')
73 << std::setw(6) << entry
->usb_keycode
75 << std::setw(4) << entry
->native_keycode
76 << " (previous was 0x"
77 << std::setw(4) << usb_to_native
[entry
->usb_keycode
]
79 usb_to_native
[entry
->usb_keycode
] = entry
->native_keycode
;
80 EXPECT_EQ(0U, native_to_usb
.count(entry
->native_keycode
))
81 << " duplicate of native code 0x" << std::hex
<< std::setfill('0')
82 << std::setw(4) << entry
->native_keycode
84 << std::setw(6) << entry
->usb_keycode
85 << " (previous was 0x"
86 << std::setw(6) << native_to_usb
[entry
->native_keycode
]
88 native_to_usb
[entry
->native_keycode
] = entry
->usb_keycode
;
90 ASSERT_EQ(usb_to_native
.size(), native_to_usb
.size());
92 // Verify that the number of mapped keys is what we expect, i.e. we haven't
93 // lost any, and if we've added some then the expectation has been updated.
94 EXPECT_EQ(kExpectedMappedKeyCount
, usb_to_native
.size());
97 TEST(UsbKeycodeMap
, NonExistent
) {
98 // Verify that UsbKeycodeToNativeKeycode works for a non-existent USB keycode.
100 ui::KeycodeConverter::InvalidNativeKeycode(),
101 ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbNonExistentKeycode
));
104 TEST(UsbKeycodeMap
, UsBackslashIsNonUsHash
) {
105 // Verify that UsbKeycodeToNativeKeycode treats the non-US "hash" key
106 // as equivalent to the US "backslash" key.
107 EXPECT_EQ(ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbUsBackslash
),
108 ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbNonUsHash
));
111 TEST(KeycodeConverter
, DomCode
) {
112 // Test invalid and unknown arguments to CodeStringToDomCode()
113 EXPECT_EQ(ui::DomCode::NONE
,
114 ui::KeycodeConverter::CodeStringToDomCode(nullptr));
115 EXPECT_EQ(ui::DomCode::NONE
, ui::KeycodeConverter::CodeStringToDomCode("-"));
116 EXPECT_EQ(ui::DomCode::NONE
, ui::KeycodeConverter::CodeStringToDomCode(""));
117 // Round-trip test DOM Level 3 .code strings.
118 const ui::KeycodeMapEntry
* keycode_map
=
119 ui::KeycodeConverter::GetKeycodeMapForTest();
120 size_t numEntries
= ui::KeycodeConverter::NumKeycodeMapEntriesForTest();
121 for (size_t i
= 0; i
< numEntries
; ++i
) {
123 const ui::KeycodeMapEntry
* entry
= &keycode_map
[i
];
124 ui::DomCode code
= ui::KeycodeConverter::CodeStringToDomCode(entry
->code
);
126 EXPECT_STREQ(entry
->code
,
127 ui::KeycodeConverter::DomCodeToCodeString(code
));
129 EXPECT_EQ(static_cast<int>(ui::DomCode::NONE
),
130 static_cast<int>(code
));
135 TEST(KeycodeConverter
, DomKey
) {
137 ui::DomKey::Base key
;
141 const char* const string
;
143 // Invalid arguments to KeyStringToDomKey().
144 {ui::DomKey::NONE
, false, false, false, nullptr},
145 {ui::DomKey::NONE
, false, false, true, ""},
146 {ui::DomKey::NONE
, false, false, false, "?!?"},
147 {ui::DomKey::NONE
, false, false, false, "\x61\xCC\x81"},
148 // Some single Unicode characters.
149 {ui::DomKey::Constant
<'-'>::Character
, true, false, true, "-"},
150 {ui::DomKey::Constant
<'A'>::Character
, true, false, true, "A"},
151 {ui::DomKey::Constant
<0xE1>::Character
, true, false, true, "\xC3\xA1"},
152 {ui::DomKey::Constant
<0x1F648>::Character
, true, false, true,
154 // Unicode-equivalent named values.
155 {ui::DomKey::BACKSPACE
, true, false, true, "Backspace"},
156 {ui::DomKey::TAB
, true, false, true, "Tab"},
157 {ui::DomKey::ENTER
, true, false, true, "Enter"},
158 {ui::DomKey::ESCAPE
, true, false, true, "Escape"},
159 {ui::DomKey::DEL
, true, false, true, "Delete"},
160 {ui::DomKey::BACKSPACE
, true, false, false, "\b"},
161 {ui::DomKey::TAB
, true, false, false, "\t"},
162 {ui::DomKey::ENTER
, true, false, false, "\r"},
163 {ui::DomKey::ESCAPE
, true, false, false, "\x1B"},
164 {ui::DomKey::DEL
, true, false, false, "\x7F"},
165 {ui::DomKey::Constant
<'\b'>::Character
, true, false, true, "Backspace"},
166 {ui::DomKey::Constant
<'\t'>::Character
, true, false, true, "Tab"},
167 {ui::DomKey::Constant
<'\r'>::Character
, true, false, true, "Enter"},
168 {ui::DomKey::Constant
<0x1B>::Character
, true, false, true, "Escape"},
169 {ui::DomKey::Constant
<0x7F>::Character
, true, false, true, "Delete"},
171 {ui::DomKey::Constant
<0xFFFF>::Dead
, false, true, true, "Dead"},
172 // Sample non-Unicode key names.
173 {ui::DomKey::SHIFT
, false, false, true, "Shift"},
174 {ui::DomKey::F16
, false, false, true, "F16"},
175 {ui::DomKey::ZOOM_IN
, false, false, true, "ZoomIn"},
176 {ui::DomKey::UNIDENTIFIED
, false, false, true, "Unidentified"},
178 for (const auto& test
: test_cases
) {
179 // Check KeyStringToDomKey().
180 ui::DomKey key
= ui::KeycodeConverter::KeyStringToDomKey(test
.string
);
181 EXPECT_EQ(test
.is_character
, key
.IsCharacter());
182 EXPECT_EQ(test
.is_dead
, key
.IsDeadKey());
183 EXPECT_EQ(test
.key
, key
);
184 // Check |DomKeyToKeyString()|.
185 if (test
.test_to_string
) {
186 std::string
s(ui::KeycodeConverter::DomKeyToKeyString(test
.key
));
187 EXPECT_STREQ(test
.string
, s
.c_str());
190 // Round-trip test all UI Events KeyboardEvent.key strings.
191 const char* s
= nullptr;
193 (s
= ui::KeycodeConverter::DomKeyStringForTest(i
)) != nullptr; ++i
) {
195 ui::DomKey key
= ui::KeycodeConverter::KeyStringToDomKey(s
);
197 EXPECT_STREQ(s
, ui::KeycodeConverter::DomKeyToKeyString(key
).c_str());
199 EXPECT_EQ(ui::DomKey::NONE
, key
);