Home | History | Annotate | Download | only in input_method
      1 // Copyright (c) 2011 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 "chrome/browser/chromeos/input_method/input_method_util.h"
      6 
      7 #include <string>
      8 
      9 #include "base/utf_string_conversions.h"
     10 #include "chrome/browser/chromeos/cros/cros_library.h"
     11 #include "grit/generated_resources.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 #include "ui/base/l10n/l10n_util.h"
     14 
     15 namespace chromeos {
     16 namespace input_method {
     17 
     18 class InputMethodUtilTest : public testing::Test {
     19  public:
     20   static void SetUpTestCase() {
     21     // Reload the internal maps before running tests, with the stub
     22     // libcros enabled, so that test data is loaded properly.
     23     ScopedStubCrosEnabler stub_cros_enabler;
     24     ReloadInternalMaps();
     25   }
     26 
     27  private:
     28   // Ensure we always use the stub libcros in each test.
     29   ScopedStubCrosEnabler stub_cros_enabler_;
     30 };
     31 
     32 TEST_F(InputMethodUtilTest, GetStringUTF8) {
     33   EXPECT_EQ("Pinyin input method",
     34             GetStringUTF8("Pinyin", ""));
     35   EXPECT_EQ("Japanese input method (for US Dvorak keyboard)",
     36             GetStringUTF8("Mozc (US Dvorak keyboard layout)", ""));
     37   EXPECT_EQ("Google Japanese Input (for US Dvorak keyboard)",
     38             GetStringUTF8("Google Japanese Input (US Dvorak keyboard layout)",
     39                           ""));
     40 }
     41 
     42 TEST_F(InputMethodUtilTest, StringIsSupported) {
     43   EXPECT_TRUE(StringIsSupported("Hiragana", "mozc"));
     44   EXPECT_TRUE(StringIsSupported("Latin", "mozc"));
     45   EXPECT_TRUE(StringIsSupported("Direct input", "mozc"));
     46   EXPECT_FALSE(StringIsSupported(
     47       "####THIS_STRING_IS_NOT_SUPPORTED####", "mozc"));
     48   EXPECT_TRUE(StringIsSupported("Chinese", "pinyin"));
     49   EXPECT_TRUE(StringIsSupported("Chinese", "mozc-chewing"));
     50   // The string "Chinese" is not for "hangul".
     51   EXPECT_FALSE(StringIsSupported("Chinese", "hangul"));
     52 }
     53 
     54 TEST_F(InputMethodUtilTest, NormalizeLanguageCode) {
     55   // TODO(yusukes): test all language codes that IBus provides.
     56   EXPECT_EQ("ja", NormalizeLanguageCode("ja"));
     57   EXPECT_EQ("ja", NormalizeLanguageCode("jpn"));
     58   // In the past "t" had a meaning of "other language" for some m17n latin
     59   // input methods for testing purpose, but it is no longer used. We test "t"
     60   // here as just an "unknown" language.
     61   EXPECT_EQ("t", NormalizeLanguageCode("t"));
     62   EXPECT_EQ("zh-CN", NormalizeLanguageCode("zh-CN"));
     63   EXPECT_EQ("zh-CN", NormalizeLanguageCode("zh_CN"));
     64   EXPECT_EQ("en-US", NormalizeLanguageCode("EN_us"));
     65   // See app/l10n_util.cc for es-419.
     66   EXPECT_EQ("es-419", NormalizeLanguageCode("es_419"));
     67 
     68   // Special three-letter language codes.
     69   EXPECT_EQ("cs", NormalizeLanguageCode("cze"));
     70   EXPECT_EQ("de", NormalizeLanguageCode("ger"));
     71   EXPECT_EQ("el", NormalizeLanguageCode("gre"));
     72   EXPECT_EQ("hr", NormalizeLanguageCode("scr"));
     73   EXPECT_EQ("ro", NormalizeLanguageCode("rum"));
     74   EXPECT_EQ("sk", NormalizeLanguageCode("slo"));
     75 }
     76 
     77 TEST_F(InputMethodUtilTest, IsKeyboardLayout) {
     78   EXPECT_TRUE(IsKeyboardLayout("xkb:us::eng"));
     79   EXPECT_FALSE(IsKeyboardLayout("mozc"));
     80 }
     81 
     82 TEST_F(InputMethodUtilTest, GetLanguageCodeFromDescriptor) {
     83   EXPECT_EQ("ja", GetLanguageCodeFromDescriptor(
     84       InputMethodDescriptor("mozc", "Mozc", "us", "ja")));
     85   EXPECT_EQ("zh-TW", GetLanguageCodeFromDescriptor(
     86       InputMethodDescriptor("mozc-chewing", "Chewing", "us", "zh")));
     87   EXPECT_EQ("zh-TW", GetLanguageCodeFromDescriptor(
     88       InputMethodDescriptor("m17n:zh:cangjie", "Cangjie", "us", "zh")));
     89   EXPECT_EQ("zh-TW", GetLanguageCodeFromDescriptor(
     90       InputMethodDescriptor("m17n:zh:quick", "Quick", "us", "zh")));
     91   EXPECT_EQ("zh-CN", GetLanguageCodeFromDescriptor(
     92       InputMethodDescriptor("pinyin", "Pinyin", "us", "zh")));
     93   EXPECT_EQ("en-US", GetLanguageCodeFromDescriptor(
     94       InputMethodDescriptor("xkb:us::eng", "USA", "us", "eng")));
     95   EXPECT_EQ("en-UK", GetLanguageCodeFromDescriptor(
     96       InputMethodDescriptor("xkb:uk::eng", "United Kingdom", "us", "eng")));
     97 }
     98 
     99 TEST_F(InputMethodUtilTest, GetKeyboardLayoutName) {
    100   // Unsupported case.
    101   EXPECT_EQ("", GetKeyboardLayoutName("UNSUPPORTED_ID"));
    102 
    103   // Supported cases (samples).
    104   EXPECT_EQ("jp", GetKeyboardLayoutName("mozc-jp"));
    105   EXPECT_EQ("us", GetKeyboardLayoutName("pinyin"));
    106   EXPECT_EQ("us", GetKeyboardLayoutName("m17n:ar:kbd"));
    107   EXPECT_EQ("es", GetKeyboardLayoutName("xkb:es::spa"));
    108   EXPECT_EQ("es(cat)", GetKeyboardLayoutName("xkb:es:cat:cat"));
    109   EXPECT_EQ("gb(extd)", GetKeyboardLayoutName("xkb:gb:extd:eng"));
    110   EXPECT_EQ("us", GetKeyboardLayoutName("xkb:us::eng"));
    111   EXPECT_EQ("us(dvorak)", GetKeyboardLayoutName("xkb:us:dvorak:eng"));
    112   EXPECT_EQ("us(colemak)", GetKeyboardLayoutName("xkb:us:colemak:eng"));
    113   EXPECT_EQ("de(neo)", GetKeyboardLayoutName("xkb:de:neo:ger"));
    114 }
    115 
    116 TEST_F(InputMethodUtilTest, GetLanguageCodeFromInputMethodId) {
    117   // Make sure that the -CN is added properly.
    118   EXPECT_EQ("zh-CN", GetLanguageCodeFromInputMethodId("pinyin"));
    119 }
    120 
    121 TEST_F(InputMethodUtilTest, GetInputMethodDisplayNameFromId) {
    122   EXPECT_EQ("Pinyin input method", GetInputMethodDisplayNameFromId("pinyin"));
    123   EXPECT_EQ("US keyboard",
    124             GetInputMethodDisplayNameFromId("xkb:us::eng"));
    125   EXPECT_EQ("", GetInputMethodDisplayNameFromId("nonexistent"));
    126 }
    127 
    128 TEST_F(InputMethodUtilTest, GetInputMethodDescriptorFromId) {
    129   EXPECT_EQ(NULL, GetInputMethodDescriptorFromId("non_existent"));
    130 
    131   const InputMethodDescriptor* descriptor =
    132       GetInputMethodDescriptorFromId("pinyin");
    133   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    134   EXPECT_EQ("pinyin", descriptor->id);
    135   EXPECT_EQ("Pinyin", descriptor->display_name);
    136   EXPECT_EQ("us", descriptor->keyboard_layout);
    137   // This is not zh-CN as the language code in InputMethodDescriptor is
    138   // not normalized to our format. The normalization is done in
    139   // GetLanguageCodeFromDescriptor().
    140   EXPECT_EQ("zh", descriptor->language_code);
    141 }
    142 
    143 TEST_F(InputMethodUtilTest, GetLanguageNativeDisplayNameFromCode) {
    144   EXPECT_EQ(UTF8ToUTF16("suomi"), GetLanguageNativeDisplayNameFromCode("fi"));
    145 }
    146 
    147 TEST_F(InputMethodUtilTest, SortLanguageCodesByNames) {
    148   std::vector<std::string> language_codes;
    149   // Check if this function can handle an empty list.
    150   SortLanguageCodesByNames(&language_codes);
    151 
    152   language_codes.push_back("ja");
    153   language_codes.push_back("fr");
    154   // For "t", see the comment in NormalizeLanguageCode test.
    155   language_codes.push_back("t");
    156   SortLanguageCodesByNames(&language_codes);
    157   ASSERT_EQ(3U, language_codes.size());
    158   ASSERT_EQ("fr", language_codes[0]);  // French
    159   ASSERT_EQ("ja", language_codes[1]);  // Japanese
    160   ASSERT_EQ("t",  language_codes[2]);  // Others
    161 
    162   // Add a duplicate entry and see if it works.
    163   language_codes.push_back("ja");
    164   SortLanguageCodesByNames(&language_codes);
    165   ASSERT_EQ(4U, language_codes.size());
    166   ASSERT_EQ("fr", language_codes[0]);  // French
    167   ASSERT_EQ("ja", language_codes[1]);  // Japanese
    168   ASSERT_EQ("ja", language_codes[2]);  // Japanese
    169   ASSERT_EQ("t",  language_codes[3]);  // Others
    170 }
    171 
    172 TEST_F(InputMethodUtilTest, GetInputMethodIdsForLanguageCode) {
    173   std::multimap<std::string, std::string> language_code_to_ids_map;
    174   language_code_to_ids_map.insert(std::make_pair("ja", "mozc"));
    175   language_code_to_ids_map.insert(std::make_pair("ja", "mozc-jp"));
    176   language_code_to_ids_map.insert(std::make_pair("ja", "xkb:jp:jpn"));
    177   language_code_to_ids_map.insert(std::make_pair("fr", "xkb:fr:fra"));
    178 
    179   std::vector<std::string> result;
    180   EXPECT_TRUE(GetInputMethodIdsFromLanguageCodeInternal(
    181       language_code_to_ids_map, "ja", kAllInputMethods, &result));
    182   EXPECT_EQ(3U, result.size());
    183   EXPECT_TRUE(GetInputMethodIdsFromLanguageCodeInternal(
    184       language_code_to_ids_map, "ja", kKeyboardLayoutsOnly, &result));
    185   ASSERT_EQ(1U, result.size());
    186   EXPECT_EQ("xkb:jp:jpn", result[0]);
    187 
    188   EXPECT_TRUE(GetInputMethodIdsFromLanguageCodeInternal(
    189       language_code_to_ids_map, "fr", kAllInputMethods, &result));
    190   ASSERT_EQ(1U, result.size());
    191   EXPECT_EQ("xkb:fr:fra", result[0]);
    192   EXPECT_TRUE(GetInputMethodIdsFromLanguageCodeInternal(
    193       language_code_to_ids_map, "fr", kKeyboardLayoutsOnly, &result));
    194   ASSERT_EQ(1U, result.size());
    195   EXPECT_EQ("xkb:fr:fra", result[0]);
    196 
    197   EXPECT_FALSE(GetInputMethodIdsFromLanguageCodeInternal(
    198       language_code_to_ids_map, "invalid_lang", kAllInputMethods, &result));
    199   EXPECT_FALSE(GetInputMethodIdsFromLanguageCodeInternal(
    200       language_code_to_ids_map, "invalid_lang", kKeyboardLayoutsOnly, &result));
    201 }
    202 
    203 // US keyboard + English US UI = US keyboard only.
    204 TEST_F(InputMethodUtilTest, GetFirstLoginInputMethodIds_Us_And_EnUs) {
    205   const InputMethodDescriptor* descriptor =
    206       GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    207   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    208   std::vector<std::string> input_method_ids;
    209   GetFirstLoginInputMethodIds("en-US", *descriptor, &input_method_ids);
    210   ASSERT_EQ(1U, input_method_ids.size());
    211   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    212 }
    213 
    214 // US keyboard + Japanese UI = US keyboard + mozc.
    215 TEST_F(InputMethodUtilTest, GetFirstLoginInputMethodIds_Us_And_Ja) {
    216   const InputMethodDescriptor* descriptor =
    217       GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    218   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    219   std::vector<std::string> input_method_ids;
    220   GetFirstLoginInputMethodIds("ja", *descriptor, &input_method_ids);
    221   ASSERT_EQ(2U, input_method_ids.size());
    222   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    223   EXPECT_EQ("mozc", input_method_ids[1]);  // Mozc for US keybaord.
    224 }
    225 
    226 // JP keyboard + Japanese UI = JP keyboard + mozc-jp.
    227 TEST_F(InputMethodUtilTest, GetFirstLoginInputMethodIds_JP_And_Ja) {
    228   const InputMethodDescriptor* descriptor =
    229       GetInputMethodDescriptorFromId("xkb:jp::jpn");  // Japanese keyboard.
    230   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    231   std::vector<std::string> input_method_ids;
    232   GetFirstLoginInputMethodIds("ja", *descriptor, &input_method_ids);
    233   ASSERT_EQ(2U, input_method_ids.size());
    234   EXPECT_EQ("xkb:jp::jpn", input_method_ids[0]);
    235   EXPECT_EQ("mozc-jp", input_method_ids[1]);  // Mozc for JP keybaord.
    236 }
    237 
    238 // US dvorak keyboard + Japanese UI = US dvorak keyboard + mozc-dv.
    239 TEST_F(InputMethodUtilTest, GetFirstLoginInputMethodIds_Dvorak_And_Ja) {
    240   const InputMethodDescriptor* descriptor =
    241       GetInputMethodDescriptorFromId("xkb:us:dvorak:eng");  // US Drovak keyboard.
    242   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    243   std::vector<std::string> input_method_ids;
    244   GetFirstLoginInputMethodIds("ja", *descriptor, &input_method_ids);
    245   ASSERT_EQ(2U, input_method_ids.size());
    246   EXPECT_EQ("xkb:us:dvorak:eng", input_method_ids[0]);
    247   EXPECT_EQ("mozc-dv", input_method_ids[1]);  // Mozc for US Dvorak keybaord.
    248 }
    249 
    250 // US keyboard + Russian UI = US keyboard + Russsian keyboard
    251 TEST_F(InputMethodUtilTest, GetFirstLoginInputMethodIds_Us_And_Ru) {
    252   const InputMethodDescriptor* descriptor =
    253       GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    254   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    255   std::vector<std::string> input_method_ids;
    256   GetFirstLoginInputMethodIds("ru", *descriptor, &input_method_ids);
    257   ASSERT_EQ(2U, input_method_ids.size());
    258   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    259   EXPECT_EQ("xkb:ru::rus", input_method_ids[1]);  // Russian keyboard.
    260 }
    261 
    262 // US keyboard + Traditional Chinese = US keyboard + chewing.
    263 TEST_F(InputMethodUtilTest, GetFirstLoginInputMethodIds_Us_And_ZhTw) {
    264   const InputMethodDescriptor* descriptor =
    265       GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    266   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    267   std::vector<std::string> input_method_ids;
    268   GetFirstLoginInputMethodIds("zh-TW", *descriptor, &input_method_ids);
    269   ASSERT_EQ(2U, input_method_ids.size());
    270   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    271   EXPECT_EQ("mozc-chewing", input_method_ids[1]);  // Chewing.
    272 }
    273 
    274 // US keyboard + Thai = US keyboard + kesmanee.
    275 TEST_F(InputMethodUtilTest, GetFirstLoginInputMethodIds_Us_And_Th) {
    276   const InputMethodDescriptor* descriptor =
    277       GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    278   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    279   std::vector<std::string> input_method_ids;
    280   GetFirstLoginInputMethodIds("th", *descriptor, &input_method_ids);
    281   ASSERT_EQ(2U, input_method_ids.size());
    282   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    283   EXPECT_EQ("m17n:th:kesmanee", input_method_ids[1]);  // Kesmanee.
    284 }
    285 
    286 // US keyboard + Vietnamese = US keyboard + TCVN6064.
    287 TEST_F(InputMethodUtilTest, GetFirstLoginInputMethodIds_Us_And_Vi) {
    288   const InputMethodDescriptor* descriptor =
    289       GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    290   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    291   std::vector<std::string> input_method_ids;
    292   GetFirstLoginInputMethodIds("vi", *descriptor, &input_method_ids);
    293   ASSERT_EQ(2U, input_method_ids.size());
    294   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    295   EXPECT_EQ("m17n:vi:tcvn", input_method_ids[1]);  // TCVN6064.
    296 }
    297 
    298 TEST_F(InputMethodUtilTest, GetLanguageCodesFromInputMethodIds) {
    299   std::vector<std::string> input_method_ids;
    300   input_method_ids.push_back("xkb:us::eng");  // English US.
    301   input_method_ids.push_back("xkb:us:dvorak:eng");  // English US Dvorak.
    302   input_method_ids.push_back("mozc-jp");  // Japanese.
    303   input_method_ids.push_back("xkb:fr::fra");  // French France.
    304   std::vector<std::string> language_codes;
    305   GetLanguageCodesFromInputMethodIds(input_method_ids, &language_codes);
    306   ASSERT_EQ(3U, language_codes.size());
    307   EXPECT_EQ("en-US", language_codes[0]);
    308   EXPECT_EQ("ja", language_codes[1]);
    309   EXPECT_EQ("fr", language_codes[2]);
    310 }
    311 
    312 }  // namespace input_method
    313 }  // namespace chromeos
    314