blob: f5da9a09226a447f0b7f82d77038ec84f134f507 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/events/keycodes/dom/keycode_converter.h"
#include <map>
#include "base/basictypes.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
using ui::KeycodeConverter;
namespace {
#if defined(OS_WIN)
const size_t kExpectedMappedKeyCount = 138;
#elif defined(OS_LINUX)
const size_t kExpectedMappedKeyCount = 168;
#elif defined(OS_MACOSX)
const size_t kExpectedMappedKeyCount = 118;
#else
const size_t kExpectedMappedKeyCount = 0;
#endif
const uint32_t kUsbNonExistentKeycode = 0xffffff;
const uint32_t kUsbUsBackslash = 0x070031;
const uint32_t kUsbNonUsHash = 0x070032;
TEST(UsbKeycodeMap, Basic) {
// Verify that the first element in the table is the "invalid" code.
const ui::KeycodeMapEntry* keycode_map =
ui::KeycodeConverter::GetKeycodeMapForTest();
EXPECT_EQ(ui::KeycodeConverter::InvalidUsbKeycode(),
keycode_map[0].usb_keycode);
EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
keycode_map[0].native_keycode);
EXPECT_EQ(ui::KeycodeConverter::InvalidNativeKeycode(),
ui::KeycodeConverter::DomCodeToNativeKeycode(ui::DomCode::NONE));
// Verify that there are no duplicate entries in the mapping.
std::map<uint32_t, uint16_t> usb_to_native;
std::map<uint16_t, uint32_t> native_to_usb;
size_t numEntries = ui::KeycodeConverter::NumKeycodeMapEntriesForTest();
for (size_t i = 0; i < numEntries; ++i) {
const ui::KeycodeMapEntry* entry = &keycode_map[i];
// Don't test keys with no native keycode mapping on this platform.
if (entry->native_keycode == ui::KeycodeConverter::InvalidNativeKeycode())
continue;
// Verify UsbKeycodeToNativeKeycode works for this key.
EXPECT_EQ(
entry->native_keycode,
ui::KeycodeConverter::UsbKeycodeToNativeKeycode(entry->usb_keycode));
// Verify DomCodeToNativeKeycode works correctly.
ui::DomCode dom_code =
ui::KeycodeConverter::CodeStringToDomCode(entry->code);
if (entry->code) {
EXPECT_EQ(entry->native_keycode,
ui::KeycodeConverter::DomCodeToNativeKeycode(dom_code));
} else {
EXPECT_EQ(ui::DomCode::NONE, dom_code);
}
// Verify that the USB or native codes aren't duplicated.
EXPECT_EQ(0U, usb_to_native.count(entry->usb_keycode))
<< " duplicate of USB code 0x" << std::hex << std::setfill('0')
<< std::setw(6) << entry->usb_keycode
<< " to native 0x"
<< std::setw(4) << entry->native_keycode
<< " (previous was 0x"
<< std::setw(4) << usb_to_native[entry->usb_keycode]
<< ")";
usb_to_native[entry->usb_keycode] = entry->native_keycode;
EXPECT_EQ(0U, native_to_usb.count(entry->native_keycode))
<< " duplicate of native code 0x" << std::hex << std::setfill('0')
<< std::setw(4) << entry->native_keycode
<< " to USB 0x"
<< std::setw(6) << entry->usb_keycode
<< " (previous was 0x"
<< std::setw(6) << native_to_usb[entry->native_keycode]
<< ")";
native_to_usb[entry->native_keycode] = entry->usb_keycode;
}
ASSERT_EQ(usb_to_native.size(), native_to_usb.size());
// Verify that the number of mapped keys is what we expect, i.e. we haven't
// lost any, and if we've added some then the expectation has been updated.
EXPECT_EQ(kExpectedMappedKeyCount, usb_to_native.size());
}
TEST(UsbKeycodeMap, NonExistent) {
// Verify that UsbKeycodeToNativeKeycode works for a non-existent USB keycode.
EXPECT_EQ(
ui::KeycodeConverter::InvalidNativeKeycode(),
ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbNonExistentKeycode));
}
TEST(UsbKeycodeMap, UsBackslashIsNonUsHash) {
// Verify that UsbKeycodeToNativeKeycode treats the non-US "hash" key
// as equivalent to the US "backslash" key.
EXPECT_EQ(ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbUsBackslash),
ui::KeycodeConverter::UsbKeycodeToNativeKeycode(kUsbNonUsHash));
}
TEST(KeycodeConverter, DomCode) {
// Test invalid and unknown arguments to CodeStringToDomCode()
EXPECT_EQ(ui::DomCode::NONE,
ui::KeycodeConverter::CodeStringToDomCode(nullptr));
EXPECT_EQ(ui::DomCode::NONE, ui::KeycodeConverter::CodeStringToDomCode("-"));
EXPECT_EQ(ui::DomCode::NONE, ui::KeycodeConverter::CodeStringToDomCode(""));
// Round-trip test DOM Level 3 .code strings.
const ui::KeycodeMapEntry* keycode_map =
ui::KeycodeConverter::GetKeycodeMapForTest();
size_t numEntries = ui::KeycodeConverter::NumKeycodeMapEntriesForTest();
for (size_t i = 0; i < numEntries; ++i) {
SCOPED_TRACE(i);
const ui::KeycodeMapEntry* entry = &keycode_map[i];
ui::DomCode code = ui::KeycodeConverter::CodeStringToDomCode(entry->code);
if (entry->code) {
EXPECT_STREQ(entry->code,
ui::KeycodeConverter::DomCodeToCodeString(code));
} else {
EXPECT_EQ(static_cast<int>(ui::DomCode::NONE),
static_cast<int>(code));
}
}
}
TEST(KeycodeConverter, DomKey) {
// Test invalid and unknown arguments to KeyStringToDomKey()
EXPECT_EQ(ui::DomKey::NONE, ui::KeycodeConverter::KeyStringToDomKey(nullptr));
EXPECT_EQ(ui::DomKey::NONE, ui::KeycodeConverter::KeyStringToDomKey("-"));
// Round-trip test DOM Level 3 .key strings.
const char* s = nullptr;
for (size_t i = 0;
(s = ui::KeycodeConverter::DomKeyStringForTest(i)) != nullptr;
++i) {
SCOPED_TRACE(i);
ui::DomKey key = ui::KeycodeConverter::KeyStringToDomKey(s);
if (s) {
EXPECT_STREQ(s, ui::KeycodeConverter::DomKeyToKeyString(key));
} else {
EXPECT_EQ(ui::DomKey::NONE, key);
}
}
}
} // namespace