Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / ui / base / l10n / l10n_util_unittest.cc
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 }