Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / input_method / input_method_util_unittest.cc
blob2c1cc1d45a01504d40b66da3f0ab4f9c761cc49d
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/chromeos/input_method/input_method_util.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chromeos/ime/fake_input_method_delegate.h"
13 #include "chromeos/ime/input_method_manager.h"
14 #include "chromeos/ime/input_method_whitelist.h"
15 #include "grit/generated_resources.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "ui/base/l10n/l10n_util.h"
19 using base::ASCIIToUTF16;
21 namespace chromeos {
23 extern const char* kExtensionImePrefix;
25 namespace input_method {
27 namespace {
29 const char pinyin_ime_id[] =
30 "_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabzh-t-i0-pinyin";
31 const char zhuyin_ime_id[] =
32 "_comp_ime_goedamlknlnjaengojinmfgpmdjmkooozh-hant-t-i0-und";
34 class TestableInputMethodUtil : public InputMethodUtil {
35 public:
36 explicit TestableInputMethodUtil(InputMethodDelegate* delegate,
37 scoped_ptr<InputMethodDescriptors> methods)
38 : InputMethodUtil(delegate, methods.Pass()) {
40 // Change access rights.
41 using InputMethodUtil::GetInputMethodIdsFromLanguageCodeInternal;
42 using InputMethodUtil::GetKeyboardLayoutName;
43 using InputMethodUtil::ReloadInternalMaps;
44 using InputMethodUtil::supported_input_methods_;
47 } // namespace
49 class InputMethodUtilTest : public testing::Test {
50 public:
51 InputMethodUtilTest()
52 : util_(&delegate_, whitelist_.GetSupportedInputMethods()) {
53 delegate_.set_get_localized_string_callback(
54 base::Bind(&l10n_util::GetStringUTF16));
55 delegate_.set_get_display_language_name_callback(
56 base::Bind(&InputMethodUtilTest::GetDisplayLanguageName));
59 virtual void SetUp() OVERRIDE {
60 InputMethodDescriptors input_methods;
62 std::vector<std::string> layouts;
63 std::vector<std::string> languages;
64 layouts.push_back("us");
65 languages.push_back("zh-CN");
67 InputMethodDescriptor pinyin_ime(pinyin_ime_id,
68 "Pinyin input for testing",
69 layouts,
70 languages,
71 false,
72 GURL(""),
73 GURL(""));
74 input_methods.push_back(pinyin_ime);
76 languages.clear();
77 languages.push_back("zh-TW");
78 InputMethodDescriptor zhuyin_ime(zhuyin_ime_id,
79 "Zhuyin input for testing",
80 layouts,
81 languages,
82 false,
83 GURL(""),
84 GURL(""));
85 input_methods.push_back(zhuyin_ime);
87 util_.SetComponentExtensions(input_methods);
90 InputMethodDescriptor GetDesc(const std::string& id,
91 const std::string& raw_layout,
92 const std::string& language_code) {
93 std::vector<std::string> layouts;
94 layouts.push_back(raw_layout);
95 std::vector<std::string> languages;
96 languages.push_back(language_code);
97 return InputMethodDescriptor(id,
98 "",
99 layouts,
100 languages,
101 true,
102 GURL(), // options page url
103 GURL()); // input view page url
106 static base::string16 GetDisplayLanguageName(const std::string& language_code) {
107 return l10n_util::GetDisplayNameForLocale(language_code, "en", true);
110 FakeInputMethodDelegate delegate_;
111 InputMethodWhitelist whitelist_;
112 TestableInputMethodUtil util_;
115 TEST_F(InputMethodUtilTest, GetInputMethodShortNameTest) {
116 // Test normal cases. Two-letter language code should be returned.
118 InputMethodDescriptor desc = GetDesc("m17n:fa:isiri", // input method id
119 "us", // keyboard layout name
120 "fa"); // language name
121 EXPECT_EQ(ASCIIToUTF16("FA"), util_.GetInputMethodShortName(desc));
124 InputMethodDescriptor desc = GetDesc("mozc-hangul", "us", "ko");
125 EXPECT_EQ(base::UTF8ToUTF16("\xed\x95\x9c"),
126 util_.GetInputMethodShortName(desc));
129 InputMethodDescriptor desc = GetDesc("invalid-id", "us", "xx");
130 // Upper-case string of the unknown language code, "xx", should be returned.
131 EXPECT_EQ(ASCIIToUTF16("XX"), util_.GetInputMethodShortName(desc));
134 // Test special cases.
136 InputMethodDescriptor desc = GetDesc("xkb:us:dvorak:eng", "us", "en-US");
137 EXPECT_EQ(ASCIIToUTF16("DV"), util_.GetInputMethodShortName(desc));
140 InputMethodDescriptor desc = GetDesc("xkb:us:colemak:eng", "us", "en-US");
141 EXPECT_EQ(ASCIIToUTF16("CO"), util_.GetInputMethodShortName(desc));
144 InputMethodDescriptor desc =
145 GetDesc("xkb:us:altgr-intl:eng", "us", "en-US");
146 EXPECT_EQ(ASCIIToUTF16("EXTD"), util_.GetInputMethodShortName(desc));
149 InputMethodDescriptor desc = GetDesc("xkb:us:intl:eng", "us", "en-US");
150 EXPECT_EQ(ASCIIToUTF16("INTL"), util_.GetInputMethodShortName(desc));
153 InputMethodDescriptor desc = GetDesc("xkb:de:neo:ger", "de(neo)", "de");
154 EXPECT_EQ(ASCIIToUTF16("NEO"), util_.GetInputMethodShortName(desc));
157 InputMethodDescriptor desc = GetDesc("xkb:es:cat:cat", "es(cat)", "ca");
158 EXPECT_EQ(ASCIIToUTF16("CAS"), util_.GetInputMethodShortName(desc));
161 InputMethodDescriptor desc = GetDesc(pinyin_ime_id, "us", "zh-CN");
162 EXPECT_EQ(base::UTF8ToUTF16("\xe6\x8b\xbc"),
163 util_.GetInputMethodShortName(desc));
166 InputMethodDescriptor desc = GetDesc(zhuyin_ime_id, "us", "zh-TW");
167 EXPECT_EQ(base::UTF8ToUTF16("\xE6\xB3\xA8"),
168 util_.GetInputMethodShortName(desc));
172 TEST_F(InputMethodUtilTest, GetInputMethodMediumNameTest) {
174 // input methods with medium name equal to short name
175 const char * input_method_id[] = {
176 "xkb:us:altgr-intl:eng",
177 "xkb:us:dvorak:eng",
178 "xkb:us:intl:eng",
179 "xkb:us:colemak:eng",
180 "english-m",
181 "xkb:de:neo:ger",
182 "xkb:es:cat:cat",
183 "xkb:gb:dvorak:eng",
185 const int len = ARRAYSIZE_UNSAFE(input_method_id);
186 for (int i=0; i<len; ++i) {
187 InputMethodDescriptor desc = GetDesc(input_method_id[i], "", "");
188 base::string16 medium_name = util_.GetInputMethodMediumName(desc);
189 base::string16 short_name = util_.GetInputMethodShortName(desc);
190 EXPECT_EQ(medium_name,short_name);
194 // input methods with medium name not equal to short name
195 const char * input_method_id[] = {
196 "m17n:zh:cangjie",
197 "m17n:zh:quick",
198 pinyin_ime_id,
199 zhuyin_ime_id,
200 "mozc-hangul",
201 pinyin_ime_id,
202 pinyin_ime_id,
204 const int len = ARRAYSIZE_UNSAFE(input_method_id);
205 for (int i=0; i<len; ++i) {
206 InputMethodDescriptor desc = GetDesc(input_method_id[i], "", "");
207 base::string16 medium_name = util_.GetInputMethodMediumName(desc);
208 base::string16 short_name = util_.GetInputMethodShortName(desc);
209 EXPECT_NE(medium_name,short_name);
214 TEST_F(InputMethodUtilTest, GetInputMethodLongNameTest) {
215 // For most languages input method or keyboard layout name is returned.
216 // See below for exceptions.
218 InputMethodDescriptor desc = GetDesc("m17n:fa:isiri", "us", "fa");
219 EXPECT_EQ(ASCIIToUTF16("Persian input method (ISIRI 2901 layout)"),
220 util_.GetInputMethodLongName(desc));
223 InputMethodDescriptor desc = GetDesc("mozc-hangul", "us", "ko");
224 EXPECT_EQ(ASCIIToUTF16("Korean input method"),
225 util_.GetInputMethodLongName(desc));
228 InputMethodDescriptor desc = GetDesc("m17n:vi:tcvn", "us", "vi");
229 EXPECT_EQ(ASCIIToUTF16("Vietnamese input method (TCVN6064)"),
230 util_.GetInputMethodLongName(desc));
233 InputMethodDescriptor desc = GetDesc("xkb:jp::jpn", "jp", "ja");
234 EXPECT_EQ(ASCIIToUTF16("Japanese keyboard"),
235 util_.GetInputMethodLongName(desc));
238 InputMethodDescriptor desc =
239 GetDesc("xkb:us:dvorak:eng", "us(dvorak)", "en-US");
240 EXPECT_EQ(ASCIIToUTF16("US Dvorak keyboard"),
241 util_.GetInputMethodLongName(desc));
244 InputMethodDescriptor desc =
245 GetDesc("xkb:gb:dvorak:eng", "gb(dvorak)", "en-US");
246 EXPECT_EQ(ASCIIToUTF16("UK Dvorak keyboard"),
247 util_.GetInputMethodLongName(desc));
250 // For Arabic, Dutch, French, German and Hindi,
251 // "language - keyboard layout" pair is returned.
253 InputMethodDescriptor desc = GetDesc("m17n:ar:kbd", "us", "ar");
254 EXPECT_EQ(ASCIIToUTF16("Arabic - Standard input method"),
255 util_.GetInputMethodLongName(desc));
258 InputMethodDescriptor desc = GetDesc("xkb:be::nld", "be", "nl");
259 EXPECT_EQ(ASCIIToUTF16("Dutch - Belgian keyboard"),
260 util_.GetInputMethodLongName(desc));
263 InputMethodDescriptor desc = GetDesc("xkb:fr::fra", "fr", "fr");
264 EXPECT_EQ(ASCIIToUTF16("French - French keyboard"),
265 util_.GetInputMethodLongName(desc));
268 InputMethodDescriptor desc = GetDesc("xkb:be::fra", "be", "fr");
269 EXPECT_EQ(ASCIIToUTF16("French - Belgian keyboard"),
270 util_.GetInputMethodLongName(desc));
273 InputMethodDescriptor desc = GetDesc("xkb:de::ger", "de", "de");
274 EXPECT_EQ(ASCIIToUTF16("German - German keyboard"),
275 util_.GetInputMethodLongName(desc));
278 InputMethodDescriptor desc = GetDesc("xkb:be::ger", "be", "de");
279 EXPECT_EQ(ASCIIToUTF16("German - Belgian keyboard"),
280 util_.GetInputMethodLongName(desc));
283 InputMethodDescriptor desc = GetDesc("m17n:hi:itrans", "us", "hi");
284 EXPECT_EQ(ASCIIToUTF16("Hindi - Standard input method"),
285 util_.GetInputMethodLongName(desc));
289 InputMethodDescriptor desc = GetDesc("invalid-id", "us", "xx");
290 // You can safely ignore the "Resouce ID is not found for: invalid-id"
291 // error.
292 EXPECT_EQ(ASCIIToUTF16("invalid-id"),
293 util_.GetInputMethodLongName(desc));
297 TEST_F(InputMethodUtilTest, TestIsValidInputMethodId) {
298 EXPECT_TRUE(util_.IsValidInputMethodId("xkb:us:colemak:eng"));
299 EXPECT_TRUE(util_.IsValidInputMethodId(pinyin_ime_id));
300 EXPECT_FALSE(util_.IsValidInputMethodId("unsupported-input-method"));
303 TEST_F(InputMethodUtilTest, TestIsKeyboardLayout) {
304 EXPECT_TRUE(InputMethodUtil::IsKeyboardLayout("xkb:us::eng"));
305 EXPECT_FALSE(InputMethodUtil::IsKeyboardLayout(pinyin_ime_id));
308 TEST_F(InputMethodUtilTest, TestGetKeyboardLayoutName) {
309 // Unsupported case.
310 EXPECT_EQ("", util_.GetKeyboardLayoutName("UNSUPPORTED_ID"));
312 // Supported cases (samples).
313 EXPECT_EQ("us", util_.GetKeyboardLayoutName(pinyin_ime_id));
314 EXPECT_EQ("es", util_.GetKeyboardLayoutName("xkb:es::spa"));
315 EXPECT_EQ("es(cat)", util_.GetKeyboardLayoutName("xkb:es:cat:cat"));
316 EXPECT_EQ("gb(extd)", util_.GetKeyboardLayoutName("xkb:gb:extd:eng"));
317 EXPECT_EQ("us", util_.GetKeyboardLayoutName("xkb:us::eng"));
318 EXPECT_EQ("us(dvorak)", util_.GetKeyboardLayoutName("xkb:us:dvorak:eng"));
319 EXPECT_EQ("us(colemak)", util_.GetKeyboardLayoutName("xkb:us:colemak:eng"));
320 EXPECT_EQ("de(neo)", util_.GetKeyboardLayoutName("xkb:de:neo:ger"));
323 TEST_F(InputMethodUtilTest, TestGetLanguageCodeFromInputMethodId) {
324 // Make sure that the -CN is added properly.
325 EXPECT_EQ("zh-CN", util_.GetLanguageCodeFromInputMethodId(pinyin_ime_id));
328 TEST_F(InputMethodUtilTest, TestGetInputMethodDisplayNameFromId) {
329 EXPECT_EQ("US keyboard",
330 util_.GetInputMethodDisplayNameFromId("xkb:us::eng"));
331 EXPECT_EQ("", util_.GetInputMethodDisplayNameFromId("nonexistent"));
334 TEST_F(InputMethodUtilTest, TestGetInputMethodDescriptorFromId) {
335 EXPECT_EQ(NULL, util_.GetInputMethodDescriptorFromId("non_existent"));
337 const InputMethodDescriptor* descriptor =
338 util_.GetInputMethodDescriptorFromId(pinyin_ime_id);
339 ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile.
340 EXPECT_EQ(pinyin_ime_id, descriptor->id());
341 EXPECT_EQ("us", descriptor->GetPreferredKeyboardLayout());
342 // This used to be "zh" but now we have "zh-CN" in input_methods.h,
343 // hence this should be zh-CN now.
344 ASSERT_TRUE(!descriptor->language_codes().empty());
345 EXPECT_EQ("zh-CN", descriptor->language_codes().at(0));
348 TEST_F(InputMethodUtilTest, TestGetInputMethodIdsForLanguageCode) {
349 std::multimap<std::string, std::string> language_code_to_ids_map;
350 language_code_to_ids_map.insert(std::make_pair("ja", pinyin_ime_id));
351 language_code_to_ids_map.insert(std::make_pair("ja", pinyin_ime_id));
352 language_code_to_ids_map.insert(std::make_pair("ja", "xkb:jp:jpn"));
353 language_code_to_ids_map.insert(std::make_pair("fr", "xkb:fr:fra"));
355 std::vector<std::string> result;
356 EXPECT_TRUE(util_.GetInputMethodIdsFromLanguageCodeInternal(
357 language_code_to_ids_map, "ja", kAllInputMethods, &result));
358 EXPECT_EQ(3U, result.size());
359 EXPECT_TRUE(util_.GetInputMethodIdsFromLanguageCodeInternal(
360 language_code_to_ids_map, "ja", kKeyboardLayoutsOnly, &result));
361 ASSERT_EQ(1U, result.size());
362 EXPECT_EQ("xkb:jp:jpn", result[0]);
364 EXPECT_TRUE(util_.GetInputMethodIdsFromLanguageCodeInternal(
365 language_code_to_ids_map, "fr", kAllInputMethods, &result));
366 ASSERT_EQ(1U, result.size());
367 EXPECT_EQ("xkb:fr:fra", result[0]);
368 EXPECT_TRUE(util_.GetInputMethodIdsFromLanguageCodeInternal(
369 language_code_to_ids_map, "fr", kKeyboardLayoutsOnly, &result));
370 ASSERT_EQ(1U, result.size());
371 EXPECT_EQ("xkb:fr:fra", result[0]);
373 EXPECT_FALSE(util_.GetInputMethodIdsFromLanguageCodeInternal(
374 language_code_to_ids_map, "invalid_lang", kAllInputMethods, &result));
375 EXPECT_FALSE(util_.GetInputMethodIdsFromLanguageCodeInternal(
376 language_code_to_ids_map, "invalid_lang", kKeyboardLayoutsOnly, &result));
379 // US keyboard + English US UI = US keyboard only.
380 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_EnUs) {
381 const InputMethodDescriptor* descriptor =
382 util_.GetInputMethodDescriptorFromId("xkb:us::eng"); // US keyboard.
383 ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile.
384 std::vector<std::string> input_method_ids;
385 util_.GetFirstLoginInputMethodIds("en-US", *descriptor, &input_method_ids);
386 ASSERT_EQ(1U, input_method_ids.size());
387 EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
390 // US keyboard + Chinese UI = US keyboard + Pinyin IME.
391 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Zh) {
392 const InputMethodDescriptor* descriptor =
393 util_.GetInputMethodDescriptorFromId("xkb:us::eng"); // US keyboard.
394 ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile.
395 std::vector<std::string> input_method_ids;
396 util_.GetFirstLoginInputMethodIds("zh-CN", *descriptor, &input_method_ids);
397 ASSERT_EQ(2U, input_method_ids.size());
398 EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
399 EXPECT_EQ(pinyin_ime_id, input_method_ids[1]); // Pinyin for US keybaord.
402 // US keyboard + Russian UI = US keyboard + Russsian keyboard
403 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Ru) {
404 const InputMethodDescriptor* descriptor =
405 util_.GetInputMethodDescriptorFromId("xkb:us::eng"); // US keyboard.
406 ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile.
407 std::vector<std::string> input_method_ids;
408 util_.GetFirstLoginInputMethodIds("ru", *descriptor, &input_method_ids);
409 ASSERT_EQ(2U, input_method_ids.size());
410 EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
411 EXPECT_EQ("xkb:ru::rus", input_method_ids[1]); // Russian keyboard.
414 // US keyboard + Traditional Chinese = US keyboard + chewing.
415 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_ZhTw) {
416 const InputMethodDescriptor* descriptor =
417 util_.GetInputMethodDescriptorFromId("xkb:us::eng"); // US keyboard.
418 ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile.
419 std::vector<std::string> input_method_ids;
420 util_.GetFirstLoginInputMethodIds("zh-TW", *descriptor, &input_method_ids);
421 ASSERT_EQ(2U, input_method_ids.size());
422 EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
423 EXPECT_EQ(zhuyin_ime_id, input_method_ids[1]); // Chewing.
426 // US keyboard + Thai = US keyboard + kesmanee.
427 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Th) {
428 const InputMethodDescriptor* descriptor =
429 util_.GetInputMethodDescriptorFromId("xkb:us::eng"); // US keyboard.
430 ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile.
431 std::vector<std::string> input_method_ids;
432 util_.GetFirstLoginInputMethodIds("th", *descriptor, &input_method_ids);
433 ASSERT_EQ(2U, input_method_ids.size());
434 EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
435 EXPECT_EQ("_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_th",
436 input_method_ids[1]); // Kesmanee.
439 // US keyboard + Vietnamese = US keyboard + TCVN6064.
440 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Vi) {
441 const InputMethodDescriptor* descriptor =
442 util_.GetInputMethodDescriptorFromId("xkb:us::eng"); // US keyboard.
443 ASSERT_TRUE(NULL != descriptor); // ASSERT_NE doesn't compile.
444 std::vector<std::string> input_method_ids;
445 util_.GetFirstLoginInputMethodIds("vi", *descriptor, &input_method_ids);
446 ASSERT_EQ(2U, input_method_ids.size());
447 EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
448 EXPECT_EQ("_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_vi_tcvn",
449 input_method_ids[1]); // TCVN6064.
452 TEST_F(InputMethodUtilTest, TestGetLanguageCodesFromInputMethodIds) {
453 std::vector<std::string> input_method_ids;
454 input_method_ids.push_back("xkb:us::eng"); // English US.
455 input_method_ids.push_back("xkb:us:dvorak:eng"); // English US Dvorak.
456 input_method_ids.push_back(pinyin_ime_id); // Pinyin
457 input_method_ids.push_back("xkb:fr::fra"); // French France.
458 std::vector<std::string> language_codes;
459 util_.GetLanguageCodesFromInputMethodIds(input_method_ids, &language_codes);
460 ASSERT_EQ(3U, language_codes.size());
461 EXPECT_EQ("en-US", language_codes[0]);
462 EXPECT_EQ("zh-CN", language_codes[1]);
463 EXPECT_EQ("fr", language_codes[2]);
466 // Test all supported descriptors to detect a typo in ibus_input_methods.txt.
467 TEST_F(InputMethodUtilTest, TestIBusInputMethodText) {
468 for (size_t i = 0; i < util_.supported_input_methods_->size(); ++i) {
469 const std::string language_code =
470 util_.supported_input_methods_->at(i).language_codes().at(0);
471 const base::string16 display_name =
472 l10n_util::GetDisplayNameForLocale(language_code, "en", false);
473 // Only two formats, like "fr" (lower case) and "en-US" (lower-upper), are
474 // allowed. See the text file for details.
475 EXPECT_TRUE(language_code.length() == 2 ||
476 (language_code.length() == 5 && language_code[2] == '-'))
477 << "Invalid language code " << language_code;
478 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax(language_code))
479 << "Invalid language code " << language_code;
480 EXPECT_FALSE(display_name.empty())
481 << "Invalid language code " << language_code;
482 // On error, GetDisplayNameForLocale() returns the |language_code| as-is.
483 EXPECT_NE(language_code, base::UTF16ToUTF8(display_name))
484 << "Invalid language code " << language_code;
488 } // namespace input_method
489 } // namespace chromeos