// 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 "chromeos/ime/xkeyboard.h" #include #include #include #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include namespace chromeos { namespace input_method { namespace { class XKeyboardTest : public testing::Test { public: XKeyboardTest() { } virtual void SetUp() { xkey_.reset(XKeyboard::Create()); } virtual void TearDown() { xkey_.reset(); } scoped_ptr xkey_; base::MessageLoopForUI message_loop_; }; // Returns true if X display is available. bool DisplayAvailable() { return (base::MessagePumpForUI::GetDefaultXDisplay() != NULL); } } // namespace // Tests CheckLayoutName() function. TEST_F(XKeyboardTest, TestCheckLayoutName) { // CheckLayoutName should not accept non-alphanumeric characters // except "()-_". EXPECT_FALSE(XKeyboard::CheckLayoutNameForTesting("us!")); EXPECT_FALSE(XKeyboard::CheckLayoutNameForTesting("us; /bin/sh")); EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting("ab-c_12")); // CheckLayoutName should not accept upper-case ascii characters. EXPECT_FALSE(XKeyboard::CheckLayoutNameForTesting("US")); // CheckLayoutName should accept lower-case ascii characters. for (int c = 'a'; c <= 'z'; ++c) { EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting(std::string(3, c))); } // CheckLayoutName should accept numbers. for (int c = '0'; c <= '9'; ++c) { EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting(std::string(3, c))); } // CheckLayoutName should accept a layout with a variant name. EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting("us(dvorak)")); EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting("jp")); } TEST_F(XKeyboardTest, TestSetCapsLockEnabled) { if (!DisplayAvailable()) { // Do not fail the test to allow developers to run unit_tests without an X // server (e.g. via ssh). Note that both try bots and waterfall always have // an X server for running browser_tests. DVLOG(1) << "X server is not available. Skip the test."; return; } const bool initial_lock_state = xkey_->CapsLockIsEnabled(); xkey_->SetCapsLockEnabled(true); EXPECT_TRUE(xkey_->CapsLockIsEnabled()); xkey_->SetCapsLockEnabled(false); EXPECT_FALSE(xkey_->CapsLockIsEnabled()); xkey_->SetCapsLockEnabled(true); EXPECT_TRUE(xkey_->CapsLockIsEnabled()); xkey_->SetCapsLockEnabled(false); EXPECT_FALSE(xkey_->CapsLockIsEnabled()); xkey_->SetCapsLockEnabled(initial_lock_state); } TEST_F(XKeyboardTest, TestSetNumLockEnabled) { if (!DisplayAvailable()) { DVLOG(1) << "X server is not available. Skip the test."; return; } const unsigned int num_lock_mask = xkey_->GetNumLockMask(); ASSERT_NE(0U, num_lock_mask); const bool initial_lock_state = xkey_->NumLockIsEnabled(); xkey_->SetNumLockEnabled(true); EXPECT_TRUE(xkey_->NumLockIsEnabled()); xkey_->SetNumLockEnabled(false); EXPECT_FALSE(xkey_->NumLockIsEnabled()); xkey_->SetNumLockEnabled(true); EXPECT_TRUE(xkey_->NumLockIsEnabled()); xkey_->SetNumLockEnabled(false); EXPECT_FALSE(xkey_->NumLockIsEnabled()); xkey_->SetNumLockEnabled(initial_lock_state); } TEST_F(XKeyboardTest, TestSetCapsLockAndNumLockAtTheSameTime) { if (!DisplayAvailable()) { DVLOG(1) << "X server is not available. Skip the test."; return; } const unsigned int num_lock_mask = xkey_->GetNumLockMask(); ASSERT_NE(0U, num_lock_mask); const bool initial_caps_lock_state = xkey_->CapsLockIsEnabled(); const bool initial_num_lock_state = xkey_->NumLockIsEnabled(); // Flip both. xkey_->SetLockedModifiers( initial_caps_lock_state ? kDisableLock : kEnableLock, initial_num_lock_state ? kDisableLock : kEnableLock); EXPECT_EQ(!initial_caps_lock_state, xkey_->CapsLockIsEnabled()); EXPECT_EQ(!initial_num_lock_state, xkey_->NumLockIsEnabled()); // Flip Caps Lock. xkey_->SetLockedModifiers( initial_caps_lock_state ? kEnableLock : kDisableLock, kDontChange); // Use GetLockedModifiers() for verifying the result. bool c, n; xkey_->GetLockedModifiers(&c, &n); EXPECT_EQ(initial_caps_lock_state, c); EXPECT_EQ(!initial_num_lock_state, n); // Flip both. xkey_->SetLockedModifiers( initial_caps_lock_state ? kDisableLock : kEnableLock, initial_num_lock_state ? kEnableLock : kDisableLock); EXPECT_EQ(!initial_caps_lock_state, xkey_->CapsLockIsEnabled()); EXPECT_EQ(initial_num_lock_state, xkey_->NumLockIsEnabled()); // Flip Num Lock. xkey_->SetLockedModifiers( kDontChange, initial_num_lock_state ? kDisableLock : kEnableLock); xkey_->GetLockedModifiers(&c, &n); EXPECT_EQ(!initial_caps_lock_state, c); EXPECT_EQ(!initial_num_lock_state, n); // Flip both to restore the initial state. xkey_->SetLockedModifiers( initial_caps_lock_state ? kEnableLock : kDisableLock, initial_num_lock_state ? kEnableLock : kDisableLock); EXPECT_EQ(initial_caps_lock_state, xkey_->CapsLockIsEnabled()); EXPECT_EQ(initial_num_lock_state, xkey_->NumLockIsEnabled()); // No-op SetLockedModifiers call. xkey_->SetLockedModifiers(kDontChange, kDontChange); EXPECT_EQ(initial_caps_lock_state, xkey_->CapsLockIsEnabled()); EXPECT_EQ(initial_num_lock_state, xkey_->NumLockIsEnabled()); // No-op GetLockedModifiers call. Confirm it does not crash. xkey_->GetLockedModifiers(NULL, NULL); } TEST_F(XKeyboardTest, TestSetAutoRepeatEnabled) { if (!DisplayAvailable()) { DVLOG(1) << "X server is not available. Skip the test."; return; } const bool state = XKeyboard::GetAutoRepeatEnabledForTesting(); XKeyboard::SetAutoRepeatEnabled(!state); EXPECT_EQ(!state, XKeyboard::GetAutoRepeatEnabledForTesting()); // Restore the initial state. XKeyboard::SetAutoRepeatEnabled(state); EXPECT_EQ(state, XKeyboard::GetAutoRepeatEnabledForTesting()); } TEST_F(XKeyboardTest, TestSetAutoRepeatRate) { if (!DisplayAvailable()) { DVLOG(1) << "X server is not available. Skip the test."; return; } AutoRepeatRate rate; EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&rate)); AutoRepeatRate tmp(rate); ++tmp.initial_delay_in_ms; ++tmp.repeat_interval_in_ms; EXPECT_TRUE(XKeyboard::SetAutoRepeatRate(tmp)); EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&tmp)); EXPECT_EQ(rate.initial_delay_in_ms + 1, tmp.initial_delay_in_ms); EXPECT_EQ(rate.repeat_interval_in_ms + 1, tmp.repeat_interval_in_ms); // Restore the initial state. EXPECT_TRUE(XKeyboard::SetAutoRepeatRate(rate)); EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&tmp)); EXPECT_EQ(rate.initial_delay_in_ms, tmp.initial_delay_in_ms); EXPECT_EQ(rate.repeat_interval_in_ms, tmp.repeat_interval_in_ms); } } // namespace input_method } // namespace chromeos