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 } 567