Home | History | Annotate | Download | only in ime
      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 "chromeos/ime/xkeyboard.h"
      6 
      7 #include <algorithm>
      8 #include <set>
      9 #include <string>
     10 
     11 #include "base/logging.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/message_loop/message_loop.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 #include <X11/Xlib.h>
     17 
     18 namespace chromeos {
     19 namespace input_method {
     20 
     21 namespace {
     22 
     23 class XKeyboardTest : public testing::Test {
     24  public:
     25   XKeyboardTest() {
     26   }
     27 
     28   virtual void SetUp() {
     29     xkey_.reset(XKeyboard::Create());
     30   }
     31 
     32   virtual void TearDown() {
     33     xkey_.reset();
     34   }
     35 
     36   scoped_ptr<XKeyboard> xkey_;
     37 
     38   base::MessageLoopForUI message_loop_;
     39 };
     40 
     41 // Returns true if X display is available.
     42 bool DisplayAvailable() {
     43   return (base::MessagePumpForUI::GetDefaultXDisplay() != NULL);
     44 }
     45 
     46 }  // namespace
     47 
     48 // Tests CheckLayoutName() function.
     49 TEST_F(XKeyboardTest, TestCheckLayoutName) {
     50   // CheckLayoutName should not accept non-alphanumeric characters
     51   // except "()-_".
     52   EXPECT_FALSE(XKeyboard::CheckLayoutNameForTesting("us!"));
     53   EXPECT_FALSE(XKeyboard::CheckLayoutNameForTesting("us; /bin/sh"));
     54   EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting("ab-c_12"));
     55 
     56   // CheckLayoutName should not accept upper-case ascii characters.
     57   EXPECT_FALSE(XKeyboard::CheckLayoutNameForTesting("US"));
     58 
     59   // CheckLayoutName should accept lower-case ascii characters.
     60   for (int c = 'a'; c <= 'z'; ++c) {
     61     EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting(std::string(3, c)));
     62   }
     63 
     64   // CheckLayoutName should accept numbers.
     65   for (int c = '0'; c <= '9'; ++c) {
     66     EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting(std::string(3, c)));
     67   }
     68 
     69   // CheckLayoutName should accept a layout with a variant name.
     70   EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting("us(dvorak)"));
     71   EXPECT_TRUE(XKeyboard::CheckLayoutNameForTesting("jp"));
     72 }
     73 
     74 TEST_F(XKeyboardTest, TestSetCapsLockEnabled) {
     75   if (!DisplayAvailable()) {
     76     // Do not fail the test to allow developers to run unit_tests without an X
     77     // server (e.g. via ssh). Note that both try bots and waterfall always have
     78     // an X server for running browser_tests.
     79     DVLOG(1) << "X server is not available. Skip the test.";
     80     return;
     81   }
     82   const bool initial_lock_state = xkey_->CapsLockIsEnabled();
     83   xkey_->SetCapsLockEnabled(true);
     84   EXPECT_TRUE(xkey_->CapsLockIsEnabled());
     85   xkey_->SetCapsLockEnabled(false);
     86   EXPECT_FALSE(xkey_->CapsLockIsEnabled());
     87   xkey_->SetCapsLockEnabled(true);
     88   EXPECT_TRUE(xkey_->CapsLockIsEnabled());
     89   xkey_->SetCapsLockEnabled(false);
     90   EXPECT_FALSE(xkey_->CapsLockIsEnabled());
     91   xkey_->SetCapsLockEnabled(initial_lock_state);
     92 }
     93 
     94 TEST_F(XKeyboardTest, TestSetNumLockEnabled) {
     95   if (!DisplayAvailable()) {
     96     DVLOG(1) << "X server is not available. Skip the test.";
     97     return;
     98   }
     99   const unsigned int num_lock_mask = xkey_->GetNumLockMask();
    100   ASSERT_NE(0U, num_lock_mask);
    101 
    102   const bool initial_lock_state = xkey_->NumLockIsEnabled();
    103   xkey_->SetNumLockEnabled(true);
    104   EXPECT_TRUE(xkey_->NumLockIsEnabled());
    105   xkey_->SetNumLockEnabled(false);
    106   EXPECT_FALSE(xkey_->NumLockIsEnabled());
    107   xkey_->SetNumLockEnabled(true);
    108   EXPECT_TRUE(xkey_->NumLockIsEnabled());
    109   xkey_->SetNumLockEnabled(false);
    110   EXPECT_FALSE(xkey_->NumLockIsEnabled());
    111   xkey_->SetNumLockEnabled(initial_lock_state);
    112 }
    113 
    114 TEST_F(XKeyboardTest, TestSetCapsLockAndNumLockAtTheSameTime) {
    115   if (!DisplayAvailable()) {
    116     DVLOG(1) << "X server is not available. Skip the test.";
    117     return;
    118   }
    119   const unsigned int num_lock_mask = xkey_->GetNumLockMask();
    120   ASSERT_NE(0U, num_lock_mask);
    121 
    122   const bool initial_caps_lock_state = xkey_->CapsLockIsEnabled();
    123   const bool initial_num_lock_state = xkey_->NumLockIsEnabled();
    124 
    125   // Flip both.
    126   xkey_->SetLockedModifiers(
    127       initial_caps_lock_state ? kDisableLock : kEnableLock,
    128       initial_num_lock_state ? kDisableLock : kEnableLock);
    129   EXPECT_EQ(!initial_caps_lock_state, xkey_->CapsLockIsEnabled());
    130   EXPECT_EQ(!initial_num_lock_state, xkey_->NumLockIsEnabled());
    131 
    132   // Flip Caps Lock.
    133   xkey_->SetLockedModifiers(
    134       initial_caps_lock_state ? kEnableLock : kDisableLock,
    135       kDontChange);
    136   // Use GetLockedModifiers() for verifying the result.
    137   bool c, n;
    138   xkey_->GetLockedModifiers(&c, &n);
    139   EXPECT_EQ(initial_caps_lock_state, c);
    140   EXPECT_EQ(!initial_num_lock_state, n);
    141 
    142   // Flip both.
    143   xkey_->SetLockedModifiers(
    144       initial_caps_lock_state ? kDisableLock : kEnableLock,
    145       initial_num_lock_state ? kEnableLock : kDisableLock);
    146   EXPECT_EQ(!initial_caps_lock_state, xkey_->CapsLockIsEnabled());
    147   EXPECT_EQ(initial_num_lock_state, xkey_->NumLockIsEnabled());
    148 
    149   // Flip Num Lock.
    150   xkey_->SetLockedModifiers(
    151       kDontChange,
    152       initial_num_lock_state ? kDisableLock : kEnableLock);
    153   xkey_->GetLockedModifiers(&c, &n);
    154   EXPECT_EQ(!initial_caps_lock_state, c);
    155   EXPECT_EQ(!initial_num_lock_state, n);
    156 
    157   // Flip both to restore the initial state.
    158   xkey_->SetLockedModifiers(
    159       initial_caps_lock_state ? kEnableLock : kDisableLock,
    160       initial_num_lock_state ? kEnableLock : kDisableLock);
    161   EXPECT_EQ(initial_caps_lock_state, xkey_->CapsLockIsEnabled());
    162   EXPECT_EQ(initial_num_lock_state, xkey_->NumLockIsEnabled());
    163 
    164   // No-op SetLockedModifiers call.
    165   xkey_->SetLockedModifiers(kDontChange, kDontChange);
    166   EXPECT_EQ(initial_caps_lock_state, xkey_->CapsLockIsEnabled());
    167   EXPECT_EQ(initial_num_lock_state, xkey_->NumLockIsEnabled());
    168 
    169   // No-op GetLockedModifiers call. Confirm it does not crash.
    170   xkey_->GetLockedModifiers(NULL, NULL);
    171 }
    172 
    173 TEST_F(XKeyboardTest, TestSetAutoRepeatEnabled) {
    174   if (!DisplayAvailable()) {
    175     DVLOG(1) << "X server is not available. Skip the test.";
    176     return;
    177   }
    178   const bool state = XKeyboard::GetAutoRepeatEnabledForTesting();
    179   XKeyboard::SetAutoRepeatEnabled(!state);
    180   EXPECT_EQ(!state, XKeyboard::GetAutoRepeatEnabledForTesting());
    181   // Restore the initial state.
    182   XKeyboard::SetAutoRepeatEnabled(state);
    183   EXPECT_EQ(state, XKeyboard::GetAutoRepeatEnabledForTesting());
    184 }
    185 
    186 TEST_F(XKeyboardTest, TestSetAutoRepeatRate) {
    187   if (!DisplayAvailable()) {
    188     DVLOG(1) << "X server is not available. Skip the test.";
    189     return;
    190   }
    191   AutoRepeatRate rate;
    192   EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&rate));
    193 
    194   AutoRepeatRate tmp(rate);
    195   ++tmp.initial_delay_in_ms;
    196   ++tmp.repeat_interval_in_ms;
    197   EXPECT_TRUE(XKeyboard::SetAutoRepeatRate(tmp));
    198   EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&tmp));
    199   EXPECT_EQ(rate.initial_delay_in_ms + 1, tmp.initial_delay_in_ms);
    200   EXPECT_EQ(rate.repeat_interval_in_ms + 1, tmp.repeat_interval_in_ms);
    201 
    202   // Restore the initial state.
    203   EXPECT_TRUE(XKeyboard::SetAutoRepeatRate(rate));
    204   EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&tmp));
    205   EXPECT_EQ(rate.initial_delay_in_ms, tmp.initial_delay_in_ms);
    206   EXPECT_EQ(rate.repeat_interval_in_ms, tmp.repeat_interval_in_ms);
    207 }
    208 
    209 }  // namespace input_method
    210 }  // namespace chromeos
    211