| OLD | NEW |
| (Empty) |
| 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 "build/build_config.h" | |
| 6 | |
| 7 #if defined(OS_POSIX) && !defined(OS_MACOSX) | |
| 8 #include <cstdlib> | |
| 9 #endif | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/environment.h" | |
| 13 #include "base/files/file_util.h" | |
| 14 #include "base/i18n/case_conversion.h" | |
| 15 #include "base/i18n/rtl.h" | |
| 16 #include "base/path_service.h" | |
| 17 #include "base/stl_util.h" | |
| 18 #include "base/strings/string_util.h" | |
| 19 #include "base/strings/utf_string_conversions.h" | |
| 20 #include "base/test/scoped_path_override.h" | |
| 21 #include "testing/gtest/include/gtest/gtest.h" | |
| 22 #include "testing/platform_test.h" | |
| 23 #include "third_party/icu/source/common/unicode/locid.h" | |
| 24 #include "ui/base/l10n/l10n_util.h" | |
| 25 #include "ui/base/l10n/l10n_util_collator.h" | |
| 26 #include "ui/base/ui_base_paths.h" | |
| 27 | |
| 28 #if defined(OS_WIN) | |
| 29 #include "base/win/windows_version.h" | |
| 30 #endif | |
| 31 | |
| 32 #if !defined(OS_MACOSX) | |
| 33 #include "ui/base/test/data/resource.h" | |
| 34 #endif | |
| 35 | |
| 36 using base::ASCIIToUTF16; | |
| 37 using base::UTF8ToUTF16; | |
| 38 | |
| 39 namespace { | |
| 40 | |
| 41 class StringWrapper { | |
| 42 public: | |
| 43 explicit StringWrapper(const base::string16& string) : string_(string) {} | |
| 44 const base::string16& string() const { return string_; } | |
| 45 | |
| 46 private: | |
| 47 base::string16 string_; | |
| 48 | |
| 49 DISALLOW_COPY_AND_ASSIGN(StringWrapper); | |
| 50 }; | |
| 51 | |
| 52 } // namespace | |
| 53 | |
| 54 class L10nUtilTest : public PlatformTest { | |
| 55 }; | |
| 56 | |
| 57 #if defined(OS_WIN) | |
| 58 // TODO(beng): disabled until app strings move to app. | |
| 59 TEST_F(L10nUtilTest, DISABLED_GetString) { | |
| 60 std::string s = l10n_util::GetStringUTF8(IDS_SIMPLE); | |
| 61 EXPECT_EQ(std::string("Hello World!"), s); | |
| 62 | |
| 63 s = l10n_util::GetStringFUTF8(IDS_PLACEHOLDERS, | |
| 64 UTF8ToUTF16("chrome"), | |
| 65 UTF8ToUTF16("10")); | |
| 66 EXPECT_EQ(std::string("Hello, chrome. Your number is 10."), s); | |
| 67 | |
| 68 base::string16 s16 = l10n_util::GetStringFUTF16Int(IDS_PLACEHOLDERS_2, 20); | |
| 69 EXPECT_EQ(UTF8ToUTF16("You owe me $20."), s16); | |
| 70 } | |
| 71 #endif // defined(OS_WIN) | |
| 72 | |
| 73 #if !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
| 74 // On Mac, we are disabling this test because GetApplicationLocale() as an | |
| 75 // API isn't something that we'll easily be able to unit test in this manner. | |
| 76 // The meaning of that API, on the Mac, is "the locale used by Cocoa's main | |
| 77 // nib file", which clearly can't be stubbed by a test app that doesn't use | |
| 78 // Cocoa. | |
| 79 | |
| 80 // On Android, we are disabling this test since GetApplicationLocale() just | |
| 81 // returns the system's locale, which, similarly, is not easily unit tested. | |
| 82 | |
| 83 #if defined(OS_POSIX) && defined(USE_GLIB) && !defined(OS_CHROMEOS) | |
| 84 const bool kPlatformHasDefaultLocale = 1; | |
| 85 const bool kUseLocaleFromEnvironment = 1; | |
| 86 const bool kSupportsLocalePreference = 0; | |
| 87 #elif defined(OS_WIN) | |
| 88 const bool kPlatformHasDefaultLocale = 1; | |
| 89 const bool kUseLocaleFromEnvironment = 0; | |
| 90 const bool kSupportsLocalePreference = 1; | |
| 91 #else | |
| 92 const bool kPlatformHasDefaultLocale = 0; | |
| 93 const bool kUseLocaleFromEnvironment = 0; | |
| 94 const bool kSupportsLocalePreference = 1; | |
| 95 #endif | |
| 96 | |
| 97 void SetDefaultLocaleForTest(const std::string& tag, base::Environment* env) { | |
| 98 if (kUseLocaleFromEnvironment) | |
| 99 env->SetVar("LANGUAGE", tag); | |
| 100 else | |
| 101 base::i18n::SetICUDefaultLocale(tag); | |
| 102 } | |
| 103 | |
| 104 TEST_F(L10nUtilTest, GetAppLocale) { | |
| 105 scoped_ptr<base::Environment> env; | |
| 106 // Use a temporary locale dir so we don't have to actually build the locale | |
| 107 // pak files for this test. | |
| 108 base::ScopedPathOverride locale_dir_override(ui::DIR_LOCALES); | |
| 109 base::FilePath new_locale_dir; | |
| 110 ASSERT_TRUE(PathService::Get(ui::DIR_LOCALES, &new_locale_dir)); | |
| 111 // Make fake locale files. | |
| 112 std::string filenames[] = { | |
| 113 "en-US", | |
| 114 "en-GB", | |
| 115 "fr", | |
| 116 "es-419", | |
| 117 "es", | |
| 118 "zh-TW", | |
| 119 "zh-CN", | |
| 120 "he", | |
| 121 "fil", | |
| 122 "nb", | |
| 123 "am", | |
| 124 "ca", | |
| 125 "ca@valencia", | |
| 126 }; | |
| 127 | |
| 128 for (size_t i = 0; i < arraysize(filenames); ++i) { | |
| 129 base::FilePath filename = new_locale_dir.AppendASCII( | |
| 130 filenames[i] + ".pak"); | |
| 131 base::WriteFile(filename, "", 0); | |
| 132 } | |
| 133 | |
| 134 // Keep a copy of ICU's default locale before we overwrite it. | |
| 135 const std::string original_locale = base::i18n::GetConfiguredLocale(); | |
| 136 | |
| 137 if (kPlatformHasDefaultLocale && kUseLocaleFromEnvironment) { | |
| 138 env.reset(base::Environment::Create()); | |
| 139 | |
| 140 // Test the support of LANGUAGE environment variable. | |
| 141 base::i18n::SetICUDefaultLocale("en-US"); | |
| 142 env->SetVar("LANGUAGE", "xx:fr_CA"); | |
| 143 EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); | |
| 144 EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | |
| 145 | |
| 146 env->SetVar("LANGUAGE", "xx:yy:en_gb.utf-8@quot"); | |
| 147 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | |
| 148 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 149 | |
| 150 env->SetVar("LANGUAGE", "xx:zh-hk"); | |
| 151 EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); | |
| 152 EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | |
| 153 | |
| 154 // We emulate gettext's behavior here, which ignores LANG/LC_MESSAGES/LC_ALL | |
| 155 // when LANGUAGE is specified. If no language specified in LANGUAGE is | |
| 156 // valid, | |
| 157 // then just fallback to the default language, which is en-US for us. | |
| 158 base::i18n::SetICUDefaultLocale("fr-FR"); | |
| 159 env->SetVar("LANGUAGE", "xx:yy"); | |
| 160 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); | |
| 161 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 162 | |
| 163 env->SetVar("LANGUAGE", "/fr:zh_CN"); | |
| 164 EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale(std::string())); | |
| 165 EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | |
| 166 | |
| 167 // Test prioritization of the different environment variables. | |
| 168 env->SetVar("LANGUAGE", "fr"); | |
| 169 env->SetVar("LC_ALL", "es"); | |
| 170 env->SetVar("LC_MESSAGES", "he"); | |
| 171 env->SetVar("LANG", "nb"); | |
| 172 EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); | |
| 173 EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | |
| 174 env->UnSetVar("LANGUAGE"); | |
| 175 EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); | |
| 176 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 177 env->UnSetVar("LC_ALL"); | |
| 178 EXPECT_EQ("he", l10n_util::GetApplicationLocale(std::string())); | |
| 179 EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); | |
| 180 env->UnSetVar("LC_MESSAGES"); | |
| 181 EXPECT_EQ("nb", l10n_util::GetApplicationLocale(std::string())); | |
| 182 EXPECT_STREQ("nb", icu::Locale::getDefault().getLanguage()); | |
| 183 env->UnSetVar("LANG"); | |
| 184 | |
| 185 SetDefaultLocaleForTest("ca", env.get()); | |
| 186 EXPECT_EQ("ca", l10n_util::GetApplicationLocale(std::string())); | |
| 187 EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | |
| 188 | |
| 189 SetDefaultLocaleForTest("ca-ES", env.get()); | |
| 190 EXPECT_EQ("ca", l10n_util::GetApplicationLocale(std::string())); | |
| 191 EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | |
| 192 | |
| 193 SetDefaultLocaleForTest("ca@valencia", env.get()); | |
| 194 EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); | |
| 195 EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | |
| 196 | |
| 197 SetDefaultLocaleForTest("ca_ES@valencia", env.get()); | |
| 198 EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); | |
| 199 EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | |
| 200 | |
| 201 SetDefaultLocaleForTest("ca_ES.UTF8@valencia", env.get()); | |
| 202 EXPECT_EQ("ca@valencia", l10n_util::GetApplicationLocale(std::string())); | |
| 203 EXPECT_STREQ("ca", icu::Locale::getDefault().getLanguage()); | |
| 204 } | |
| 205 | |
| 206 SetDefaultLocaleForTest("en-US", env.get()); | |
| 207 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); | |
| 208 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 209 | |
| 210 SetDefaultLocaleForTest("xx", env.get()); | |
| 211 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string())); | |
| 212 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 213 | |
| 214 if (!kPlatformHasDefaultLocale) { | |
| 215 // ChromeOS & embedded use only browser prefs in GetApplicationLocale(), | |
| 216 // ignoring the environment, and default to en-US. Other platforms honor | |
| 217 // the default locale from the OS or environment. | |
| 218 SetDefaultLocaleForTest("en-GB", env.get()); | |
| 219 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); | |
| 220 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 221 | |
| 222 SetDefaultLocaleForTest("en-US", env.get()); | |
| 223 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-GB")); | |
| 224 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 225 | |
| 226 SetDefaultLocaleForTest("en-US", env.get()); | |
| 227 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-AU")); | |
| 228 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 229 | |
| 230 SetDefaultLocaleForTest("en-US", env.get()); | |
| 231 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-NZ")); | |
| 232 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 233 | |
| 234 SetDefaultLocaleForTest("en-US", env.get()); | |
| 235 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-CA")); | |
| 236 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 237 | |
| 238 SetDefaultLocaleForTest("en-US", env.get()); | |
| 239 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("en-ZA")); | |
| 240 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 241 } else { | |
| 242 // Most platforms have an OS-provided locale. This locale is preferred. | |
| 243 SetDefaultLocaleForTest("en-GB", env.get()); | |
| 244 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | |
| 245 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 246 | |
| 247 SetDefaultLocaleForTest("fr-CA", env.get()); | |
| 248 EXPECT_EQ("fr", l10n_util::GetApplicationLocale(std::string())); | |
| 249 EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | |
| 250 | |
| 251 SetDefaultLocaleForTest("es-MX", env.get()); | |
| 252 EXPECT_EQ("es-419", l10n_util::GetApplicationLocale(std::string())); | |
| 253 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 254 | |
| 255 SetDefaultLocaleForTest("es-AR", env.get()); | |
| 256 EXPECT_EQ("es-419", l10n_util::GetApplicationLocale(std::string())); | |
| 257 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 258 | |
| 259 SetDefaultLocaleForTest("es-ES", env.get()); | |
| 260 EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); | |
| 261 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 262 | |
| 263 SetDefaultLocaleForTest("es", env.get()); | |
| 264 EXPECT_EQ("es", l10n_util::GetApplicationLocale(std::string())); | |
| 265 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 266 | |
| 267 SetDefaultLocaleForTest("zh-HK", env.get()); | |
| 268 EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); | |
| 269 EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | |
| 270 | |
| 271 SetDefaultLocaleForTest("zh-MO", env.get()); | |
| 272 EXPECT_EQ("zh-TW", l10n_util::GetApplicationLocale(std::string())); | |
| 273 EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | |
| 274 | |
| 275 SetDefaultLocaleForTest("zh-SG", env.get()); | |
| 276 EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale(std::string())); | |
| 277 EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | |
| 278 | |
| 279 SetDefaultLocaleForTest("en-CA", env.get()); | |
| 280 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | |
| 281 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 282 | |
| 283 SetDefaultLocaleForTest("en-AU", env.get()); | |
| 284 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | |
| 285 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 286 | |
| 287 SetDefaultLocaleForTest("en-NZ", env.get()); | |
| 288 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | |
| 289 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 290 | |
| 291 SetDefaultLocaleForTest("en-ZA", env.get()); | |
| 292 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale(std::string())); | |
| 293 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 294 } | |
| 295 | |
| 296 SetDefaultLocaleForTest("en-US", env.get()); | |
| 297 | |
| 298 if (kSupportsLocalePreference) { | |
| 299 // On windows, the user can override the locale in preferences. | |
| 300 base::i18n::SetICUDefaultLocale("en-US"); | |
| 301 EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr")); | |
| 302 EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | |
| 303 EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr-CA")); | |
| 304 EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); | |
| 305 | |
| 306 base::i18n::SetICUDefaultLocale("en-US"); | |
| 307 // Aliases iw, no, tl to he, nb, fil. | |
| 308 EXPECT_EQ("he", l10n_util::GetApplicationLocale("iw")); | |
| 309 EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); | |
| 310 EXPECT_EQ("nb", l10n_util::GetApplicationLocale("no")); | |
| 311 EXPECT_STREQ("nb", icu::Locale::getDefault().getLanguage()); | |
| 312 EXPECT_EQ("fil", l10n_util::GetApplicationLocale("tl")); | |
| 313 EXPECT_STREQ("fil", icu::Locale::getDefault().getLanguage()); | |
| 314 // es-419 and es-XX (where XX is not Spain) should be | |
| 315 // mapped to es-419 (Latin American Spanish). | |
| 316 EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("es-419")); | |
| 317 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 318 EXPECT_EQ("es", l10n_util::GetApplicationLocale("es-ES")); | |
| 319 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 320 EXPECT_EQ("es-419", l10n_util::GetApplicationLocale("es-AR")); | |
| 321 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 322 | |
| 323 base::i18n::SetICUDefaultLocale("es-AR"); | |
| 324 EXPECT_EQ("es", l10n_util::GetApplicationLocale("es")); | |
| 325 EXPECT_STREQ("es", icu::Locale::getDefault().getLanguage()); | |
| 326 | |
| 327 base::i18n::SetICUDefaultLocale("zh-HK"); | |
| 328 EXPECT_EQ("zh-CN", l10n_util::GetApplicationLocale("zh-CN")); | |
| 329 EXPECT_STREQ("zh", icu::Locale::getDefault().getLanguage()); | |
| 330 | |
| 331 base::i18n::SetICUDefaultLocale("he"); | |
| 332 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en")); | |
| 333 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 334 | |
| 335 base::i18n::SetICUDefaultLocale("he"); | |
| 336 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en", false)); | |
| 337 EXPECT_STREQ("he", icu::Locale::getDefault().getLanguage()); | |
| 338 | |
| 339 base::i18n::SetICUDefaultLocale("de"); | |
| 340 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("xx", false)); | |
| 341 EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); | |
| 342 | |
| 343 base::i18n::SetICUDefaultLocale("de"); | |
| 344 EXPECT_EQ("fr", l10n_util::GetApplicationLocale("fr", false)); | |
| 345 EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); | |
| 346 | |
| 347 base::i18n::SetICUDefaultLocale("de"); | |
| 348 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en", false)); | |
| 349 EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); | |
| 350 | |
| 351 base::i18n::SetICUDefaultLocale("de"); | |
| 352 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("en-US", true)); | |
| 353 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 354 } else { | |
| 355 base::i18n::SetICUDefaultLocale("de"); | |
| 356 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string(), false)); | |
| 357 EXPECT_STREQ("de", icu::Locale::getDefault().getLanguage()); | |
| 358 | |
| 359 base::i18n::SetICUDefaultLocale("de"); | |
| 360 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale(std::string(), true)); | |
| 361 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 362 } | |
| 363 | |
| 364 #if defined(OS_WIN) | |
| 365 // Amharic should be blocked unless OS is Vista or newer. | |
| 366 if (base::win::GetVersion() < base::win::VERSION_VISTA) { | |
| 367 base::i18n::SetICUDefaultLocale("am"); | |
| 368 EXPECT_EQ("en-US", l10n_util::GetApplicationLocale("")); | |
| 369 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 370 base::i18n::SetICUDefaultLocale("en-GB"); | |
| 371 EXPECT_EQ("en-GB", l10n_util::GetApplicationLocale("am")); | |
| 372 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); | |
| 373 } else { | |
| 374 base::i18n::SetICUDefaultLocale("am"); | |
| 375 EXPECT_EQ("am", l10n_util::GetApplicationLocale("")); | |
| 376 EXPECT_STREQ("am", icu::Locale::getDefault().getLanguage()); | |
| 377 base::i18n::SetICUDefaultLocale("en-GB"); | |
| 378 EXPECT_EQ("am", l10n_util::GetApplicationLocale("am")); | |
| 379 EXPECT_STREQ("am", icu::Locale::getDefault().getLanguage()); | |
| 380 } | |
| 381 #endif // defined(OS_WIN) | |
| 382 | |
| 383 // Clean up. | |
| 384 base::i18n::SetICUDefaultLocale(original_locale); | |
| 385 } | |
| 386 #endif // !defined(OS_MACOSX) | |
| 387 | |
| 388 TEST_F(L10nUtilTest, SortStringsUsingFunction) { | |
| 389 std::vector<StringWrapper*> strings; | |
| 390 strings.push_back(new StringWrapper(UTF8ToUTF16("C"))); | |
| 391 strings.push_back(new StringWrapper(UTF8ToUTF16("d"))); | |
| 392 strings.push_back(new StringWrapper(UTF8ToUTF16("b"))); | |
| 393 strings.push_back(new StringWrapper(UTF8ToUTF16("a"))); | |
| 394 l10n_util::SortStringsUsingMethod("en-US", | |
| 395 &strings, | |
| 396 &StringWrapper::string); | |
| 397 ASSERT_TRUE(UTF8ToUTF16("a") == strings[0]->string()); | |
| 398 ASSERT_TRUE(UTF8ToUTF16("b") == strings[1]->string()); | |
| 399 ASSERT_TRUE(UTF8ToUTF16("C") == strings[2]->string()); | |
| 400 ASSERT_TRUE(UTF8ToUTF16("d") == strings[3]->string()); | |
| 401 STLDeleteElements(&strings); | |
| 402 } | |
| 403 | |
| 404 /** | |
| 405 * Helper method for validating strings that require direcitonal markup. | |
| 406 * Checks that parentheses are enclosed in appropriate direcitonal markers. | |
| 407 */ | |
| 408 void CheckUiDisplayNameForLocale(const std::string& locale, | |
| 409 const std::string& display_locale, | |
| 410 bool is_rtl) { | |
| 411 EXPECT_EQ(true, base::i18n::IsRTL()); | |
| 412 base::string16 result = l10n_util::GetDisplayNameForLocale(locale, | |
| 413 display_locale, | |
| 414 /* is_for_ui */ true); | |
| 415 | |
| 416 bool rtl_direction = true; | |
| 417 for (size_t i = 0; i < result.length() - 1; i++) { | |
| 418 base::char16 ch = result.at(i); | |
| 419 switch (ch) { | |
| 420 case base::i18n::kLeftToRightMark: | |
| 421 case base::i18n::kLeftToRightEmbeddingMark: | |
| 422 rtl_direction = false; | |
| 423 break; | |
| 424 case base::i18n::kRightToLeftMark: | |
| 425 case base::i18n::kRightToLeftEmbeddingMark: | |
| 426 rtl_direction = true; | |
| 427 break; | |
| 428 case '(': | |
| 429 case ')': | |
| 430 EXPECT_EQ(is_rtl, rtl_direction); | |
| 431 } | |
| 432 } | |
| 433 } | |
| 434 | |
| 435 TEST_F(L10nUtilTest, GetDisplayNameForLocale) { | |
| 436 // TODO(jungshik): Make this test more extensive. | |
| 437 // Test zh-CN and zh-TW are treated as zh-Hans and zh-Hant. | |
| 438 base::string16 result = | |
| 439 l10n_util::GetDisplayNameForLocale("zh-CN", "en", false); | |
| 440 EXPECT_EQ(ASCIIToUTF16("Chinese (Simplified)"), result); | |
| 441 | |
| 442 result = l10n_util::GetDisplayNameForLocale("zh-TW", "en", false); | |
| 443 EXPECT_EQ(ASCIIToUTF16("Chinese (Traditional)"), result); | |
| 444 | |
| 445 // tl and fil are not identical to be strict, but we treat them as | |
| 446 // synonyms. | |
| 447 result = l10n_util::GetDisplayNameForLocale("tl", "en", false); | |
| 448 EXPECT_EQ(l10n_util::GetDisplayNameForLocale("fil", "en", false), result); | |
| 449 | |
| 450 result = l10n_util::GetDisplayNameForLocale("pt-BR", "en", false); | |
| 451 EXPECT_EQ(ASCIIToUTF16("Portuguese (Brazil)"), result); | |
| 452 | |
| 453 result = l10n_util::GetDisplayNameForLocale("es-419", "en", false); | |
| 454 EXPECT_EQ(ASCIIToUTF16("Spanish (Latin America)"), result); | |
| 455 | |
| 456 result = l10n_util::GetDisplayNameForLocale("-BR", "en", false); | |
| 457 EXPECT_EQ(ASCIIToUTF16("Brazil"), result); | |
| 458 | |
| 459 result = l10n_util::GetDisplayNameForLocale("xyz-xyz", "en", false); | |
| 460 EXPECT_EQ(ASCIIToUTF16("xyz (XYZ)"), result); | |
| 461 | |
| 462 // Check for directional markers when using RTL languages to ensure that | |
| 463 // direction neutral characters such as parentheses are properly formatted. | |
| 464 | |
| 465 // Keep a copy of ICU's default locale before we overwrite it. | |
| 466 const std::string original_locale = base::i18n::GetConfiguredLocale(); | |
| 467 | |
| 468 base::i18n::SetICUDefaultLocale("he"); | |
| 469 CheckUiDisplayNameForLocale("en-US", "en", false); | |
| 470 CheckUiDisplayNameForLocale("en-US", "he", true); | |
| 471 | |
| 472 // Clean up. | |
| 473 base::i18n::SetICUDefaultLocale(original_locale); | |
| 474 | |
| 475 // ToUpper and ToLower should work with embedded NULLs. | |
| 476 const size_t length_with_null = 4; | |
| 477 base::char16 buf_with_null[length_with_null] = { 0, 'a', 0, 'b' }; | |
| 478 base::string16 string16_with_null(buf_with_null, length_with_null); | |
| 479 | |
| 480 base::string16 upper_with_null = base::i18n::ToUpper(string16_with_null); | |
| 481 ASSERT_EQ(length_with_null, upper_with_null.size()); | |
| 482 EXPECT_TRUE(upper_with_null[0] == 0 && upper_with_null[1] == 'A' && | |
| 483 upper_with_null[2] == 0 && upper_with_null[3] == 'B'); | |
| 484 | |
| 485 base::string16 lower_with_null = base::i18n::ToLower(upper_with_null); | |
| 486 ASSERT_EQ(length_with_null, upper_with_null.size()); | |
| 487 EXPECT_TRUE(lower_with_null[0] == 0 && lower_with_null[1] == 'a' && | |
| 488 lower_with_null[2] == 0 && lower_with_null[3] == 'b'); | |
| 489 } | |
| 490 | |
| 491 TEST_F(L10nUtilTest, GetDisplayNameForCountry) { | |
| 492 base::string16 result = l10n_util::GetDisplayNameForCountry("BR", "en"); | |
| 493 EXPECT_EQ(ASCIIToUTF16("Brazil"), result); | |
| 494 | |
| 495 result = l10n_util::GetDisplayNameForCountry("419", "en"); | |
| 496 EXPECT_EQ(ASCIIToUTF16("Latin America"), result); | |
| 497 | |
| 498 result = l10n_util::GetDisplayNameForCountry("xyz", "en"); | |
| 499 EXPECT_EQ(ASCIIToUTF16("XYZ"), result); | |
| 500 } | |
| 501 | |
| 502 TEST_F(L10nUtilTest, GetParentLocales) { | |
| 503 std::vector<std::string> locales; | |
| 504 const std::string top_locale("sr_Cyrl_RS"); | |
| 505 l10n_util::GetParentLocales(top_locale, &locales); | |
| 506 | |
| 507 ASSERT_EQ(3U, locales.size()); | |
| 508 EXPECT_EQ("sr_Cyrl_RS", locales[0]); | |
| 509 EXPECT_EQ("sr_Cyrl", locales[1]); | |
| 510 EXPECT_EQ("sr", locales[2]); | |
| 511 } | |
| 512 | |
| 513 TEST_F(L10nUtilTest, IsValidLocaleSyntax) { | |
| 514 // Test valid locales. | |
| 515 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en")); | |
| 516 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr")); | |
| 517 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("de")); | |
| 518 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("pt")); | |
| 519 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh")); | |
| 520 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fil")); | |
| 521 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("haw")); | |
| 522 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en-US")); | |
| 523 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_US")); | |
| 524 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_GB")); | |
| 525 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("pt-BR")); | |
| 526 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_CN")); | |
| 527 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hans")); | |
| 528 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hans_CN")); | |
| 529 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hant")); | |
| 530 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zh_Hant_TW")); | |
| 531 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr_CA")); | |
| 532 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("i-klingon")); | |
| 533 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("es-419")); | |
| 534 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE_PREEURO")); | |
| 535 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE_u_cu_IEP")); | |
| 536 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("en_IE@currency=IEP")); | |
| 537 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("fr@x=y")); | |
| 538 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax("zn_CN@foo=bar")); | |
| 539 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax( | |
| 540 "fr@collation=phonebook;calendar=islamic-civil")); | |
| 541 EXPECT_TRUE(l10n_util::IsValidLocaleSyntax( | |
| 542 "sr_Latn_RS_REVISED@currency=USD")); | |
| 543 | |
| 544 // Test invalid locales. | |
| 545 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax(std::string())); | |
| 546 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("x")); | |
| 547 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("12")); | |
| 548 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("456")); | |
| 549 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("a1")); | |
| 550 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("enUS")); | |
| 551 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("zhcn")); | |
| 552 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en.US")); | |
| 553 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en#US")); | |
| 554 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("-en-US")); | |
| 555 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US-")); | |
| 556 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("123-en-US")); | |
| 557 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("Latin")); | |
| 558 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("German")); | |
| 559 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("pt--BR")); | |
| 560 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("sl-macedonia")); | |
| 561 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("@")); | |
| 562 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@")); | |
| 563 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@x")); | |
| 564 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@x=")); | |
| 565 EXPECT_FALSE(l10n_util::IsValidLocaleSyntax("en-US@=y")); | |
| 566 } | |
| OLD | NEW |