• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SetUpTestCase()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 
TEST_F(InputMethodUtilTest,GetStringUTF8)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 
TEST_F(InputMethodUtilTest,StringIsSupported)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 
TEST_F(InputMethodUtilTest,NormalizeLanguageCode)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 
TEST_F(InputMethodUtilTest,IsKeyboardLayout)77 TEST_F(InputMethodUtilTest, IsKeyboardLayout) {
78   EXPECT_TRUE(IsKeyboardLayout("xkb:us::eng"));
79   EXPECT_FALSE(IsKeyboardLayout("mozc"));
80 }
81 
TEST_F(InputMethodUtilTest,GetLanguageCodeFromDescriptor)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 
TEST_F(InputMethodUtilTest,GetKeyboardLayoutName)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 
TEST_F(InputMethodUtilTest,GetLanguageCodeFromInputMethodId)116 TEST_F(InputMethodUtilTest, GetLanguageCodeFromInputMethodId) {
117   // Make sure that the -CN is added properly.
118   EXPECT_EQ("zh-CN", GetLanguageCodeFromInputMethodId("pinyin"));
119 }
120 
TEST_F(InputMethodUtilTest,GetInputMethodDisplayNameFromId)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 
TEST_F(InputMethodUtilTest,GetInputMethodDescriptorFromId)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 
TEST_F(InputMethodUtilTest,GetLanguageNativeDisplayNameFromCode)143 TEST_F(InputMethodUtilTest, GetLanguageNativeDisplayNameFromCode) {
144   EXPECT_EQ(UTF8ToUTF16("suomi"), GetLanguageNativeDisplayNameFromCode("fi"));
145 }
146 
TEST_F(InputMethodUtilTest,SortLanguageCodesByNames)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 
TEST_F(InputMethodUtilTest,GetInputMethodIdsForLanguageCode)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.
TEST_F(InputMethodUtilTest,GetFirstLoginInputMethodIds_Us_And_EnUs)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.
TEST_F(InputMethodUtilTest,GetFirstLoginInputMethodIds_Us_And_Ja)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.
TEST_F(InputMethodUtilTest,GetFirstLoginInputMethodIds_JP_And_Ja)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.
TEST_F(InputMethodUtilTest,GetFirstLoginInputMethodIds_Dvorak_And_Ja)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
TEST_F(InputMethodUtilTest,GetFirstLoginInputMethodIds_Us_And_Ru)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.
TEST_F(InputMethodUtilTest,GetFirstLoginInputMethodIds_Us_And_ZhTw)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.
TEST_F(InputMethodUtilTest,GetFirstLoginInputMethodIds_Us_And_Th)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.
TEST_F(InputMethodUtilTest,GetFirstLoginInputMethodIds_Us_And_Vi)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 
TEST_F(InputMethodUtilTest,GetLanguageCodesFromInputMethodIds)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