Home | History | Annotate | Download | only in input_method
      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.
      4 
      5 #include "chrome/browser/chromeos/input_method/input_method_util.h"
      6 
      7 #include <string>
      8 
      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"
     18 
     19 namespace chromeos {
     20 
     21 extern const char* kExtensionImePrefix;
     22 
     23 namespace input_method {
     24 
     25 namespace {
     26 
     27 const char pinyin_ime_id[] =
     28     "_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabzh-t-i0-pinyin";
     29 const char zhuyin_ime_id[] =
     30     "_comp_ime_goedamlknlnjaengojinmfgpmdjmkooozh-hant-t-i0-und";
     31 
     32 class TestableInputMethodUtil : public InputMethodUtil {
     33  public:
     34   explicit TestableInputMethodUtil(InputMethodDelegate* delegate,
     35                                    scoped_ptr<InputMethodDescriptors> methods)
     36       : InputMethodUtil(delegate, methods.Pass()) {
     37   }
     38   // Change access rights.
     39   using InputMethodUtil::GetInputMethodIdsFromLanguageCodeInternal;
     40   using InputMethodUtil::GetKeyboardLayoutName;
     41   using InputMethodUtil::ReloadInternalMaps;
     42   using InputMethodUtil::supported_input_methods_;
     43 };
     44 
     45 }  // namespace
     46 
     47 class InputMethodUtilTest : public testing::Test {
     48  public:
     49   InputMethodUtilTest()
     50       : util_(&delegate_, whitelist_.GetSupportedInputMethods()) {
     51     delegate_.set_get_localized_string_callback(
     52         base::Bind(&l10n_util::GetStringUTF16));
     53     delegate_.set_get_display_language_name_callback(
     54         base::Bind(&InputMethodUtilTest::GetDisplayLanguageName));
     55   }
     56 
     57   virtual void SetUp() OVERRIDE {
     58     InputMethodDescriptors input_methods;
     59 
     60     std::vector<std::string> layouts;
     61     std::vector<std::string> languages;
     62     layouts.push_back("us");
     63     languages.push_back("zh-CN");
     64 
     65     InputMethodDescriptor pinyin_ime(pinyin_ime_id,
     66                                      "Pinyin input for testing",
     67                                      layouts,
     68                                      languages,
     69                                      GURL(""));
     70     input_methods.push_back(pinyin_ime);
     71 
     72     languages.clear();
     73     languages.push_back("zh-TW");
     74     InputMethodDescriptor zhuyin_ime(zhuyin_ime_id,
     75                                      "Zhuyin input for testing",
     76                                      layouts,
     77                                      languages,
     78                                      GURL(""));
     79     input_methods.push_back(zhuyin_ime);
     80 
     81     util_.SetComponentExtensions(input_methods);
     82   }
     83 
     84   InputMethodDescriptor GetDesc(const std::string& id,
     85                                 const std::string& raw_layout,
     86                                 const std::string& language_code) {
     87     std::vector<std::string> layouts;
     88     layouts.push_back(raw_layout);
     89     std::vector<std::string> languages;
     90     languages.push_back(language_code);
     91     return InputMethodDescriptor(id,
     92                                  "",
     93                                  layouts,
     94                                  languages,
     95                                  GURL());  // options page url
     96   }
     97 
     98   static string16 GetDisplayLanguageName(const std::string& language_code) {
     99     return l10n_util::GetDisplayNameForLocale(language_code, "en", true);
    100   }
    101 
    102   FakeInputMethodDelegate delegate_;
    103   InputMethodWhitelist whitelist_;
    104   TestableInputMethodUtil util_;
    105 };
    106 
    107 TEST_F(InputMethodUtilTest, GetInputMethodShortNameTest) {
    108   // Test normal cases. Two-letter language code should be returned.
    109   {
    110     InputMethodDescriptor desc = GetDesc("m17n:fa:isiri",  // input method id
    111                                          "us",  // keyboard layout name
    112                                          "fa");  // language name
    113     EXPECT_EQ(ASCIIToUTF16("FA"), util_.GetInputMethodShortName(desc));
    114   }
    115   {
    116     InputMethodDescriptor desc = GetDesc("mozc-hangul", "us", "ko");
    117     EXPECT_EQ(UTF8ToUTF16("\xed\x95\x9c"),
    118               util_.GetInputMethodShortName(desc));
    119   }
    120   {
    121     InputMethodDescriptor desc = GetDesc("invalid-id", "us", "xx");
    122     // Upper-case string of the unknown language code, "xx", should be returned.
    123     EXPECT_EQ(ASCIIToUTF16("XX"), util_.GetInputMethodShortName(desc));
    124   }
    125 
    126   // Test special cases.
    127   {
    128     InputMethodDescriptor desc = GetDesc("xkb:us:dvorak:eng", "us", "en-US");
    129     EXPECT_EQ(ASCIIToUTF16("DV"), util_.GetInputMethodShortName(desc));
    130   }
    131   {
    132     InputMethodDescriptor desc = GetDesc("xkb:us:colemak:eng", "us", "en-US");
    133     EXPECT_EQ(ASCIIToUTF16("CO"), util_.GetInputMethodShortName(desc));
    134   }
    135   {
    136     InputMethodDescriptor desc =
    137         GetDesc("xkb:us:altgr-intl:eng", "us", "en-US");
    138     EXPECT_EQ(ASCIIToUTF16("EXTD"), util_.GetInputMethodShortName(desc));
    139   }
    140   {
    141     InputMethodDescriptor desc = GetDesc("xkb:us:intl:eng", "us", "en-US");
    142     EXPECT_EQ(ASCIIToUTF16("INTL"), util_.GetInputMethodShortName(desc));
    143   }
    144   {
    145     InputMethodDescriptor desc = GetDesc("xkb:de:neo:ger", "de(neo)", "de");
    146     EXPECT_EQ(ASCIIToUTF16("NEO"), util_.GetInputMethodShortName(desc));
    147   }
    148   {
    149     InputMethodDescriptor desc = GetDesc("xkb:es:cat:cat", "es(cat)", "ca");
    150     EXPECT_EQ(ASCIIToUTF16("CAS"), util_.GetInputMethodShortName(desc));
    151   }
    152   {
    153     InputMethodDescriptor desc = GetDesc(pinyin_ime_id, "us", "zh-CN");
    154     EXPECT_EQ(UTF8ToUTF16("\xe6\x8b\xbc"),
    155               util_.GetInputMethodShortName(desc));
    156   }
    157   {
    158     InputMethodDescriptor desc = GetDesc(zhuyin_ime_id, "us", "zh-TW");
    159     EXPECT_EQ(UTF8ToUTF16("\xe9\x85\xb7"),
    160               util_.GetInputMethodShortName(desc));
    161   }
    162   {
    163     InputMethodDescriptor desc = GetDesc("m17n:zh:cangjie", "us", "zh-TW");
    164     EXPECT_EQ(UTF8ToUTF16("\xe5\x80\x89"),
    165               util_.GetInputMethodShortName(desc));
    166   }
    167   {
    168     InputMethodDescriptor desc = GetDesc("m17n:zh:quick", "us", "zh-TW");
    169     EXPECT_EQ(UTF8ToUTF16("\xe9\x80\x9f"),
    170               util_.GetInputMethodShortName(desc));
    171   }
    172 }
    173 
    174 TEST_F(InputMethodUtilTest, GetInputMethodMediumNameTest) {
    175   {
    176     // input methods with medium name equal to short name
    177     const char * input_method_id[] = {
    178       "xkb:us:altgr-intl:eng",
    179       "xkb:us:dvorak:eng",
    180       "xkb:us:intl:eng",
    181       "xkb:us:colemak:eng",
    182       "english-m",
    183       "xkb:de:neo:ger",
    184       "xkb:es:cat:cat",
    185       "xkb:gb:dvorak:eng",
    186     };
    187     const int len = ARRAYSIZE_UNSAFE(input_method_id);
    188     for (int i=0; i<len; ++i) {
    189       InputMethodDescriptor desc = GetDesc(input_method_id[i], "", "");
    190       string16 medium_name = util_.GetInputMethodMediumName(desc);
    191       string16 short_name = util_.GetInputMethodShortName(desc);
    192       EXPECT_EQ(medium_name,short_name);
    193     }
    194   }
    195   {
    196     // input methods with medium name not equal to short name
    197     const char * input_method_id[] = {
    198       "m17n:zh:cangjie",
    199       "m17n:zh:quick",
    200       pinyin_ime_id,
    201       zhuyin_ime_id,
    202       "mozc-hangul",
    203       pinyin_ime_id,
    204       pinyin_ime_id,
    205     };
    206     const int len = ARRAYSIZE_UNSAFE(input_method_id);
    207     for (int i=0; i<len; ++i) {
    208       InputMethodDescriptor desc = GetDesc(input_method_id[i], "", "");
    209       string16 medium_name = util_.GetInputMethodMediumName(desc);
    210       string16 short_name = util_.GetInputMethodShortName(desc);
    211       EXPECT_NE(medium_name,short_name);
    212     }
    213   }
    214 }
    215 
    216 TEST_F(InputMethodUtilTest, GetInputMethodLongNameTest) {
    217   // For most languages input method or keyboard layout name is returned.
    218   // See below for exceptions.
    219   {
    220     InputMethodDescriptor desc = GetDesc("m17n:fa:isiri", "us", "fa");
    221     EXPECT_EQ(ASCIIToUTF16("Persian input method (ISIRI 2901 layout)"),
    222               util_.GetInputMethodLongName(desc));
    223   }
    224   {
    225     InputMethodDescriptor desc = GetDesc("mozc-hangul", "us", "ko");
    226     EXPECT_EQ(ASCIIToUTF16("Korean input method"),
    227               util_.GetInputMethodLongName(desc));
    228   }
    229   {
    230     InputMethodDescriptor desc = GetDesc("m17n:vi:tcvn", "us", "vi");
    231     EXPECT_EQ(ASCIIToUTF16("Vietnamese input method (TCVN6064)"),
    232               util_.GetInputMethodLongName(desc));
    233   }
    234   {
    235     InputMethodDescriptor desc = GetDesc("xkb:jp::jpn", "jp", "ja");
    236     EXPECT_EQ(ASCIIToUTF16("Japanese keyboard"),
    237               util_.GetInputMethodLongName(desc));
    238   }
    239   {
    240     InputMethodDescriptor desc =
    241         GetDesc("xkb:us:dvorak:eng", "us(dvorak)", "en-US");
    242     EXPECT_EQ(ASCIIToUTF16("US Dvorak keyboard"),
    243               util_.GetInputMethodLongName(desc));
    244   }
    245   {
    246     InputMethodDescriptor desc =
    247         GetDesc("xkb:gb:dvorak:eng", "gb(dvorak)", "en-US");
    248     EXPECT_EQ(ASCIIToUTF16("UK Dvorak keyboard"),
    249               util_.GetInputMethodLongName(desc));
    250   }
    251 
    252   // For Arabic, Dutch, French, German and Hindi,
    253   // "language - keyboard layout" pair is returned.
    254   {
    255     InputMethodDescriptor desc = GetDesc("m17n:ar:kbd", "us", "ar");
    256     EXPECT_EQ(ASCIIToUTF16("Arabic - Standard input method"),
    257               util_.GetInputMethodLongName(desc));
    258   }
    259   {
    260     InputMethodDescriptor desc = GetDesc("xkb:be::nld", "be", "nl");
    261     EXPECT_EQ(ASCIIToUTF16("Dutch - Belgian keyboard"),
    262               util_.GetInputMethodLongName(desc));
    263   }
    264   {
    265     InputMethodDescriptor desc = GetDesc("xkb:fr::fra", "fr", "fr");
    266     EXPECT_EQ(ASCIIToUTF16("French - French keyboard"),
    267               util_.GetInputMethodLongName(desc));
    268   }
    269   {
    270     InputMethodDescriptor desc = GetDesc("xkb:be::fra", "be", "fr");
    271     EXPECT_EQ(ASCIIToUTF16("French - Belgian keyboard"),
    272               util_.GetInputMethodLongName(desc));
    273   }
    274   {
    275     InputMethodDescriptor desc = GetDesc("xkb:de::ger", "de", "de");
    276     EXPECT_EQ(ASCIIToUTF16("German - German keyboard"),
    277               util_.GetInputMethodLongName(desc));
    278   }
    279   {
    280     InputMethodDescriptor desc = GetDesc("xkb:be::ger", "be", "de");
    281     EXPECT_EQ(ASCIIToUTF16("German - Belgian keyboard"),
    282               util_.GetInputMethodLongName(desc));
    283   }
    284   {
    285     InputMethodDescriptor desc = GetDesc("m17n:hi:itrans", "us", "hi");
    286     EXPECT_EQ(ASCIIToUTF16("Hindi - Standard input method"),
    287               util_.GetInputMethodLongName(desc));
    288   }
    289 
    290   {
    291     InputMethodDescriptor desc = GetDesc("invalid-id", "us", "xx");
    292     // You can safely ignore the "Resouce ID is not found for: invalid-id"
    293     // error.
    294     EXPECT_EQ(ASCIIToUTF16("invalid-id"),
    295               util_.GetInputMethodLongName(desc));
    296   }
    297 }
    298 
    299 TEST_F(InputMethodUtilTest, TestIsValidInputMethodId) {
    300   EXPECT_TRUE(util_.IsValidInputMethodId("xkb:us:colemak:eng"));
    301   EXPECT_TRUE(util_.IsValidInputMethodId(pinyin_ime_id));
    302   EXPECT_FALSE(util_.IsValidInputMethodId("unsupported-input-method"));
    303 }
    304 
    305 TEST_F(InputMethodUtilTest, TestIsKeyboardLayout) {
    306   EXPECT_TRUE(InputMethodUtil::IsKeyboardLayout("xkb:us::eng"));
    307   EXPECT_FALSE(InputMethodUtil::IsKeyboardLayout(pinyin_ime_id));
    308 }
    309 
    310 TEST_F(InputMethodUtilTest, TestGetKeyboardLayoutName) {
    311   // Unsupported case.
    312   EXPECT_EQ("", util_.GetKeyboardLayoutName("UNSUPPORTED_ID"));
    313 
    314   // Supported cases (samples).
    315   EXPECT_EQ("us", util_.GetKeyboardLayoutName(pinyin_ime_id));
    316   EXPECT_EQ("es", util_.GetKeyboardLayoutName("xkb:es::spa"));
    317   EXPECT_EQ("es(cat)", util_.GetKeyboardLayoutName("xkb:es:cat:cat"));
    318   EXPECT_EQ("gb(extd)", util_.GetKeyboardLayoutName("xkb:gb:extd:eng"));
    319   EXPECT_EQ("us", util_.GetKeyboardLayoutName("xkb:us::eng"));
    320   EXPECT_EQ("us(dvorak)", util_.GetKeyboardLayoutName("xkb:us:dvorak:eng"));
    321   EXPECT_EQ("us(colemak)", util_.GetKeyboardLayoutName("xkb:us:colemak:eng"));
    322   EXPECT_EQ("de(neo)", util_.GetKeyboardLayoutName("xkb:de:neo:ger"));
    323 }
    324 
    325 TEST_F(InputMethodUtilTest, TestGetLanguageCodeFromInputMethodId) {
    326   // Make sure that the -CN is added properly.
    327   EXPECT_EQ("zh-CN", util_.GetLanguageCodeFromInputMethodId(pinyin_ime_id));
    328 }
    329 
    330 TEST_F(InputMethodUtilTest, TestGetInputMethodDisplayNameFromId) {
    331   EXPECT_EQ("US keyboard",
    332             util_.GetInputMethodDisplayNameFromId("xkb:us::eng"));
    333   EXPECT_EQ("", util_.GetInputMethodDisplayNameFromId("nonexistent"));
    334 }
    335 
    336 TEST_F(InputMethodUtilTest, TestGetInputMethodDescriptorFromId) {
    337   EXPECT_EQ(NULL, util_.GetInputMethodDescriptorFromId("non_existent"));
    338 
    339   const InputMethodDescriptor* descriptor =
    340       util_.GetInputMethodDescriptorFromId(pinyin_ime_id);
    341   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    342   EXPECT_EQ(pinyin_ime_id, descriptor->id());
    343   EXPECT_EQ("us", descriptor->GetPreferredKeyboardLayout());
    344   // This used to be "zh" but now we have "zh-CN" in input_methods.h,
    345   // hence this should be zh-CN now.
    346   ASSERT_TRUE(!descriptor->language_codes().empty());
    347   EXPECT_EQ("zh-CN", descriptor->language_codes().at(0));
    348 }
    349 
    350 TEST_F(InputMethodUtilTest, TestGetInputMethodIdsForLanguageCode) {
    351   std::multimap<std::string, std::string> language_code_to_ids_map;
    352   language_code_to_ids_map.insert(std::make_pair("ja", pinyin_ime_id));
    353   language_code_to_ids_map.insert(std::make_pair("ja", pinyin_ime_id));
    354   language_code_to_ids_map.insert(std::make_pair("ja", "xkb:jp:jpn"));
    355   language_code_to_ids_map.insert(std::make_pair("fr", "xkb:fr:fra"));
    356 
    357   std::vector<std::string> result;
    358   EXPECT_TRUE(util_.GetInputMethodIdsFromLanguageCodeInternal(
    359       language_code_to_ids_map, "ja", kAllInputMethods, &result));
    360   EXPECT_EQ(3U, result.size());
    361   EXPECT_TRUE(util_.GetInputMethodIdsFromLanguageCodeInternal(
    362       language_code_to_ids_map, "ja", kKeyboardLayoutsOnly, &result));
    363   ASSERT_EQ(1U, result.size());
    364   EXPECT_EQ("xkb:jp:jpn", result[0]);
    365 
    366   EXPECT_TRUE(util_.GetInputMethodIdsFromLanguageCodeInternal(
    367       language_code_to_ids_map, "fr", kAllInputMethods, &result));
    368   ASSERT_EQ(1U, result.size());
    369   EXPECT_EQ("xkb:fr:fra", result[0]);
    370   EXPECT_TRUE(util_.GetInputMethodIdsFromLanguageCodeInternal(
    371       language_code_to_ids_map, "fr", kKeyboardLayoutsOnly, &result));
    372   ASSERT_EQ(1U, result.size());
    373   EXPECT_EQ("xkb:fr:fra", result[0]);
    374 
    375   EXPECT_FALSE(util_.GetInputMethodIdsFromLanguageCodeInternal(
    376       language_code_to_ids_map, "invalid_lang", kAllInputMethods, &result));
    377   EXPECT_FALSE(util_.GetInputMethodIdsFromLanguageCodeInternal(
    378       language_code_to_ids_map, "invalid_lang", kKeyboardLayoutsOnly, &result));
    379 }
    380 
    381 // US keyboard + English US UI = US keyboard only.
    382 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_EnUs) {
    383   const InputMethodDescriptor* descriptor =
    384       util_.GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    385   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    386   std::vector<std::string> input_method_ids;
    387   util_.GetFirstLoginInputMethodIds("en-US", *descriptor, &input_method_ids);
    388   ASSERT_EQ(1U, input_method_ids.size());
    389   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    390 }
    391 
    392 // US keyboard + Chinese UI = US keyboard + Pinyin IME.
    393 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Zh) {
    394   const InputMethodDescriptor* descriptor =
    395       util_.GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    396   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    397   std::vector<std::string> input_method_ids;
    398   util_.GetFirstLoginInputMethodIds("zh-CN", *descriptor, &input_method_ids);
    399   ASSERT_EQ(2U, input_method_ids.size());
    400   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    401   EXPECT_EQ(pinyin_ime_id, input_method_ids[1]);  // Pinyin for US keybaord.
    402 }
    403 
    404 // US keyboard + Russian UI = US keyboard + Russsian keyboard
    405 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Ru) {
    406   const InputMethodDescriptor* descriptor =
    407       util_.GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    408   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    409   std::vector<std::string> input_method_ids;
    410   util_.GetFirstLoginInputMethodIds("ru", *descriptor, &input_method_ids);
    411   ASSERT_EQ(2U, input_method_ids.size());
    412   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    413   EXPECT_EQ("xkb:ru::rus", input_method_ids[1]);  // Russian keyboard.
    414 }
    415 
    416 // US keyboard + Traditional Chinese = US keyboard + chewing.
    417 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_ZhTw) {
    418   const InputMethodDescriptor* descriptor =
    419       util_.GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    420   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    421   std::vector<std::string> input_method_ids;
    422   util_.GetFirstLoginInputMethodIds("zh-TW", *descriptor, &input_method_ids);
    423   ASSERT_EQ(2U, input_method_ids.size());
    424   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    425   EXPECT_EQ(zhuyin_ime_id, input_method_ids[1]);  // Chewing.
    426 }
    427 
    428 // US keyboard + Thai = US keyboard + kesmanee.
    429 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Th) {
    430   const InputMethodDescriptor* descriptor =
    431       util_.GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    432   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    433   std::vector<std::string> input_method_ids;
    434   util_.GetFirstLoginInputMethodIds("th", *descriptor, &input_method_ids);
    435   ASSERT_EQ(2U, input_method_ids.size());
    436   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    437   EXPECT_EQ("_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_th",
    438             input_method_ids[1]);  // Kesmanee.
    439 }
    440 
    441 // US keyboard + Vietnamese = US keyboard + TCVN6064.
    442 TEST_F(InputMethodUtilTest, TestGetFirstLoginInputMethodIds_Us_And_Vi) {
    443   const InputMethodDescriptor* descriptor =
    444       util_.GetInputMethodDescriptorFromId("xkb:us::eng");  // US keyboard.
    445   ASSERT_TRUE(NULL != descriptor);  // ASSERT_NE doesn't compile.
    446   std::vector<std::string> input_method_ids;
    447   util_.GetFirstLoginInputMethodIds("vi", *descriptor, &input_method_ids);
    448   ASSERT_EQ(2U, input_method_ids.size());
    449   EXPECT_EQ("xkb:us::eng", input_method_ids[0]);
    450   EXPECT_EQ("_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_vi_tcvn",
    451             input_method_ids[1]);  // TCVN6064.
    452 }
    453 
    454 TEST_F(InputMethodUtilTest, TestGetLanguageCodesFromInputMethodIds) {
    455   std::vector<std::string> input_method_ids;
    456   input_method_ids.push_back("xkb:us::eng");  // English US.
    457   input_method_ids.push_back("xkb:us:dvorak:eng");  // English US Dvorak.
    458   input_method_ids.push_back(pinyin_ime_id);  // Pinyin
    459   input_method_ids.push_back("xkb:fr::fra");  // French France.
    460   std::vector<std::string> language_codes;
    461   util_.GetLanguageCodesFromInputMethodIds(input_method_ids, &language_codes);
    462   ASSERT_EQ(3U, language_codes.size());
    463   EXPECT_EQ("en-US", language_codes[0]);
    464   EXPECT_EQ("zh-CN", language_codes[1]);
    465   EXPECT_EQ("fr", language_codes[2]);
    466 }
    467 
    468 // Test all supported descriptors to detect a typo in ibus_input_methods.txt.
    469 TEST_F(InputMethodUtilTest, TestIBusInputMethodText) {
    470   for (size_t i = 0; i < util_.supported_input_methods_->size(); ++i) {
    471     const std::string language_code =
    472         util_.supported_input_methods_->at(i).language_codes().at(0);
    473     const string16 display_name =
    474         l10n_util::GetDisplayNameForLocale(language_code, "en", false);
    475     // Only two formats, like "fr" (lower case) and "en-US" (lower-upper), are
    476     // allowed. See the text file for details.
    477     EXPECT_TRUE(language_code.length() == 2 ||
    478                 (language_code.length() == 5 && language_code[2] == '-'))
    479         << "Invalid language code " << language_code;
    480     EXPECT_TRUE(l10n_util::IsValidLocaleSyntax(language_code))
    481         << "Invalid language code " << language_code;
    482     EXPECT_FALSE(display_name.empty())
    483         << "Invalid language code " << language_code;
    484     // On error, GetDisplayNameForLocale() returns the |language_code| as-is.
    485     EXPECT_NE(language_code, UTF16ToUTF8(display_name))
    486         << "Invalid language code " << language_code;
    487   }
    488 }
    489 
    490 }  // namespace input_method
    491 }  // namespace chromeos
    492