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