|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "build/build_config.h" | 
|  |  | 
|  | #if defined(OS_POSIX) && !defined(OS_MACOSX) | 
|  | #include <cstdlib> | 
|  | #endif | 
|  |  | 
|  | #include "base/basictypes.h" | 
|  | #include "base/environment.h" | 
|  | #include "base/files/file_util.h" | 
|  | #include "base/i18n/case_conversion.h" | 
|  | #include "base/i18n/rtl.h" | 
|  | #include "base/path_service.h" | 
|  | #include "base/stl_util.h" | 
|  | #include "base/strings/string_util.h" | 
|  | #include "base/strings/utf_string_conversions.h" | 
|  | #include "base/test/scoped_path_override.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  | #include "testing/platform_test.h" | 
|  | #include "third_party/icu/source/common/unicode/locid.h" | 
|  | #include "ui/base/l10n/l10n_util.h" | 
|  | #include "ui/base/l10n/l10n_util_collator.h" | 
|  | #include "ui/base/ui_base_paths.h" | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | #include "base/win/windows_version.h" | 
|  | #endif | 
|  |  | 
|  | #if !defined(OS_MACOSX) | 
|  | #include "ui/base/test/data/resource.h" | 
|  | #endif | 
|  |  | 
|  | using base::ASCIIToUTF16; | 
|  | using base::UTF8ToUTF16; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | class StringWrapper { | 
|  | public: | 
|  | explicit StringWrapper(const base::string16& string) : string_(string) {} | 
|  | const base::string16& string() const { return string_; } | 
|  |  | 
|  | private: | 
|  | base::string16 string_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(StringWrapper); | 
|  | }; | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | class L10nUtilTest : public PlatformTest { | 
|  | }; | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | // TODO(beng): disabled until app strings move to app. | 
|  | TEST_F(L10nUtilTest, DISABLED_GetString) { | 
|  | std::string s = l10n_util::GetStringUTF8(IDS_SIMPLE); | 
|  | EXPECT_EQ(std::string("Hello World!"), s); | 
|  |  | 
|  | s = l10n_util::GetStringFUTF8(IDS_PLACEHOLDERS, | 
|  | UTF8ToUTF16("chrome"), | 
|  | UTF8ToUTF16("10")); | 
|  | EXPECT_EQ(std::string("Hello, chrome. Your number is 10."), s); | 
|  |  | 
|  | base::string16 s16 = l10n_util::GetStringFUTF16Int(IDS_PLACEHOLDERS_2, 20); | 
|  | EXPECT_EQ(UTF8ToUTF16("You owe me $20."), s16); | 
|  | } | 
|  | #endif  // defined(OS_WIN) | 
|  |  | 
|  | #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | 
|  | // On Mac, we are disabling this test because GetApplicationLocale() as an | 
|  | // API isn't something that we'll easily be able to unit test in this manner. | 
|  | // The meaning of that API, on the Mac, is "the locale used by Cocoa's main | 
|  | // nib file", which clearly can't be stubbed by a test app that doesn't use | 
|  | // Cocoa. | 
|  |  | 
|  | // On Android, we are disabling this test since GetApplicationLocale() just | 
|  | // returns the system's locale, which, similarly, is not easily unit tested. | 
|  |  | 
|  | #if defined(OS_POSIX) && defined(USE_GLIB) && !defined(OS_CHROMEOS) | 
|  | const bool kPlatformHasDefaultLocale = 1; | 
|  | const bool kUseLocaleFromEnvironment = 1; | 
|  | const bool kSupportsLocalePreference = 0; | 
|  | #elif defined(OS_WIN) | 
|  | const bool kPlatformHasDefaultLocale = 1; | 
|  | const bool kUseLocaleFromEnvironment = 0; | 
|  | const bool kSupportsLocalePreference = 1; | 
|  | #else | 
|  | const bool kPlatformHasDefaultLocale = 0; | 
|  | const bool kUseLocaleFromEnvironment = 0; | 
|  | const bool kSupportsLocalePreference = 1; | 
|  | #endif | 
|  |  | 
|  | void SetDefaultLocaleForTest(const std::string& tag, base::Environment* env) { | 
|  | if (kUseLocaleFromEnvironment) | 
|  | env->SetVar("LANGUAGE", tag); | 
|  | else | 
|  | base::i18n::SetICUDefaultLocale(tag); | 
|  | } | 
|  |  | 
|  | TEST_F(L10nUtilTest, GetAppLocale) { | 
|  | scoped_ptr<base::Environment> env; | 
|  | // Use a temporary locale dir so we don't have to actually build the locale | 
|  | // pak files for this test. | 
|  | base::ScopedPathOverride locale_dir_override(ui::DIR_LOCALES); | 
|  | base::FilePath new_locale_dir; | 
|  | ASSERT_TRUE(PathService::Get(ui::DIR_LOCALES, &new_locale_dir)); | 
|  | // Make fake locale files. | 
|  | std::string filenames[] = { | 
|  | "en-US", | 
|  | "en-GB", | 
|  | "fr", | 
|  | "es-419", | 
|  | "es", | 
|  | "zh-TW", | 
|  | "zh-CN", | 
|  | "he", | 
|  | "fil", | 
|  | "nb", | 
|  | "am", | 
|  | "ca", | 
|  | "ca@valencia", | 
|  | }; | 
|  |  | 
|  | for (size_t i = 0; i < arraysize(filenames); ++i) { | 
|  | base::FilePath filename = new_locale_dir.AppendASCII( | 
|  | filenames[i] + ".pak"); | 
|  | base::WriteFile(filename, "", 0); | 
|  | } | 
|  |  | 
|  | // Keep a copy of ICU's default locale before we overwrite it. | 
|  | const std::string original_locale = base::i18n::GetConfiguredLocale(); | 
|  |  | 
|  | if (kPlatformHasDefaultLocale && kUseLocaleFromEnvironment) { | 
|  | env.reset(base::Environment::Create()); | 
|  |  | 
|  | // Test the support of LANGUAGE environment variable. | 
|  | base::i18n::SetICUDefaultLocale("en-US"); | 
|  | env->SetVar("LANGUAGE", "xx:fr_CA"); | 
|  | EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | env->SetVar("LANGUAGE", "xx:yy:en_gb.utf-8@quot"); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | env->SetVar("LANGUAGE", "xx:zh-hk"); | 
|  | EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | // We emulate gettext's behavior here, which ignores LANG/LC_MESSAGES/LC_ALL | 
|  | // when LANGUAGE is specified. If no language specified in LANGUAGE is | 
|  | // valid, | 
|  | // then just fallback to the default language, which is en-US for us. | 
|  | base::i18n::SetICUDefaultLocale("fr-FR"); | 
|  | env->SetVar("LANGUAGE", "xx:yy"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | env->SetVar("LANGUAGE", "/fr:zh_CN"); | 
|  | EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | // Test prioritization of the different environment variables. | 
|  | env->SetVar("LANGUAGE", "fr"); | 
|  | env->SetVar("LC_ALL", "es"); | 
|  | env->SetVar("LC_MESSAGES", "he"); | 
|  | env->SetVar("LANG", "nb"); | 
|  | EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | 
|  | env->UnSetVar("LANGUAGE"); | 
|  | EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  | env->UnSetVar("LC_ALL"); | 
|  | EXPECT_EQ("he", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); | 
|  | env->UnSetVar("LC_MESSAGES"); | 
|  | EXPECT_EQ("nb", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("nb", icu::Locale::getDefault().getLanguage()); | 
|  | env->UnSetVar("LANG"); | 
|  |  | 
|  | SetDefaultLocaleForTest("ca", env.get()); | 
|  | EXPECT_EQ("ca", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("ca-ES", env.get()); | 
|  | EXPECT_EQ("ca", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("ca@valencia", env.get()); | 
|  | EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("ca_ES@valencia", env.get()); | 
|  | EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("ca_ES.UTF8@valencia", env.get()); | 
|  | EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | 
|  | } | 
|  |  | 
|  | SetDefaultLocaleForTest("en-US", env.get()); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("xx", env.get()); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | if (!kPlatformHasDefaultLocale) { | 
|  | // ChromeOS & embedded use only browser prefs in GetApplicationLocale(), | 
|  | // ignoring the environment, and default to en-US. Other platforms honor | 
|  | // the default locale from the OS or environment. | 
|  | SetDefaultLocaleForTest("en-GB", env.get()); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-US", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-GB")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-US", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-AU")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-US", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-NZ")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-US", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-CA")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-US", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-ZA")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  | } else { | 
|  | // Most platforms have an OS-provided locale. This locale is preferred. | 
|  | SetDefaultLocaleForTest("en-GB", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("fr-CA", env.get()); | 
|  | EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("es-MX", env.get()); | 
|  | EXPECT_EQ("es-419", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("es-AR", env.get()); | 
|  | EXPECT_EQ("es-419", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("es-ES", env.get()); | 
|  | EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("es", env.get()); | 
|  | EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("zh-HK", env.get()); | 
|  | EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("zh-MO", env.get()); | 
|  | EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("zh-SG", env.get()); | 
|  | EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-CA", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-AU", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-NZ", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | SetDefaultLocaleForTest("en-ZA", env.get()); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  | } | 
|  |  | 
|  | SetDefaultLocaleForTest("en-US", env.get()); | 
|  |  | 
|  | if (kSupportsLocalePreference) { | 
|  | // On windows, the user can override the locale in preferences. | 
|  | base::i18n::SetICUDefaultLocale("en-US"); | 
|  | EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr")); | 
|  | EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | 
|  | EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr-CA")); | 
|  | EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("en-US"); | 
|  | // Aliases iw, no, tl to he, nb, fil. | 
|  | EXPECT_EQ("he", l10n_util::GetApplicationLocale("iw")); | 
|  | EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); | 
|  | EXPECT_EQ("nb", l10n_util::GetApplicationLocale("no")); | 
|  | EXPECT_STREQ("nb", icu::Locale::getDefault().getLanguage()); | 
|  | EXPECT_EQ("fil", l10n_util::GetApplicationLocale("tl")); | 
|  | EXPECT_STREQ("fil", icu::Locale::getDefault().getLanguage()); | 
|  | // es-419 and es-XX (where XX is not Spain) should be | 
|  | // mapped to es-419 (Latin American Spanish). | 
|  | EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("es-419")); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  | EXPECT_EQ("es", l10n_util::GetApplicationLocale("es-ES")); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  | EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("es-AR")); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("es-AR"); | 
|  | EXPECT_EQ("es", l10n_util::GetApplicationLocale("es")); | 
|  | EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("zh-HK"); | 
|  | EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale("zh-CN")); | 
|  | EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("he"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("he"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en", false)); | 
|  | EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("de"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("xx", false)); | 
|  | EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("de"); | 
|  | EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr", false)); | 
|  | EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("de"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en", false)); | 
|  | EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("de"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en-US", true)); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  | } else { | 
|  | base::i18n::SetICUDefaultLocale("de"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string(), false)); | 
|  | EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("de"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string(), true)); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  | } | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | // Amharic should be blocked unless OS is Vista or newer. | 
|  | if (base::win::GetVersion() < base::win::VERSION_VISTA) { | 
|  | base::i18n::SetICUDefaultLocale("am"); | 
|  | EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  | base::i18n::SetICUDefaultLocale("en-GB"); | 
|  | EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("am")); | 
|  | EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | 
|  | } else { | 
|  | base::i18n::SetICUDefaultLocale("am"); | 
|  | EXPECT_EQ("am", l10n_util::GetApplicationLocale("")); | 
|  | EXPECT_STREQ("am", icu::Locale::getDefault().getLanguage()); | 
|  | base::i18n::SetICUDefaultLocale("en-GB"); | 
|  | EXPECT_EQ("am", l10n_util::GetApplicationLocale("am")); | 
|  | EXPECT_STREQ("am", icu::Locale::getDefault().getLanguage()); | 
|  | } | 
|  | #endif  // defined(OS_WIN) | 
|  |  | 
|  | // Clean up. | 
|  | base::i18n::SetICUDefaultLocale(original_locale); | 
|  | } | 
|  | #endif  // !defined(OS_MACOSX) | 
|  |  | 
|  | TEST_F(L10nUtilTest, SortStringsUsingFunction) { | 
|  | std::vector<StringWrapper*> strings; | 
|  | strings.push_back(new StringWrapper(UTF8ToUTF16("C"))); | 
|  | strings.push_back(new StringWrapper(UTF8ToUTF16("d"))); | 
|  | strings.push_back(new StringWrapper(UTF8ToUTF16("b"))); | 
|  | strings.push_back(new StringWrapper(UTF8ToUTF16("a"))); | 
|  | l10n_util::SortStringsUsingMethod("en-US", | 
|  | &strings, | 
|  | &StringWrapper::string); | 
|  | ASSERT_TRUE(UTF8ToUTF16("a") == strings[0]->string()); | 
|  | ASSERT_TRUE(UTF8ToUTF16("b") == strings[1]->string()); | 
|  | ASSERT_TRUE(UTF8ToUTF16("C") == strings[2]->string()); | 
|  | ASSERT_TRUE(UTF8ToUTF16("d") == strings[3]->string()); | 
|  | STLDeleteElements(&strings); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper method for validating strings that require direcitonal markup. | 
|  | * Checks that parentheses are enclosed in appropriate direcitonal markers. | 
|  | */ | 
|  | void CheckUiDisplayNameForLocale(const std::string& locale, | 
|  | const std::string& display_locale, | 
|  | bool is_rtl) { | 
|  | EXPECT_EQ(true, base::i18n::IsRTL()); | 
|  | base::string16 result = l10n_util::GetDisplayNameForLocale(locale, | 
|  | display_locale, | 
|  | /* is_for_ui */ true); | 
|  |  | 
|  | bool rtl_direction = true; | 
|  | for (size_t i = 0; i < result.length() - 1; i++) { | 
|  | base::char16 ch = result.at(i); | 
|  | switch (ch) { | 
|  | case base::i18n::kLeftToRightMark: | 
|  | case base::i18n::kLeftToRightEmbeddingMark: | 
|  | rtl_direction = false; | 
|  | break; | 
|  | case base::i18n::kRightToLeftMark: | 
|  | case base::i18n::kRightToLeftEmbeddingMark: | 
|  | rtl_direction = true; | 
|  | break; | 
|  | case '(': | 
|  | case ')': | 
|  | EXPECT_EQ(is_rtl, rtl_direction); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST_F(L10nUtilTest, GetDisplayNameForLocale) { | 
|  | // TODO(jungshik): Make this test more extensive. | 
|  | // Test zh-CN and zh-TW are treated as zh-Hans and zh-Hant. | 
|  | base::string16 result = | 
|  | l10n_util::GetDisplayNameForLocale("zh-CN", "en", false); | 
|  | EXPECT_EQ(ASCIIToUTF16("Chinese (Simplified)"), result); | 
|  |  | 
|  | result = l10n_util::GetDisplayNameForLocale("zh-TW", "en", false); | 
|  | EXPECT_EQ(ASCIIToUTF16("Chinese (Traditional)"), result); | 
|  |  | 
|  | // tl and fil are not identical to be strict, but we treat them as | 
|  | // synonyms. | 
|  | result = l10n_util::GetDisplayNameForLocale("tl", "en", false); | 
|  | EXPECT_EQ(l10n_util::GetDisplayNameForLocale("fil", "en", false), result); | 
|  |  | 
|  | result = l10n_util::GetDisplayNameForLocale("pt-BR", "en", false); | 
|  | EXPECT_EQ(ASCIIToUTF16("Portuguese (Brazil)"), result); | 
|  |  | 
|  | result = l10n_util::GetDisplayNameForLocale("es-419", "en", false); | 
|  | EXPECT_EQ(ASCIIToUTF16("Spanish (Latin America)"), result); | 
|  |  | 
|  | result = l10n_util::GetDisplayNameForLocale("-BR", "en", false); | 
|  | EXPECT_EQ(ASCIIToUTF16("Brazil"), result); | 
|  |  | 
|  | result = l10n_util::GetDisplayNameForLocale("xyz-xyz", "en", false); | 
|  | EXPECT_EQ(ASCIIToUTF16("xyz (XYZ)"), result); | 
|  |  | 
|  | // Check for directional markers when using RTL languages to ensure that | 
|  | // direction neutral characters such as parentheses are properly formatted. | 
|  |  | 
|  | // Keep a copy of ICU's default locale before we overwrite it. | 
|  | const std::string original_locale = base::i18n::GetConfiguredLocale(); | 
|  |  | 
|  | base::i18n::SetICUDefaultLocale("he"); | 
|  | CheckUiDisplayNameForLocale("en-US", "en", false); | 
|  | CheckUiDisplayNameForLocale("en-US", "he", true); | 
|  |  | 
|  | // Clean up. | 
|  | base::i18n::SetICUDefaultLocale(original_locale); | 
|  |  | 
|  | // ToUpper and ToLower should work with embedded NULLs. | 
|  | const size_t length_with_null = 4; | 
|  | base::char16 buf_with_null[length_with_null] = { 0, 'a', 0, 'b' }; | 
|  | base::string16 string16_with_null(buf_with_null, length_with_null); | 
|  |  | 
|  | base::string16 upper_with_null = base::i18n::ToUpper(string16_with_null); | 
|  | ASSERT_EQ(length_with_null, upper_with_null.size()); | 
|  | EXPECT_TRUE(upper_with_null[0] == 0 && upper_with_null[1] == 'A' && | 
|  | upper_with_null[2] == 0 && upper_with_null[3] == 'B'); | 
|  |  | 
|  | base::string16 lower_with_null = base::i18n::ToLower(upper_with_null); | 
|  | ASSERT_EQ(length_with_null, upper_with_null.size()); | 
|  | EXPECT_TRUE(lower_with_null[0] == 0 && lower_with_null[1] == 'a' && | 
|  | lower_with_null[2] == 0 && lower_with_null[3] == 'b'); | 
|  | } | 
|  |  | 
|  | TEST_F(L10nUtilTest, GetDisplayNameForCountry) { | 
|  | base::string16 result = l10n_util::GetDisplayNameForCountry("BR", "en"); | 
|  | EXPECT_EQ(ASCIIToUTF16("Brazil"), result); | 
|  |  | 
|  | result = l10n_util::GetDisplayNameForCountry("419", "en"); | 
|  | EXPECT_EQ(ASCIIToUTF16("Latin America"), result); | 
|  |  | 
|  | result = l10n_util::GetDisplayNameForCountry("xyz", "en"); | 
|  | EXPECT_EQ(ASCIIToUTF16("XYZ"), result); | 
|  | } | 
|  |  | 
|  | TEST_F(L10nUtilTest, GetParentLocales) { | 
|  | std::vector<std::string> locales; | 
|  | const std::string top_locale("sr_Cyrl_RS"); | 
|  | l10n_util::GetParentLocales(top_locale, &locales); | 
|  |  | 
|  | ASSERT_EQ(3U, locales.size()); | 
|  | EXPECT_EQ("sr_Cyrl_RS", locales[0]); | 
|  | EXPECT_EQ("sr_Cyrl", locales[1]); | 
|  | EXPECT_EQ("sr", locales[2]); | 
|  | } | 
|  |  | 
|  | TEST_F(L10nUtilTest, IsValidLocaleSyntax) { | 
|  | // Test valid locales. | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("de")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("pt")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fil")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("haw")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en-US")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_US")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_GB")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("pt-BR")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_CN")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hans")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hans_CN")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hant")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hant_TW")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr_CA")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("i-klingon")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("es-419")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE_PREEURO")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE_u_cu_IEP")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE@currency=IEP")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr@x=y")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zn_CN@foo=bar")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax( | 
|  | "fr@collation=phonebook;calendar=islamic-civil")); | 
|  | EXPECT_TRUE(l10n_util::IsValidLocaleSyntax( | 
|  | "sr_Latn_RS_REVISED@currency=USD")); | 
|  |  | 
|  | // Test invalid locales. | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax(std::string())); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("x")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("12")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("456")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("a1")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("enUS")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("zhcn")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en.US")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en#US")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("-en-US")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US-")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("123-en-US")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("Latin")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("German")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("pt--BR")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("sl-macedonia")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("@")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@x")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@x=")); | 
|  | EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@=y")); | 
|  | } |