Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / events / keycodes / dom / keycode_converter_unittest.cc
blob02fc13bfa0333ace3ceae29782ed0193c4c34620
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"
7 #include <map>
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;
16 namespace {
18 #if defined(OS_WIN)
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;
26 #else
27 const size_t kExpectedMappedKeyCount = 0;
28 #endif
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())
53 continue;
55 // Verify UsbKeycodeToNativeKeycode works for this key.
56 EXPECT_EQ(
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);
63 if (entry->code) {
64 EXPECT_EQ(entry->native_keycode,
65 ui::KeycodeConverter::DomCodeToNativeKeycode(dom_code));
66 } else {
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
74 << " to native 0x"
75 << std::setw(4) << entry->native_keycode
76 << " (previous was 0x"
77 << std::setw(4) << usb_to_native[entry->usb_keycode]
78 << ")";
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
83 << " to USB 0x"
84 << std::setw(6) << entry->usb_keycode
85 << " (previous was 0x"
86 << std::setw(6) << native_to_usb[entry->native_keycode]
87 << ")";
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.
99 EXPECT_EQ(
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) {
122 SCOPED_TRACE(i);
123 const ui::KeycodeMapEntry* entry = &keycode_map[i];
124 ui::DomCode code = ui::KeycodeConverter::CodeStringToDomCode(entry->code);
125 if (entry->code) {
126 EXPECT_STREQ(entry->code,
127 ui::KeycodeConverter::DomCodeToCodeString(code));
128 } else {
129 EXPECT_EQ(static_cast<int>(ui::DomCode::NONE),
130 static_cast<int>(code));
135 TEST(KeycodeConverter, DomKey) {
136 const struct {
137 ui::DomKey::Base key;
138 bool is_character;
139 bool is_dead;
140 bool test_to_string;
141 const char* const string;
142 } test_cases[] = {
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,
153 "\xF0\x9F\x99\x88"},
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"},
170 // 'Dead' key.
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;
192 for (size_t i = 0;
193 (s = ui::KeycodeConverter::DomKeyStringForTest(i)) != nullptr; ++i) {
194 SCOPED_TRACE(i);
195 ui::DomKey key = ui::KeycodeConverter::KeyStringToDomKey(s);
196 if (s) {
197 EXPECT_STREQ(s, ui::KeycodeConverter::DomKeyToKeyString(key).c_str());
198 } else {
199 EXPECT_EQ(ui::DomKey::NONE, key);
204 } // namespace