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