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/events/keycodes/dom4/keycode_converter.h"
6
7#include <map>
8
9#include "base/basictypes.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12using ui::KeycodeConverter;
13
14namespace {
15
16#if defined(OS_WIN)
17const size_t kExpectedMappedKeyCount = 138;
18#elif defined(OS_LINUX)
19const size_t kExpectedMappedKeyCount = 145;
20#elif defined(OS_MACOSX)
21const size_t kExpectedMappedKeyCount = 118;
22#else
23const size_t kExpectedMappedKeyCount = 0;
24#endif
25
26const uint32_t kUsbNonExistentKeycode = 0xffffff;
27const uint32_t kUsbUsBackslash =        0x070031;
28const uint32_t kUsbNonUsHash =          0x070032;
29
30TEST(UsbKeycodeMap, Basic) {
31  // Verify that the first element in the table is the "invalid" code.
32  const ui::KeycodeMapEntry* keycode_map =
33      ui::KeycodeConverter::GetKeycodeMapForTest();
34  EXPECT_EQ(ui::KeycodeConverter::InvalidUsbKeycode(),
35            keycode_map[0].usb_keycode);
36  EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
37            keycode_map[0].native_keycode);
38  EXPECT_STREQ(ui::KeycodeConverter::InvalidKeyboardEventCode(),
39               "Unidentified");
40  EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
41            ui::KeycodeConverter::CodeToNativeKeycode("Unidentified"));
42
43  // Verify that there are no duplicate entries in the mapping.
44  std::map<uint32_t, uint16_t> usb_to_native;
45  std::map<uint16_t, uint32_t> native_to_usb;
46  size_t numEntries = ui::KeycodeConverter::NumKeycodeMapEntriesForTest();
47  for (size_t i = 0; i < numEntries; ++i) {
48    const ui::KeycodeMapEntry* entry = &keycode_map[i];
49    // Don't test keys with no native keycode mapping on this platform.
50    if (entry->native_keycode == ui::KeycodeConverter::InvalidNativeKeycode())
51      continue;
52
53    // Verify UsbKeycodeToNativeKeycode works for this key.
54    EXPECT_EQ(
55        entry->native_keycode,
56        ui::KeycodeConverter::UsbKeycodeToNativeKeycode(entry->usb_keycode));
57
58    // Verify CodeToNativeKeycode and NativeKeycodeToCode work correctly.
59    if (entry->code) {
60      EXPECT_EQ(entry->native_keycode,
61                ui::KeycodeConverter::CodeToNativeKeycode(entry->code));
62      EXPECT_STREQ(
63          entry->code,
64          ui::KeycodeConverter::NativeKeycodeToCode(entry->native_keycode));
65    }
66    else {
67      EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
68                ui::KeycodeConverter::CodeToNativeKeycode(entry->code));
69    }
70
71    // Verify that the USB or native codes aren't duplicated.
72    EXPECT_EQ(0U, usb_to_native.count(entry->usb_keycode))
73        << " duplicate of USB code 0x" << std::hex << std::setfill('0')
74        << std::setw(6) << entry->usb_keycode
75        << " to native 0x"
76        << std::setw(4) << entry->native_keycode
77        << " (previous was 0x"
78        << std::setw(4) << usb_to_native[entry->usb_keycode]
79        << ")";
80    usb_to_native[entry->usb_keycode] = entry->native_keycode;
81    EXPECT_EQ(0U, native_to_usb.count(entry->native_keycode))
82        << " duplicate of native code 0x" << std::hex << std::setfill('0')
83        << std::setw(4) << entry->native_keycode
84        << " to USB 0x"
85        << std::setw(6) << entry->usb_keycode
86        << " (previous was 0x"
87        << std::setw(6) << native_to_usb[entry->native_keycode]
88        << ")";
89    native_to_usb[entry->native_keycode] = entry->usb_keycode;
90  }
91  ASSERT_EQ(usb_to_native.size(), native_to_usb.size());
92
93  // Verify that the number of mapped keys is what we expect, i.e. we haven't
94  // lost any, and if we've added some then the expectation has been updated.
95  EXPECT_EQ(kExpectedMappedKeyCount, usb_to_native.size());
96}
97
98TEST(UsbKeycodeMap, NonExistent) {
99  // Verify that UsbKeycodeToNativeKeycode works for a non-existent USB keycode.
100  EXPECT_EQ(
101      ui::KeycodeConverter::InvalidNativeKeycode(),
102      ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbNonExistentKeycode));
103}
104
105TEST(UsbKeycodeMap, UsBackslashIsNonUsHash) {
106  // Verify that UsbKeycodeToNativeKeycode treats the non-US "hash" key
107  // as equivalent to the US "backslash" key.
108  EXPECT_EQ(ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbUsBackslash),
109            ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbNonUsHash));
110}
111
112}  // namespace
113