1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
10 #include "unicode/decimfmt.h"
11 #include "unicode/ucurr.h"
12 #include "unicode/smpdtfmt.h"
13 #include "unicode/dtfmtsym.h"
14 #include "unicode/brkiter.h"
15 #include "unicode/coll.h"
21 #include "unicode/ustring.h"
24 static const char* const rawData
[33][8] = {
27 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
29 { "", "", "", "", "", "", "", "Hans" },
31 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" },
33 { "", "", "", "", "NY", "", "", "" },
35 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" },
37 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" },
39 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" },
41 { "409", "40c", "403", "408", "814", "10", "0", "804" },
43 // display langage (English)
44 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" },
45 // display script (English)
46 { "", "", "", "", "", "", "", "Simplified Han" },
47 // display country (English)
48 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China" },
49 // display variant (English)
50 { "", "", "", "", "NY", "", "", ""},
51 // display name (English)
52 // Updated no_NO_NY English display name for new pattern-based algorithm
53 // (part of Euro support).
54 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplified, China)" },
56 // display langage (French)
57 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
58 // display script (French)
59 { "", "", "", "", "", "", "", "sinogrammes simplifi\\u00E9s" },
60 // display country (French)
61 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine" },
62 // display variant (French)
63 { "", "", "", "", "NY", "", "", "" },
64 // display name (French)
65 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
66 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois (simplifi\\u00E9, Chine)" },
69 /* display language (Catalan) */
70 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E8s" },
71 /* display script (Catalan) */
72 { "", "", "", "", "", "", "", "han simplificat" },
73 /* display country (Catalan) */
74 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina" },
75 /* display variant (Catalan) */
76 { "", "", "", "", "NY", "", "" },
77 /* display name (Catalan) */
78 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E8s (simplificat, Xina)" },
80 // display langage (Greek)[actual values listed below]
81 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
82 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
83 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
84 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
85 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
86 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
88 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
90 // display script (Greek)
91 { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd" },
92 // display country (Greek)[actual values listed below]
93 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
94 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
95 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
96 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
97 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
100 "\\u039A\\u03AF\\u03BD\\u03B1"
102 // display variant (Greek)
103 { "", "", "", "", "NY", "", "" },
104 // display name (Greek)[actual values listed below]
105 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
106 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
107 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
108 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
109 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
110 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
112 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1, \\u039A\\u03AF\\u03BD\\u03B1)"
115 // display langage (<root>)
116 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" },
117 // display script (<root>)
118 { "", "", "", "", "", "", "", ""},
119 // display country (<root>)
120 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" },
121 // display variant (<root>)
122 { "", "", "", "", "Nynorsk", "", "", ""},
123 // display name (<root>)
124 //{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" },
125 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
131 test_assert( Test (should be TRUE) )
136 the macro is ugly but makes the tests pretty.
139 #define test_assert(test) \
142 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \
144 logln("PASS: asserted " #test); \
149 test_assert_print( Test (should be TRUE), printable )
152 test_assert(i==3, toString(i));
154 the macro is ugly but makes the tests pretty.
157 #define test_assert_print(test,print) \
160 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \
162 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \
166 #define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); }
168 LocaleTest::LocaleTest()
174 LocaleTest::~LocaleTest()
176 if (dataTable
!= 0) {
177 for (int32_t i
= 0; i
< 33; i
++) {
178 delete []dataTable
[i
];
185 void LocaleTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
188 TESTCASE_AUTO(TestBug11421
); // Must run early in list to trigger failure.
189 TESTCASE_AUTO(TestBasicGetters
);
190 TESTCASE_AUTO(TestSimpleResourceInfo
);
191 TESTCASE_AUTO(TestDisplayNames
);
192 TESTCASE_AUTO(TestSimpleObjectStuff
);
193 TESTCASE_AUTO(TestPOSIXParsing
);
194 TESTCASE_AUTO(TestGetAvailableLocales
);
195 TESTCASE_AUTO(TestDataDirectory
);
196 TESTCASE_AUTO(TestISO3Fallback
);
197 TESTCASE_AUTO(TestGetLangsAndCountries
);
198 TESTCASE_AUTO(TestSimpleDisplayNames
);
199 TESTCASE_AUTO(TestUninstalledISO3Names
);
200 TESTCASE_AUTO(TestAtypicalLocales
);
201 #if !UCONFIG_NO_FORMATTING
202 TESTCASE_AUTO(TestThaiCurrencyFormat
);
203 TESTCASE_AUTO(TestEuroSupport
);
205 TESTCASE_AUTO(TestToString
);
206 #if !UCONFIG_NO_FORMATTING
207 TESTCASE_AUTO(Test4139940
);
208 TESTCASE_AUTO(Test4143951
);
210 TESTCASE_AUTO(Test4147315
);
211 TESTCASE_AUTO(Test4147317
);
212 TESTCASE_AUTO(Test4147552
);
213 TESTCASE_AUTO(TestVariantParsing
);
214 #if !UCONFIG_NO_FORMATTING
215 TESTCASE_AUTO(Test4105828
);
217 TESTCASE_AUTO(TestSetIsBogus
);
218 TESTCASE_AUTO(TestParallelAPIValues
);
219 TESTCASE_AUTO(TestKeywordVariants
);
220 TESTCASE_AUTO(TestKeywordVariantParsing
);
221 TESTCASE_AUTO(TestSetKeywordValue
);
222 TESTCASE_AUTO(TestGetBaseName
);
223 #if !UCONFIG_NO_FILE_IO
224 TESTCASE_AUTO(TestGetLocale
);
226 TESTCASE_AUTO(TestVariantWithOutCountry
);
227 TESTCASE_AUTO(TestCanonicalization
);
228 TESTCASE_AUTO(TestCurrencyByDate
);
229 TESTCASE_AUTO(TestGetVariantWithKeywords
);
230 TESTCASE_AUTO(TestIsRightToLeft
);
234 void LocaleTest::TestBasicGetters() {
238 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
239 Locale
testLocale("");
240 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
241 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
244 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
246 logln("Testing " + (UnicodeString
)testLocale
.getName() + "...");
248 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
249 errln(" Language code mismatch: " + temp
+ " versus "
250 + dataTable
[LANG
][i
]);
251 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
252 errln(" Script code mismatch: " + temp
+ " versus "
253 + dataTable
[SCRIPT
][i
]);
254 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
255 errln(" Country code mismatch: " + temp
+ " versus "
256 + dataTable
[CTRY
][i
]);
257 if ( (temp
=testLocale
.getVariant()) != (dataTable
[VAR
][i
]))
258 errln(" Variant code mismatch: " + temp
+ " versus "
259 + dataTable
[VAR
][i
]);
260 if ( (temp
=testLocale
.getName()) != (dataTable
[NAME
][i
]))
261 errln(" Locale name mismatch: " + temp
+ " versus "
262 + dataTable
[NAME
][i
]);
265 logln("Same thing without variant codes...");
266 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
267 Locale
testLocale("");
268 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
269 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
]);
272 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
]);
274 logln("Testing " + (temp
=testLocale
.getName()) + "...");
276 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
277 errln("Language code mismatch: " + temp
+ " versus "
278 + dataTable
[LANG
][i
]);
279 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
280 errln("Script code mismatch: " + temp
+ " versus "
281 + dataTable
[SCRIPT
][i
]);
282 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
283 errln("Country code mismatch: " + temp
+ " versus "
284 + dataTable
[CTRY
][i
]);
285 if (testLocale
.getVariant()[0] != 0)
286 errln("Variant code mismatch: something versus \"\"");
289 logln("Testing long language names and getters");
290 Locale test8
= Locale::createFromName("x-klingon-latn-zx.utf32be@special");
292 temp
= test8
.getLanguage();
293 if (temp
!= UnicodeString("x-klingon") )
294 errln("Language code mismatch: " + temp
+ " versus \"x-klingon\"");
296 temp
= test8
.getScript();
297 if (temp
!= UnicodeString("Latn") )
298 errln("Script code mismatch: " + temp
+ " versus \"Latn\"");
300 temp
= test8
.getCountry();
301 if (temp
!= UnicodeString("ZX") )
302 errln("Country code mismatch: " + temp
+ " versus \"ZX\"");
304 temp
= test8
.getVariant();
305 //if (temp != UnicodeString("SPECIAL") )
306 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\"");
307 // As of 3.0, the "@special" will *not* be parsed by uloc_getName()
308 if (temp
!= UnicodeString("") )
309 errln("Variant code mismatch: " + temp
+ " versus \"\"");
311 if (Locale::getDefault() != Locale::createFromName(NULL
))
312 errln("Locale::getDefault() == Locale::createFromName(NULL)");
315 // NOTE: There used to be a special test for locale names that had language or
316 // country codes that were longer than two letters. The new version of Locale
317 // doesn't support anything that isn't an officially recognized language or
318 // country code, so we no longer support this feature.
320 Locale
bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code too long
321 if(!bogusLang
.isBogus()) {
322 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE");
325 bogusLang
=Locale("eo");
326 if( bogusLang
.isBogus() ||
327 strcmp(bogusLang
.getLanguage(), "eo")!=0 ||
328 *bogusLang
.getCountry()!=0 ||
329 *bogusLang
.getVariant()!=0 ||
330 strcmp(bogusLang
.getName(), "eo")!=0
332 errln("assignment to bogus Locale does not unbogus it or sets bad data");
335 Locale
a("eo_DE@currency=DEM");
336 Locale
*pb
=a
.clone();
337 if(pb
==&a
|| *pb
!=a
) {
338 errln("Locale.clone() failed");
343 void LocaleTest::TestParallelAPIValues() {
344 logln("Test synchronization between C and C++ API");
345 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE
) != 0) {
346 errln("Differences for ULOC_CHINESE Locale");
348 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH
) != 0) {
349 errln("Differences for ULOC_ENGLISH Locale");
351 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH
) != 0) {
352 errln("Differences for ULOC_FRENCH Locale");
354 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN
) != 0) {
355 errln("Differences for ULOC_GERMAN Locale");
357 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN
) != 0) {
358 errln("Differences for ULOC_ITALIAN Locale");
360 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE
) != 0) {
361 errln("Differences for ULOC_JAPANESE Locale");
363 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN
) != 0) {
364 errln("Differences for ULOC_KOREAN Locale");
366 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE
) != 0) {
367 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale");
369 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINESE
) != 0) {
370 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale");
374 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA
) != 0) {
375 errln("Differences for ULOC_CANADA Locale");
377 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH
) != 0) {
378 errln("Differences for ULOC_CANADA_FRENCH Locale");
380 if (strcmp(Locale::getChina().getName(), ULOC_CHINA
) != 0) {
381 errln("Differences for ULOC_CHINA Locale");
383 if (strcmp(Locale::getPRC().getName(), ULOC_PRC
) != 0) {
384 errln("Differences for ULOC_PRC Locale");
386 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE
) != 0) {
387 errln("Differences for ULOC_FRANCE Locale");
389 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY
) != 0) {
390 errln("Differences for ULOC_GERMANY Locale");
392 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY
) != 0) {
393 errln("Differences for ULOC_ITALY Locale");
395 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN
) != 0) {
396 errln("Differences for ULOC_JAPAN Locale");
398 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA
) != 0) {
399 errln("Differences for ULOC_KOREA Locale");
401 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN
) != 0) {
402 errln("Differences for ULOC_TAIWAN Locale");
404 if (strcmp(Locale::getUK().getName(), ULOC_UK
) != 0) {
405 errln("Differences for ULOC_UK Locale");
407 if (strcmp(Locale::getUS().getName(), ULOC_US
) != 0) {
408 errln("Differences for ULOC_US Locale");
413 void LocaleTest::TestSimpleResourceInfo() {
416 UErrorCode err
= U_ZERO_ERROR
;
419 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
420 Locale
testLocale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
421 logln("Testing " + (temp
=testLocale
.getName()) + "...");
423 if ( (temp
=testLocale
.getISO3Language()) != (dataTable
[LANG3
][i
]))
424 errln(" ISO-3 language code mismatch: " + temp
425 + " versus " + dataTable
[LANG3
][i
]);
426 if ( (temp
=testLocale
.getISO3Country()) != (dataTable
[CTRY3
][i
]))
427 errln(" ISO-3 country code mismatch: " + temp
428 + " versus " + dataTable
[CTRY3
][i
]);
430 sprintf(temp2
, "%x", (int)testLocale
.getLCID());
431 if (UnicodeString(temp2
) != dataTable
[LCID
][i
])
432 errln((UnicodeString
)" LCID mismatch: " + temp2
+ " versus "
433 + dataTable
[LCID
][i
]);
437 errln((UnicodeString
)"Some error on number " + i
+ u_errorName(err
));
443 if(strcmp(locale
.getName(), "en") != 0||
444 strcmp(locale
.getLanguage(), "en") != 0) {
445 errln("construction of Locale(en) failed\n");
452 * Jitterbug 2439 -- markus 20030425
454 * The lookup of display names must not fall back through the default
455 * locale because that yields useless results.
458 LocaleTest::TestDisplayNames()
460 Locale
english("en", "US");
461 Locale
french("fr", "FR");
462 Locale
croatian("ca", "ES");
463 Locale
greek("el", "GR");
465 logln(" In locale = en_US...");
466 doTestDisplayNames(english
, DLANG_EN
);
467 logln(" In locale = fr_FR...");
468 doTestDisplayNames(french
, DLANG_FR
);
469 logln(" In locale = ca_ES...");
470 doTestDisplayNames(croatian
, DLANG_CA
);
471 logln(" In locale = el_GR...");
472 doTestDisplayNames(greek
, DLANG_EL
);
475 UErrorCode status
= U_ZERO_ERROR
;
477 #if !UCONFIG_NO_FORMATTING
478 DecimalFormatSymbols
symb(status
);
479 /* Check to see if ICU supports this locale */
480 if (symb
.getLocale(ULOC_VALID_LOCALE
, status
) != Locale("root")) {
481 /* test that the default locale has a display name for its own language */
482 /* Currently, there is no language information in the "tl" data file so this test will fail if default locale is "tl" */
483 if (uprv_strcmp(Locale().getLanguage(), "tl") != 0) {
484 Locale().getDisplayLanguage(Locale(), s
);
485 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
486 /* check <=3 to reject getting the language code as a display name */
487 dataerrln("unable to get a display string for the language of the default locale: " + s
);
491 * API coverage improvements: call
492 * Locale::getDisplayLanguage(UnicodeString &) and
493 * Locale::getDisplayCountry(UnicodeString &)
496 Locale().getDisplayLanguage(s
);
497 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
498 dataerrln("unable to get a display string for the language of the default locale [2]: " + s
);
503 logln("Default locale %s is unsupported by ICU\n", Locale().getName());
508 french
.getDisplayCountry(s
);
510 errln("unable to get any default-locale display string for the country of fr_FR\n");
513 Locale("zh", "Hant").getDisplayScript(s
);
515 errln("unable to get any default-locale display string for the country of zh_Hant\n");
519 void LocaleTest::TestSimpleObjectStuff() {
520 Locale
test1("aa", "AA");
521 Locale
test2("aa", "AA");
523 Locale
test4("zz", "ZZ");
524 Locale
test5("aa", "AA", "");
525 Locale
test6("aa", "AA", "ANTARES");
526 Locale
test7("aa", "AA", "JUPITER");
527 Locale test8
= Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that
529 // now list them all for debugging usage.
530 test_dumpLocale(test1
);
531 test_dumpLocale(test2
);
532 test_dumpLocale(test3
);
533 test_dumpLocale(test4
);
534 test_dumpLocale(test5
);
535 test_dumpLocale(test6
);
536 test_dumpLocale(test7
);
537 test_dumpLocale(test8
);
539 // Make sure things compare to themselves!
540 test_assert(test1
== test1
);
541 test_assert(test2
== test2
);
542 test_assert(test3
== test3
);
543 test_assert(test4
== test4
);
544 test_assert(test5
== test5
);
545 test_assert(test6
== test6
);
546 test_assert(test7
== test7
);
547 test_assert(test8
== test8
);
549 // make sure things are not equal to themselves.
550 test_assert(!(test1
!= test1
));
551 test_assert(!(test2
!= test2
));
552 test_assert(!(test3
!= test3
));
553 test_assert(!(test4
!= test4
));
554 test_assert(!(test5
!= test5
));
555 test_assert(!(test6
!= test6
));
556 test_assert(!(test7
!= test7
));
557 test_assert(!(test8
!= test8
));
559 // make sure things that are equal to each other don't show up as unequal.
560 test_assert(!(test1
!= test2
));
561 test_assert(!(test2
!= test1
));
562 test_assert(!(test1
!= test3
));
563 test_assert(!(test2
!= test3
));
564 test_assert(test5
== test1
);
565 test_assert(test6
!= test2
);
566 test_assert(test6
!= test5
);
568 test_assert(test6
!= test7
);
570 // test for things that shouldn't compare equal.
571 test_assert(!(test1
== test4
));
572 test_assert(!(test2
== test4
));
573 test_assert(!(test3
== test4
));
575 test_assert(test7
== test8
);
577 // test for hash codes to be the same.
578 int32_t hash1
= test1
.hashCode();
579 int32_t hash2
= test2
.hashCode();
580 int32_t hash3
= test3
.hashCode();
582 test_assert(hash1
== hash2
);
583 test_assert(hash1
== hash3
);
584 test_assert(hash2
== hash3
);
586 // test that the assignment operator works.
588 logln("test4=test1;");
589 test_dumpLocale(test4
);
590 test_assert(test4
== test4
);
592 test_assert(!(test1
!= test4
));
593 test_assert(!(test2
!= test4
));
594 test_assert(!(test3
!= test4
));
595 test_assert(test1
== test4
);
596 test_assert(test4
== test1
);
598 // test assignments with a variant
599 logln("test7 = test6");
601 test_dumpLocale(test7
);
602 test_assert(test7
== test7
);
603 test_assert(test7
== test6
);
604 test_assert(test7
!= test5
);
606 logln("test6 = test1");
608 test_dumpLocale(test6
);
609 test_assert(test6
!= test7
);
610 test_assert(test6
== test1
);
611 test_assert(test6
== test6
);
614 // A class which exposes constructors that are implemented in terms of the POSIX parsing code.
615 class POSIXLocale
: public Locale
618 POSIXLocale(const UnicodeString
& l
)
622 ch
= new char[l
.length() + 1];
623 ch
[l
.extract(0, 0x7fffffff, ch
, "")] = 0;
627 POSIXLocale(const char *l
)
634 void LocaleTest::TestPOSIXParsing()
636 POSIXLocale
test1("ab_AB");
637 POSIXLocale
test2(UnicodeString("ab_AB"));
638 Locale
test3("ab","AB");
640 POSIXLocale
test4("ab_AB_Antares");
641 POSIXLocale
test5(UnicodeString("ab_AB_Antares"));
642 Locale
test6("ab", "AB", "Antares");
644 test_dumpLocale(test1
);
645 test_dumpLocale(test2
);
646 test_dumpLocale(test3
);
647 test_dumpLocale(test4
);
648 test_dumpLocale(test5
);
649 test_dumpLocale(test6
);
651 test_assert(test1
== test1
);
653 test_assert(test1
== test2
);
654 test_assert(test2
== test3
);
655 test_assert(test3
== test1
);
657 test_assert(test4
== test5
);
658 test_assert(test5
== test6
);
659 test_assert(test6
== test4
);
661 test_assert(test1
!= test4
);
662 test_assert(test5
!= test3
);
663 test_assert(test5
!= test2
);
665 int32_t hash1
= test1
.hashCode();
666 int32_t hash2
= test2
.hashCode();
667 int32_t hash3
= test3
.hashCode();
669 test_assert(hash1
== hash2
);
670 test_assert(hash2
== hash3
);
671 test_assert(hash3
== hash1
);
674 void LocaleTest::TestGetAvailableLocales()
676 int32_t locCount
= 0;
677 const Locale
* locList
= Locale::getAvailableLocales(locCount
);
680 dataerrln("getAvailableLocales() returned an empty list!");
682 logln(UnicodeString("Number of locales returned = ") + locCount
);
684 for(int32_t i
= 0; i
< locCount
; ++i
)
685 logln(locList
[i
].getName());
687 // I have no idea how to test this function...
690 // This test isn't applicable anymore - getISO3Language is
691 // independent of the data directory
692 void LocaleTest::TestDataDirectory()
695 char oldDirectory[80];
697 UErrorCode err = U_ZERO_ERROR;
698 UnicodeString testValue;
700 temp = Locale::getDataDirectory();
701 strcpy(oldDirectory, temp);
702 logln(UnicodeString("oldDirectory = ") + oldDirectory);
704 Locale test(Locale::US);
705 test.getISO3Language(testValue);
706 logln("first fetch of language retrieved " + testValue);
707 if (testValue != "eng")
708 errln("Initial check of ISO3 language failed: expected \"eng\", got \"" + testValue + "\"");
712 path=IntlTest::getTestDirectory();
713 Locale::setDataDirectory( path );
716 test.getISO3Language(testValue);
717 logln("second fetch of language retrieved " + testValue);
718 if (testValue != "xxx")
719 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue + "\"");
721 Locale::setDataDirectory(oldDirectory);
722 test.getISO3Language(testValue);
723 logln("third fetch of language retrieved " + testValue);
724 if (testValue != "eng")
725 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testValue + "\"");
729 //===========================================================
731 void LocaleTest::doTestDisplayNames(Locale
& displayLocale
, int32_t compareIndex
) {
734 for (int32_t i
= 0; i
<= MAX_LOCALES
; i
++) {
735 Locale
testLocale("");
736 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
737 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
740 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
742 logln(" Testing " + (temp
=testLocale
.getName()) + "...");
744 UnicodeString testLang
;
745 UnicodeString testScript
;
746 UnicodeString testCtry
;
747 UnicodeString testVar
;
748 UnicodeString testName
;
750 testLocale
.getDisplayLanguage(displayLocale
, testLang
);
751 testLocale
.getDisplayScript(displayLocale
, testScript
);
752 testLocale
.getDisplayCountry(displayLocale
, testCtry
);
753 testLocale
.getDisplayVariant(displayLocale
, testVar
);
754 testLocale
.getDisplayName(displayLocale
, testName
);
756 UnicodeString expectedLang
;
757 UnicodeString expectedScript
;
758 UnicodeString expectedCtry
;
759 UnicodeString expectedVar
;
760 UnicodeString expectedName
;
762 expectedLang
= dataTable
[compareIndex
][i
];
763 if (expectedLang
.length() == 0)
764 expectedLang
= dataTable
[DLANG_EN
][i
];
766 expectedScript
= dataTable
[compareIndex
+ 1][i
];
767 if (expectedScript
.length() == 0)
768 expectedScript
= dataTable
[DSCRIPT_EN
][i
];
770 expectedCtry
= dataTable
[compareIndex
+ 2][i
];
771 if (expectedCtry
.length() == 0)
772 expectedCtry
= dataTable
[DCTRY_EN
][i
];
774 expectedVar
= dataTable
[compareIndex
+ 3][i
];
775 if (expectedVar
.length() == 0)
776 expectedVar
= dataTable
[DVAR_EN
][i
];
778 expectedName
= dataTable
[compareIndex
+ 4][i
];
779 if (expectedName
.length() == 0)
780 expectedName
= dataTable
[DNAME_EN
][i
];
782 if (testLang
!= expectedLang
)
783 dataerrln("Display language (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testLang
+ " expected " + expectedLang
);
784 if (testScript
!= expectedScript
)
785 dataerrln("Display script (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testScript
+ " expected " + expectedScript
);
786 if (testCtry
!= expectedCtry
)
787 dataerrln("Display country (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testCtry
+ " expected " + expectedCtry
);
788 if (testVar
!= expectedVar
)
789 dataerrln("Display variant (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testVar
+ " expected " + expectedVar
);
790 if (testName
!= expectedName
)
791 dataerrln("Display name (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testName
+ " expected " + expectedName
);
795 //---------------------------------------------------
796 // table of valid data
797 //---------------------------------------------------
801 void LocaleTest::setUpDataTable()
803 if (dataTable
== 0) {
804 dataTable
= new UnicodeString
*[33];
806 for (int32_t i
= 0; i
< 33; i
++) {
807 dataTable
[i
] = new UnicodeString
[8];
808 for (int32_t j
= 0; j
< 8; j
++) {
809 dataTable
[i
][j
] = CharsToUnicodeString(rawData
[i
][j
]);
815 // ====================
819 * @bug 4011756 4011380
822 LocaleTest::TestISO3Fallback()
824 Locale
test("xx", "YY");
828 result
= test
.getISO3Language();
830 // Conform to C API usage
832 if (!result
|| (result
[0] != 0))
833 errln("getISO3Language() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
835 result
= test
.getISO3Country();
837 if (!result
|| (result
[0] != 0))
838 errln("getISO3Country() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
842 * @bug 4106155 4118587
845 LocaleTest::TestGetLangsAndCountries()
847 // It didn't seem right to just do an exhaustive test of everything here, so I check
848 // for the following things:
849 // 1) Does each list have the right total number of entries?
850 // 2) Does each list contain certain language and country codes we think are important
851 // (the G7 countries, plus a couple others)?
852 // 3) Does each list have every entry formatted correctly? (i.e., two characters,
853 // all lower case for the language codes, all upper case for the country codes)
854 // 4) Is each list in sorted order?
855 int32_t testCount
= 0;
856 const char * const * test
= Locale::getISOLanguages();
857 const char spotCheck1
[ ][4] = { "en", "es", "fr", "de", "it",
858 "ja", "ko", "zh", "th", "he",
859 "id", "iu", "ug", "yi", "za" };
863 for(testCount
= 0;test
[testCount
];testCount
++)
866 /* TODO: Change this test to be more like the cloctst version? */
867 if (testCount
!= 594)
868 errln("Expected getISOLanguages() to return 594 languages; it returned %d", testCount
);
870 for (i
= 0; i
< 15; i
++) {
872 for (j
= 0; j
< testCount
; j
++)
873 if (uprv_strcmp(test
[j
],spotCheck1
[i
])== 0)
875 if (j
== testCount
|| (uprv_strcmp(test
[j
],spotCheck1
[i
])!=0))
876 errln("Couldn't find " + (UnicodeString
)spotCheck1
[i
] + " in language list.");
879 for (i
= 0; i
< testCount
; i
++) {
880 UnicodeString
testee(test
[i
],"");
881 UnicodeString
lc(test
[i
],"");
882 if (testee
!= lc
.toLower())
883 errln(lc
+ " is not all lower case.");
884 if ( (testee
.length() != 2) && (testee
.length() != 3))
885 errln(testee
+ " is not two or three characters long.");
886 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
887 errln(testee
+ " appears in an out-of-order position in the list.");
890 test
= Locale::getISOCountries();
891 UnicodeString spotCheck2
[] = { "US", "CA", "GB", "FR", "DE",
892 "IT", "JP", "KR", "CN", "TW",
894 int32_t spot2Len
= 11;
895 for(testCount
=0;test
[testCount
];testCount
++)
898 if (testCount
!= 256){
899 errln("Expected getISOCountries to return 256 countries; it returned %d", testCount
);
901 for (i
= 0; i
< spot2Len
; i
++) {
903 for (j
= 0; j
< testCount
; j
++)
905 UnicodeString
testee(test
[j
],"");
907 if (testee
== spotCheck2
[i
])
910 UnicodeString
testee(test
[j
],"");
911 if (j
== testCount
|| testee
!= spotCheck2
[i
])
912 errln("Couldn't find " + spotCheck2
[i
] + " in country list.");
915 for (i
= 0; i
< testCount
; i
++) {
916 UnicodeString
testee(test
[i
],"");
917 UnicodeString
uc(test
[i
],"");
918 if (testee
!= uc
.toUpper())
919 errln(testee
+ " is not all upper case.");
920 if (testee
.length() != 2)
921 errln(testee
+ " is not two characters long.");
922 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
923 errln(testee
+ " appears in an out-of-order position in the list.");
926 // This getAvailableLocales and getISO3Language
928 int32_t numOfLocales
;
930 const Locale
*pLocales
= Locale::getAvailableLocales(numOfLocales
);
932 for (int i
= 0; i
< numOfLocales
; i
++) {
933 const Locale
&loc(pLocales
[i
]);
937 loc
.getDisplayName (enLoc
, name
);
938 name
.extract (0, 200, szName
, sizeof(szName
));
940 if (strlen(loc
.getISO3Language()) == 0) {
941 errln("getISO3Language() returned an empty string for: " + name
);
951 LocaleTest::TestSimpleDisplayNames()
953 // This test is different from TestDisplayNames because TestDisplayNames checks
954 // fallback behavior, combination of language and country names to form locale
955 // names, and other stuff like that. This test just checks specific language
956 // and country codes to make sure we have the correct names for them.
957 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
958 UnicodeString languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
961 for (int32_t i
= 0; i
< 6; i
++) {
963 Locale
l(languageCodes
[i
], "", "");
964 l
.getDisplayLanguage(Locale::getUS(), test
);
965 if (test
!= languageNames
[i
])
966 dataerrln("Got wrong display name for " + UnicodeString(languageCodes
[i
]) + ": Expected \"" +
967 languageNames
[i
] + "\", got \"" + test
+ "\".");
975 LocaleTest::TestUninstalledISO3Names()
977 // This test checks to make sure getISO3Language and getISO3Country work right
978 // even for locales that are not installed.
979 const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
981 const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
982 "ssw", "twi", "zul" };
986 for (i
= 0; i
< 8; i
++) {
987 UErrorCode err
= U_ZERO_ERROR
;
990 Locale
l(iso2Languages
[i
], "", "");
991 test
= l
.getISO3Language();
992 if((test
!= iso3Languages
[i
]) || U_FAILURE(err
))
993 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages
[i
]) + ": Expected \"" +
994 iso3Languages
[i
] + "\", got \"" + test
+ "\"." + UnicodeString(u_errorName(err
)));
997 char iso2Countries
[][4] = { "AF", "BW", "KZ", "MO", "MN",
999 char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
1000 "SLB", "TCA", "ZWE" };
1002 for (i
= 0; i
< 8; i
++) {
1003 UErrorCode err
= U_ZERO_ERROR
;
1004 Locale
l("", iso2Countries
[i
], "");
1005 UnicodeString
test(l
.getISO3Country(), "");
1006 if (test
!= iso3Countries
[i
])
1007 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries
[i
]) + ": Expected \"" +
1008 UnicodeString(iso3Countries
[i
]) + "\", got \"" + test
+ "\"." + u_errorName(err
));
1014 * I could not reproduce this bug. I'm pretty convinced it was fixed with the
1015 * big locale-data reorg of 10/28/97. The lookup logic for language and country
1016 * display names was also changed at that time in that check-in. --rtg 3/20/98
1019 LocaleTest::TestAtypicalLocales()
1021 Locale localesToTest
[] = { Locale("de", "CA"),
1031 UnicodeString englishDisplayNames
[] = { "German (Canada)",
1032 "Japanese (South Africa)",
1035 "Spanish (Germany)",
1038 "Dominican Republic",
1040 UnicodeString frenchDisplayNames
[]= { "allemand (Canada)",
1041 "japonais (Afrique du Sud)",
1044 "espagnol (Allemagne)",
1046 CharsToUnicodeString("Su\\u00E8de"),
1047 CharsToUnicodeString("R\\u00E9publique dominicaine"),
1049 UnicodeString spanishDisplayNames
[] = {
1050 CharsToUnicodeString("alem\\u00E1n (Canad\\u00E1)"),
1051 CharsToUnicodeString("japon\\u00E9s (Sud\\u00E1frica)"),
1052 CharsToUnicodeString("ruso (M\\u00E9xico)"),
1053 CharsToUnicodeString("ingl\\u00E9s (Francia)"),
1054 CharsToUnicodeString("espa\\u00F1ol (Alemania)"),
1057 CharsToUnicodeString("Rep\\u00FAblica Dominicana"),
1058 CharsToUnicodeString("B\\u00E9lgica") };
1059 // De-Anglicizing root required the change from
1060 // English display names to ISO Codes - ram 2003/09/26
1061 UnicodeString invDisplayNames
[] = { "German (Canada)",
1062 "Japanese (South Africa)",
1065 "Spanish (Germany)",
1068 "Dominican Republic",
1072 UErrorCode status
= U_ZERO_ERROR
;
1074 Locale::setDefault(Locale::getUS(), status
);
1075 for (i
= 0; i
< 9; ++i
) {
1077 localesToTest
[i
].getDisplayName(Locale::getUS(), name
);
1079 if (name
!= englishDisplayNames
[i
])
1081 dataerrln("Lookup in English failed: expected \"" + englishDisplayNames
[i
]
1082 + "\", got \"" + name
+ "\"");
1083 logln("Locale name was-> " + (name
=localesToTest
[i
].getName()));
1087 for (i
= 0; i
< 9; i
++) {
1089 localesToTest
[i
].getDisplayName(Locale("es", "ES"), name
);
1091 if (name
!= spanishDisplayNames
[i
])
1092 dataerrln("Lookup in Spanish failed: expected \"" + spanishDisplayNames
[i
]
1093 + "\", got \"" + name
+ "\"");
1096 for (i
= 0; i
< 9; i
++) {
1098 localesToTest
[i
].getDisplayName(Locale::getFrance(), name
);
1100 if (name
!= frenchDisplayNames
[i
])
1101 dataerrln("Lookup in French failed: expected \"" + frenchDisplayNames
[i
]
1102 + "\", got \"" + name
+ "\"");
1105 for (i
= 0; i
< 9; i
++) {
1107 localesToTest
[i
].getDisplayName(Locale("inv", "IN"), name
);
1108 logln(name
+ " Locale fallback to be, and data fallback to root");
1109 if (name
!= invDisplayNames
[i
])
1110 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1111 + "\", got \"" + prettify(name
) + "\"");
1112 localesToTest
[i
].getDisplayName(Locale("inv", "BD"), name
);
1113 logln(name
+ " Data fallback to root");
1114 if (name
!= invDisplayNames
[i
])
1115 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1116 + "\", got \"" + prettify(name
)+ "\"");
1118 Locale::setDefault(saveLocale
, status
);
1121 #if !UCONFIG_NO_FORMATTING
1125 * This would be better tested by the LocaleDataTest. Will move it when I
1126 * get the LocaleDataTest working again.
1129 LocaleTest::TestThaiCurrencyFormat()
1131 UErrorCode status
= U_ZERO_ERROR
;
1132 DecimalFormat
*thaiCurrency
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(
1133 Locale("th", "TH"), status
);
1134 UnicodeString
posPrefix("THB", 3, US_INV
); // per cldrbug 7618
1137 if(U_FAILURE(status
) || !thaiCurrency
)
1139 dataerrln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status
)));
1142 if (thaiCurrency
->getPositivePrefix(temp
) != posPrefix
)
1143 errln("Thai currency prefix wrong: expected THB, got \"" +
1144 thaiCurrency
->getPositivePrefix(temp
) + "\"");
1145 if (thaiCurrency
->getPositiveSuffix(temp
) != "")
1146 errln("Thai currency suffix wrong: expected \"\", got \"" +
1147 thaiCurrency
->getPositiveSuffix(temp
) + "\"");
1149 delete thaiCurrency
;
1154 * Confirm that Euro support works. This test is pretty rudimentary; all it does
1155 * is check that any locales with the EURO variant format a number using the
1156 * Euro currency symbol.
1158 * ASSUME: All locales encode the Euro character "\u20AC".
1159 * If this is changed to use the single-character Euro symbol, this
1160 * test must be updated.
1164 LocaleTest::TestEuroSupport()
1166 UChar euro
= 0x20ac;
1167 const UnicodeString
EURO_CURRENCY(&euro
, 1, 1); // Look for this UnicodeString in formatted Euro currency
1168 const char* localeArr
[] = {
1192 const char** locales
= localeArr
;
1194 UErrorCode status
= U_ZERO_ERROR
;
1198 for (;*locales
!=NULL
;locales
++) {
1199 Locale
loc (*locales
);
1201 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(loc
, status
);
1204 if (U_FAILURE(status
)) {
1205 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales
);
1209 nf
->format(271828.182845, pos
);
1211 nf
->format(-271828.182845, neg
);
1212 if (pos
.indexOf(EURO_CURRENCY
) >= 0 &&
1213 neg
.indexOf(EURO_CURRENCY
) >= 0) {
1214 logln("Ok: " + (temp
=loc
.getName()) +
1215 ": " + pos
+ " / " + neg
);
1218 errln("Fail: " + (temp
=loc
.getName()) +
1219 " formats without " + EURO_CURRENCY
+
1220 ": " + pos
+ " / " + neg
+
1221 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***");
1227 UnicodeString
dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar
)0x00a4), resultStr
;
1229 status
= U_ZERO_ERROR
;
1231 ucurr_forLocale("en_US", tmp
, 4, &status
);
1232 resultStr
.setTo(tmp
);
1233 if (dollarStr
!= resultStr
) {
1234 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
1236 ucurr_forLocale("en_US_EURO", tmp
, 4, &status
);
1237 resultStr
.setTo(tmp
);
1238 if (euroStr
!= resultStr
) {
1239 errcheckln(status
, "Fail: en_US_EURO didn't return EUR - %s", u_errorName(status
));
1241 ucurr_forLocale("en_GB_EURO", tmp
, 4, &status
);
1242 resultStr
.setTo(tmp
);
1243 if (euroStr
!= resultStr
) {
1244 errcheckln(status
, "Fail: en_GB_EURO didn't return EUR - %s", u_errorName(status
));
1246 ucurr_forLocale("en_US_PREEURO", tmp
, 4, &status
);
1247 resultStr
.setTo(tmp
);
1248 if (dollarStr
!= resultStr
) {
1249 errcheckln(status
, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status
));
1251 ucurr_forLocale("en_US_Q", tmp
, 4, &status
);
1252 resultStr
.setTo(tmp
);
1253 if (dollarStr
!= resultStr
) {
1254 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
1256 int32_t invalidLen
= ucurr_forLocale("en_QQ", tmp
, 4, &status
);
1257 if (invalidLen
|| U_SUCCESS(status
)) {
1258 errln("Fail: en_QQ didn't return NULL");
1266 * toString() doesn't work with language_VARIANT.
1269 LocaleTest::TestToString() {
1271 Locale("xx", "", ""),
1272 Locale("", "YY", ""),
1273 Locale("", "", "ZZ"),
1274 Locale("xx", "YY", ""),
1275 Locale("xx", "", "ZZ"),
1276 Locale("", "YY", "ZZ"),
1277 Locale("xx", "YY", "ZZ"),
1280 const char DATA_S
[][20] = {
1290 for (int32_t i
=0; i
< 7; ++i
) {
1292 name
= DATA
[i
].getName();
1294 if (strcmp(name
, DATA_S
[i
]) != 0)
1296 errln("Fail: Locale.getName(), got:" + UnicodeString(name
) + ", expected: " + DATA_S
[i
]);
1299 logln("Pass: Locale.getName(), got:" + UnicodeString(name
) );
1303 #if !UCONFIG_NO_FORMATTING
1307 * Couldn't reproduce this bug -- probably was fixed earlier.
1309 * ORIGINAL BUG REPORT:
1310 * -- basically, hungarian for monday shouldn't have an \u00f4
1311 * (o circumflex)in it instead it should be an o with 2 inclined
1312 * (right) lines over it..
1314 * You may wonder -- why do all this -- why not just add a line to
1315 * LocaleData? Well, I could see by inspection that the locale file had the
1316 * right character in it, so I wanted to check the rest of the pipeline -- a
1317 * very remote possibility, but I wanted to be sure. The other possibility
1318 * is that something is wrong with the font mapping subsystem, but we can't
1322 LocaleTest::Test4139940()
1324 Locale
mylocale("hu", "", "");
1325 UDate mydate
= date(98,3,13); // A Monday
1326 UErrorCode status
= U_ZERO_ERROR
;
1327 SimpleDateFormat
df_full("EEEE", mylocale
, status
);
1328 if(U_FAILURE(status
)){
1329 dataerrln(UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: ") + UnicodeString(u_errorName(status
)));
1333 FieldPosition
pos(FieldPosition::DONT_CARE
);
1334 df_full
.format(mydate
, str
, pos
);
1335 // Make sure that o circumflex (\u00F4) is NOT there, and
1336 // o double acute (\u0151) IS.
1339 if (str
.indexOf(oda
) < 0 || str
.indexOf(ocf
) >= 0) {
1340 /* If the default locale is "th" this test will fail because of the buddhist calendar. */
1341 if (strcmp(Locale::getDefault().getLanguage(), "th") != 0) {
1342 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
1343 str
.indexOf(oda
), str
.indexOf(ocf
));
1345 logln(UnicodeString("An error is produce in buddhist calendar."));
1347 logln(UnicodeString("String is: ") + str
);
1352 LocaleTest::date(int32_t y
, int32_t m
, int32_t d
, int32_t hr
, int32_t min
, int32_t sec
)
1354 UErrorCode status
= U_ZERO_ERROR
;
1355 Calendar
*cal
= Calendar::createInstance(status
);
1359 cal
->set(1900 + y
, m
, d
, hr
, min
, sec
); // Add 1900 to follow java.util.Date protocol
1360 UDate dt
= cal
->getTime(status
);
1361 if (U_FAILURE(status
))
1370 * Russian first day of week should be Monday. Confirmed.
1373 LocaleTest::Test4143951()
1375 UErrorCode status
= U_ZERO_ERROR
;
1376 Calendar
*cal
= Calendar::createInstance(Locale("ru", "", ""), status
);
1377 if(U_SUCCESS(status
)) {
1378 if (cal
->getFirstDayOfWeek(status
) != UCAL_MONDAY
) {
1379 dataerrln("Fail: First day of week in Russia should be Monday");
1389 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes.
1390 * Should throw an exception for unknown locales
1393 LocaleTest::Test4147315()
1396 // Try with codes that are the wrong length but happen to match text
1397 // at a valid offset in the mapping table
1398 Locale
locale("xxx", "CCC");
1400 const char *result
= locale
.getISO3Country();
1402 // Change to conform to C api usage
1403 if((result
==NULL
)||(result
[0] != 0))
1404 errln("ERROR: getISO3Country() returns: " + UnicodeString(result
,"") +
1405 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1410 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
1411 * Should throw an exception for unknown locales
1414 LocaleTest::Test4147317()
1417 // Try with codes that are the wrong length but happen to match text
1418 // at a valid offset in the mapping table
1419 Locale
locale("xxx", "CCC");
1421 const char *result
= locale
.getISO3Language();
1423 // Change to conform to C api usage
1424 if((result
==NULL
)||(result
[0] != 0))
1425 errln("ERROR: getISO3Language() returns: " + UnicodeString(result
,"") +
1426 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1433 LocaleTest::Test4147552()
1435 Locale locales
[] = { Locale("no", "NO"),
1436 Locale("no", "NO", "B"),
1437 Locale("no", "NO", "NY")
1440 UnicodeString
edn("Norwegian (Norway, B)");
1441 UnicodeString englishDisplayNames
[] = {
1442 "Norwegian (Norway)",
1444 // "Norwegian (Norway,B)",
1445 //"Norwegian (Norway,NY)"
1446 "Norwegian (Norway, NY)"
1448 UnicodeString
ndn("norsk (Norge, B");
1449 UnicodeString norwegianDisplayNames
[] = {
1454 //"Norsk (Noreg, Nynorsk)"
1456 UErrorCode status
= U_ZERO_ERROR
;
1459 Locale::setDefault(Locale::getEnglish(), status
);
1460 for (int32_t i
= 0; i
< 3; ++i
) {
1461 Locale loc
= locales
[i
];
1463 if (loc
.getDisplayName(temp
) != englishDisplayNames
[i
])
1464 dataerrln("English display-name mismatch: expected " +
1465 englishDisplayNames
[i
] + ", got " + loc
.getDisplayName(temp
));
1466 if (loc
.getDisplayName(loc
, temp
) != norwegianDisplayNames
[i
])
1467 dataerrln("Norwegian display-name mismatch: expected " +
1468 norwegianDisplayNames
[i
] + ", got " +
1469 loc
.getDisplayName(loc
, temp
));
1471 Locale::setDefault(saveLocale
, status
);
1475 LocaleTest::TestVariantParsing()
1477 Locale
en_US_custom("en", "US", "De Anza_Cupertino_California_United States_Earth");
1479 UnicodeString
dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)");
1480 UnicodeString
dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH");
1484 en_US_custom
.getDisplayVariant(Locale::getUS(), got
);
1485 if(got
!= dispVar
) {
1486 errln("FAIL: getDisplayVariant()");
1487 errln("Wanted: " + dispVar
);
1488 errln("Got : " + got
);
1491 en_US_custom
.getDisplayName(Locale::getUS(), got
);
1492 if(got
!= dispName
) {
1493 dataerrln("FAIL: getDisplayName()");
1494 dataerrln("Wanted: " + dispName
);
1495 dataerrln("Got : " + got
);
1498 Locale
shortVariant("fr", "FR", "foo");
1499 shortVariant
.getDisplayVariant(got
);
1502 errln("FAIL: getDisplayVariant()");
1503 errln("Wanted: foo");
1504 errln("Got : " + got
);
1507 Locale
bogusVariant("fr", "FR", "_foo");
1508 bogusVariant
.getDisplayVariant(got
);
1511 errln("FAIL: getDisplayVariant()");
1512 errln("Wanted: foo");
1513 errln("Got : " + got
);
1516 Locale
bogusVariant2("fr", "FR", "foo_");
1517 bogusVariant2
.getDisplayVariant(got
);
1520 errln("FAIL: getDisplayVariant()");
1521 errln("Wanted: foo");
1522 errln("Got : " + got
);
1525 Locale
bogusVariant3("fr", "FR", "_foo_");
1526 bogusVariant3
.getDisplayVariant(got
);
1529 errln("FAIL: getDisplayVariant()");
1530 errln("Wanted: foo");
1531 errln("Got : " + got
);
1535 #if !UCONFIG_NO_FORMATTING
1539 * Currency symbol in zh is wrong. We will test this at the NumberFormat
1540 * end to test the whole pipe.
1543 LocaleTest::Test4105828()
1545 Locale LOC
[] = { Locale::getChinese(), Locale("zh", "CN", ""),
1546 Locale("zh", "TW", ""), Locale("zh", "HK", "") };
1547 UErrorCode status
= U_ZERO_ERROR
;
1548 for (int32_t i
= 0; i
< 4; ++i
) {
1549 NumberFormat
*fmt
= NumberFormat::createPercentInstance(LOC
[i
], status
);
1550 if(U_FAILURE(status
)) {
1551 dataerrln("Couldn't create NumberFormat - %s", u_errorName(status
));
1554 UnicodeString result
;
1555 FieldPosition
pos(FieldPosition::DONT_CARE
);
1556 fmt
->format((int32_t)1, result
, pos
);
1558 if(result
!= "100%") {
1559 errln(UnicodeString("Percent for ") + LOC
[i
].getDisplayName(temp
) + " should be 100%, got " + result
);
1567 // Tests setBogus and isBogus APIs for Locale
1570 LocaleTest::TestSetIsBogus() {
1573 if(l
.isBogus() != TRUE
) {
1574 errln("After setting bogus, didn't return TRUE");
1576 l
= "en_US"; // This should reset bogus
1577 if(l
.isBogus() != FALSE
) {
1578 errln("After resetting bogus, didn't return FALSE");
1584 LocaleTest::TestKeywordVariants(void) {
1585 static const struct {
1586 const char *localeID
;
1587 const char *expectedLocaleID
;
1588 //const char *expectedLocaleIDNoKeywords;
1589 //const char *expectedCanonicalID;
1590 const char *expectedKeywords
[10];
1591 int32_t numKeywords
;
1592 UErrorCode expectedStatus
;
1595 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1596 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1598 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1599 {"calendar", "collation", "currency"},
1607 //"de_DE@currency=EUR",
1608 {"","","","","","",""},
1610 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1613 UErrorCode status
= U_ZERO_ERROR
;
1615 int32_t i
= 0, j
= 0;
1616 const char *result
= NULL
;
1617 StringEnumeration
*keywords
;
1618 int32_t keyCount
= 0;
1619 const char *keyword
= NULL
;
1620 const UnicodeString
*keywordString
;
1621 int32_t keywordLen
= 0;
1623 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1624 status
= U_ZERO_ERROR
;
1625 Locale
l(testCases
[i
].localeID
);
1626 keywords
= l
.createKeywords(status
);
1628 if(status
!= testCases
[i
].expectedStatus
) {
1629 err("Expected to get status %s. Got %s instead\n",
1630 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1632 status
= U_ZERO_ERROR
;
1634 if((keyCount
= keywords
->count(status
)) != testCases
[i
].numKeywords
) {
1635 err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1640 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1643 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1644 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1647 if((keywordString
= keywords
->snext(status
)) == NULL
) {
1650 if(*keywordString
!= UnicodeString(testCases
[i
].expectedKeywords
[j
], "")) {
1651 err("Expected to get keyword UnicodeString %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1656 if(j
== keyCount
/ 2) {
1657 // replace keywords with a clone of itself
1658 StringEnumeration
*k2
= keywords
->clone();
1659 if(k2
== NULL
|| keyCount
!= k2
->count(status
)) {
1660 errln("KeywordEnumeration.clone() failed");
1667 keywords
->reset(status
); // Make sure that reset works.
1669 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1672 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1673 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1680 result
= l
.getName();
1681 if(uprv_strcmp(testCases
[i
].expectedLocaleID
, result
) != 0) {
1682 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n",
1683 testCases
[i
].expectedLocaleID
, testCases
[i
].localeID
, result
);
1691 LocaleTest::TestKeywordVariantParsing(void) {
1692 static const struct {
1693 const char *localeID
;
1694 const char *keyword
;
1695 const char *expectedValue
;
1697 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook" },
1698 { "de_DE", "collation", ""},
1699 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" },
1700 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation", "PHONEBOOk" },
1703 UErrorCode status
= U_ZERO_ERROR
;
1706 int32_t resultLen
= 0;
1709 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1711 Locale
l(testCases
[i
].localeID
);
1712 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1713 (void)resultLen
; // Suppress unused variable warning.
1714 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1715 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1716 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1722 LocaleTest::TestSetKeywordValue(void) {
1723 static const struct {
1724 const char *keyword
;
1727 { "collation", "phonebook" },
1728 { "currency", "euro" },
1729 { "calendar", "buddhist" }
1732 UErrorCode status
= U_ZERO_ERROR
;
1735 int32_t resultLen
= 0;
1738 Locale
l(Locale::getGerman());
1740 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1741 l
.setKeywordValue(testCases
[i
].keyword
, testCases
[i
].value
, status
);
1742 if(U_FAILURE(status
)) {
1743 err("FAIL: Locale::setKeywordValue failed - %s\n", u_errorName(status
));
1747 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1748 (void)resultLen
; // Suppress unused variable warning.
1749 if(uprv_strcmp(testCases
[i
].value
, buffer
) != 0) {
1750 err("Expected to extract \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1751 testCases
[i
].value
, testCases
[i
].keyword
, buffer
);
1757 LocaleTest::TestGetBaseName(void) {
1758 static const struct {
1759 const char *localeID
;
1760 const char *baseName
;
1762 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
1763 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
1764 { "ja@calendar = buddhist", "ja" },
1765 { "de-u-co-phonebk", "de"}
1770 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1771 Locale
loc(testCases
[i
].localeID
);
1772 if(strcmp(testCases
[i
].baseName
, loc
.getBaseName())) {
1773 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
1774 testCases
[i
].localeID
, testCases
[i
].baseName
, loc
.getBaseName());
1779 // Verify that adding a keyword to an existing Locale doesn't change the base name.
1780 UErrorCode status
= U_ZERO_ERROR
;
1781 Locale
loc2("en-US");
1782 if (strcmp("en_US", loc2
.getBaseName())) {
1783 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
1785 loc2
.setKeywordValue("key", "value", status
);
1786 if (strcmp("en_US@key=value", loc2
.getName())) {
1787 errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getName());
1789 if (strcmp("en_US", loc2
.getBaseName())) {
1790 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
1795 * Compare two locale IDs. If they are equal, return 0. If `string'
1796 * starts with `prefix' plus an additional element, that is, string ==
1797 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
1799 static UBool
_loccmp(const char* string
, const char* prefix
) {
1800 int32_t slen
= (int32_t)strlen(string
),
1801 plen
= (int32_t)strlen(prefix
);
1802 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
1803 /* 'root' is "less than" everything */
1804 if (uprv_strcmp(prefix
, "root") == 0) {
1805 return (uprv_strcmp(string
, "root") == 0) ? 0 : 1;
1807 if (c
) return -1; /* mismatch */
1808 if (slen
== plen
) return 0;
1809 if (string
[plen
] == '_') return 1;
1810 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
1814 * Check the relationship between requested locales, and report problems.
1815 * The caller specifies the expected relationships between requested
1816 * and valid (expReqValid) and between valid and actual (expValidActual).
1817 * Possible values are:
1818 * "gt" strictly greater than, e.g., en_US > en
1819 * "ge" greater or equal, e.g., en >= en
1820 * "eq" equal, e.g., en == en
1822 void LocaleTest::_checklocs(const char* label
,
1824 const Locale
& validLoc
,
1825 const Locale
& actualLoc
,
1826 const char* expReqValid
,
1827 const char* expValidActual
) {
1828 const char* valid
= validLoc
.getName();
1829 const char* actual
= actualLoc
.getName();
1830 int32_t reqValid
= _loccmp(req
, valid
);
1831 int32_t validActual
= _loccmp(valid
, actual
);
1832 if (((0 == uprv_strcmp(expReqValid
, "gt") && reqValid
> 0) ||
1833 (0 == uprv_strcmp(expReqValid
, "ge") && reqValid
>= 0) ||
1834 (0 == uprv_strcmp(expReqValid
, "eq") && reqValid
== 0)) &&
1835 ((0 == uprv_strcmp(expValidActual
, "gt") && validActual
> 0) ||
1836 (0 == uprv_strcmp(expValidActual
, "ge") && validActual
>= 0) ||
1837 (0 == uprv_strcmp(expValidActual
, "eq") && validActual
== 0))) {
1838 logln("%s; req=%s, valid=%s, actual=%s",
1839 label
, req
, valid
, actual
);
1841 dataerrln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
1842 label
, req
, valid
, actual
,
1843 expReqValid
, expValidActual
);
1847 void LocaleTest::TestGetLocale(void) {
1848 #if !UCONFIG_NO_SERVICE
1850 Locale valid
, actual
, reqLoc
;
1853 #if !UCONFIG_NO_FORMATTING
1855 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1856 req
= "en_US_BROOKLYN";
1857 Calendar
* cal
= Calendar::createInstance(Locale::createFromName(req
), ec
);
1858 if (U_FAILURE(ec
)) {
1859 dataerrln("FAIL: Calendar::createInstance failed - %s", u_errorName(ec
));
1861 valid
= cal
->getLocale(ULOC_VALID_LOCALE
, ec
);
1862 actual
= cal
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1863 if (U_FAILURE(ec
)) {
1864 errln("FAIL: Calendar::getLocale() failed");
1866 _checklocs("Calendar", req
, valid
, actual
);
1868 /* Make sure that it fails correctly */
1869 ec
= U_FILE_ACCESS_ERROR
;
1870 if (cal
->getLocale(ULOC_VALID_LOCALE
, ec
).getName()[0] != 0) {
1871 errln("FAIL: Calendar::getLocale() failed to fail correctly. It should have returned \"\"");
1879 // DecimalFormat, DecimalFormatSymbols
1880 #if !UCONFIG_NO_FORMATTING
1882 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1884 NumberFormat
* nf
= NumberFormat::createInstance(Locale::createFromName(req
), ec
);
1885 if (U_FAILURE(ec
)) {
1886 dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec
));
1888 DecimalFormat
* dec
= dynamic_cast<DecimalFormat
*>(nf
);
1890 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
1893 valid
= dec
->getLocale(ULOC_VALID_LOCALE
, ec
);
1894 actual
= dec
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1895 if (U_FAILURE(ec
)) {
1896 errln("FAIL: DecimalFormat::getLocale() failed");
1898 _checklocs("DecimalFormat", req
, valid
, actual
);
1901 const DecimalFormatSymbols
* sym
= dec
->getDecimalFormatSymbols();
1903 errln("FAIL: getDecimalFormatSymbols returned NULL");
1906 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1907 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1908 if (U_FAILURE(ec
)) {
1909 errln("FAIL: DecimalFormatSymbols::getLocale() failed");
1911 _checklocs("DecimalFormatSymbols", req
, valid
, actual
);
1918 // DateFormat, DateFormatSymbols
1919 #if !UCONFIG_NO_FORMATTING
1921 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1922 req
= "de_CH_LUCERNE";
1924 DateFormat::createDateInstance(DateFormat::kDefault
,
1925 Locale::createFromName(req
));
1927 dataerrln("Error calling DateFormat::createDateInstance()");
1929 SimpleDateFormat
* dat
= dynamic_cast<SimpleDateFormat
*>(df
);
1931 errln("FAIL: DateFormat::createInstance does not return a SimpleDateFormat");
1934 valid
= dat
->getLocale(ULOC_VALID_LOCALE
, ec
);
1935 actual
= dat
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1936 if (U_FAILURE(ec
)) {
1937 errln("FAIL: SimpleDateFormat::getLocale() failed");
1939 _checklocs("SimpleDateFormat", req
, valid
, actual
);
1942 const DateFormatSymbols
* sym
= dat
->getDateFormatSymbols();
1944 errln("FAIL: getDateFormatSymbols returned NULL");
1947 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1948 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1949 if (U_FAILURE(ec
)) {
1950 errln("FAIL: DateFormatSymbols::getLocale() failed");
1952 _checklocs("DateFormatSymbols", req
, valid
, actual
);
1960 #if !UCONFIG_NO_BREAK_ITERATION
1962 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1963 req
= "es_ES_BARCELONA";
1964 reqLoc
= Locale::createFromName(req
);
1965 BreakIterator
* brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1966 if (U_FAILURE(ec
)) {
1967 dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_errorName(ec
));
1969 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1970 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1971 if (U_FAILURE(ec
)) {
1972 errln("FAIL: BreakIterator::getLocale() failed");
1974 _checklocs("BreakIterator", req
, valid
, actual
);
1977 // After registering something, the behavior should be different
1978 URegistryKey key
= BreakIterator::registerInstance(brk
, reqLoc
, UBRK_WORD
, ec
);
1979 brk
= 0; // registerInstance adopts
1980 if (U_FAILURE(ec
)) {
1981 errln("FAIL: BreakIterator::registerInstance() failed");
1983 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1984 if (U_FAILURE(ec
)) {
1985 errln("FAIL: BreakIterator::createWordInstance failed");
1987 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1988 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1989 if (U_FAILURE(ec
)) {
1990 errln("FAIL: BreakIterator::getLocale() failed");
1992 // N.B.: now expect valid==actual==req
1993 _checklocs("BreakIterator(registered)",
1994 req
, valid
, actual
, "eq", "eq");
1997 // No matter what, unregister
1998 BreakIterator::unregister(key
, ec
);
1999 if (U_FAILURE(ec
)) {
2000 errln("FAIL: BreakIterator::unregister() failed");
2006 // After unregistering, should behave normally again
2007 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2008 if (U_FAILURE(ec
)) {
2009 errln("FAIL: BreakIterator::createWordInstance failed");
2011 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2012 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2013 if (U_FAILURE(ec
)) {
2014 errln("FAIL: BreakIterator::getLocale() failed");
2016 _checklocs("BreakIterator(unregistered)", req
, valid
, actual
);
2025 #if !UCONFIG_NO_COLLATION
2027 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2029 checkRegisteredCollators(NULL
); // Don't expect any extras
2031 req
= "hi_IN_BHOPAL";
2032 reqLoc
= Locale::createFromName(req
);
2033 Collator
* coll
= Collator::createInstance(reqLoc
, ec
);
2034 if (U_FAILURE(ec
)) {
2035 dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(ec
));
2037 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2038 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2039 if (U_FAILURE(ec
)) {
2040 errln("FAIL: Collator::getLocale() failed");
2042 _checklocs("Collator", req
, valid
, actual
);
2045 // After registering something, the behavior should be different
2046 URegistryKey key
= Collator::registerInstance(coll
, reqLoc
, ec
);
2047 coll
= 0; // registerInstance adopts
2048 if (U_FAILURE(ec
)) {
2049 errln("FAIL: Collator::registerInstance() failed");
2051 coll
= Collator::createInstance(reqLoc
, ec
);
2052 if (U_FAILURE(ec
)) {
2053 errln("FAIL: Collator::createWordInstance failed");
2055 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2056 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2057 if (U_FAILURE(ec
)) {
2058 errln("FAIL: Collator::getLocale() failed");
2060 // N.B.: now expect valid==actual==req
2061 _checklocs("Collator(registered)",
2062 req
, valid
, actual
, "eq", "eq");
2065 checkRegisteredCollators(req
); // include hi_IN_BHOPAL
2067 // No matter what, unregister
2068 Collator::unregister(key
, ec
);
2069 if (U_FAILURE(ec
)) {
2070 errln("FAIL: Collator::unregister() failed");
2076 // After unregistering, should behave normally again
2077 coll
= Collator::createInstance(reqLoc
, ec
);
2078 if (U_FAILURE(ec
)) {
2079 errln("FAIL: Collator::createInstance failed");
2081 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2082 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2083 if (U_FAILURE(ec
)) {
2084 errln("FAIL: Collator::getLocale() failed");
2086 _checklocs("Collator(unregistered)", req
, valid
, actual
);
2092 checkRegisteredCollators(NULL
); // extra should be gone again
2098 #if !UCONFIG_NO_COLLATION
2100 * Compare Collator::getAvailableLocales(int) [ "old", returning an array ]
2101 * with Collator::getAvailableLocales() [ "new", returning a StringEnumeration ]
2102 * These should be identical (check their API docs) EXCEPT that
2103 * if expectExtra is non-NULL, it will be in the "new" array but not "old".
2104 * Does not return any status but calls errln on error.
2105 * @param expectExtra an extra locale, will be in "new" but not "old". Or NULL.
2107 void LocaleTest::checkRegisteredCollators(const char *expectExtra
) {
2108 UErrorCode status
= U_ZERO_ERROR
;
2109 int32_t count1
=0,count2
=0;
2110 Hashtable
oldHash(status
);
2111 Hashtable
newHash(status
);
2112 TEST_ASSERT_STATUS(status
);
2114 UnicodeString
expectStr(expectExtra
?expectExtra
:"n/a", "");
2116 // the 'old' list (non enumeration)
2117 const Locale
* oldList
= Collator::getAvailableLocales(count1
);
2118 if(oldList
== NULL
) {
2119 dataerrln("Error: Collator::getAvailableLocales(count) returned NULL");
2123 // the 'new' list (enumeration)
2124 LocalPointer
<StringEnumeration
> newEnum(Collator::getAvailableLocales());
2125 if(newEnum
.isNull()) {
2126 errln("Error: collator::getAvailableLocales() returned NULL");
2130 // OK. Let's add all of the OLD
2131 // then check for any in the NEW not in OLD
2132 // then check for any in OLD not in NEW.
2134 // 1. add all of OLD
2135 for(int32_t i
=0;i
<count1
;i
++) {
2136 const UnicodeString
key(oldList
[i
].getName(), "");
2137 int32_t oldI
= oldHash
.puti(key
, 1, status
);
2139 errln("Error: duplicate key %s in Collator::getAvailableLocales(count) list.\n",
2140 oldList
[i
].getName());
2143 if(expectExtra
!= NULL
&& !strcmp(expectExtra
, oldList
[i
].getName())) {
2144 errln("Inexplicably, Collator::getAvailableCollators(count) had registered collator %s. This shouldn't happen, so I am going to consider it an error.\n", expectExtra
);
2148 // 2. add all of NEW
2149 const UnicodeString
*locStr
;
2150 UBool foundExpected
= FALSE
;
2151 while((locStr
= newEnum
->snext(status
)) && U_SUCCESS(status
)) {
2154 if(expectExtra
!= NULL
&& expectStr
== *locStr
) {
2155 foundExpected
= TRUE
;
2156 logln(UnicodeString("Found expected registered collator: ","") + expectStr
);
2158 (void)foundExpected
; // Hush unused variable compiler warning.
2160 if( oldHash
.geti(*locStr
) == 0 ) {
2161 if(expectExtra
!= NULL
&& expectStr
==*locStr
) {
2162 logln(UnicodeString("As expected, Collator::getAvailableLocales(count) is missing registered collator ") + expectStr
);
2164 errln(UnicodeString("Error: Collator::getAvailableLocales(count) is missing: ","")
2168 newHash
.puti(*locStr
, 1, status
);
2171 // 3. check all of OLD again
2172 for(int32_t i
=0;i
<count1
;i
++) {
2173 const UnicodeString
key(oldList
[i
].getName(), "");
2174 int32_t newI
= newHash
.geti(key
);
2176 errln(UnicodeString("Error: Collator::getAvailableLocales() is missing: ","")
2181 int32_t expectCount2
= count1
;
2182 if(expectExtra
!= NULL
) {
2183 expectCount2
++; // if an extra item registered, bump the expect count
2186 assertEquals("Collator::getAvail() count", expectCount2
, count2
);
2192 void LocaleTest::TestVariantWithOutCountry(void) {
2193 Locale
loc("en","","POSIX");
2194 if (0 != strcmp(loc
.getVariant(), "POSIX")) {
2195 errln("FAIL: en__POSIX didn't get parsed correctly - name is %s - expected %s got %s", loc
.getName(), "POSIX", loc
.getVariant());
2197 Locale
loc2("en","","FOUR");
2198 if (0 != strcmp(loc2
.getVariant(), "FOUR")) {
2199 errln("FAIL: en__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc2
.getName(), "FOUR", loc2
.getVariant());
2201 Locale
loc3("en","Latn","","FOUR");
2202 if (0 != strcmp(loc3
.getVariant(), "FOUR")) {
2203 errln("FAIL: en_Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc3
.getName(), "FOUR", loc3
.getVariant());
2205 Locale
loc4("","Latn","","FOUR");
2206 if (0 != strcmp(loc4
.getVariant(), "FOUR")) {
2207 errln("FAIL: _Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc4
.getName(), "FOUR", loc4
.getVariant());
2209 Locale
loc5("","Latn","US","FOUR");
2210 if (0 != strcmp(loc5
.getVariant(), "FOUR")) {
2211 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc5
.getName(), "FOUR", loc5
.getVariant());
2213 Locale
loc6("de-1901");
2214 if (0 != strcmp(loc6
.getVariant(), "1901")) {
2215 errln("FAIL: de-1901 didn't get parsed correctly - name is %s - expected %s got %s", loc6
.getName(), "1901", loc6
.getVariant());
2219 static Locale
_canonicalize(int32_t selector
, /* 0==createFromName, 1==createCanonical, 2==Locale ct */
2220 const char* localeID
) {
2223 return Locale::createFromName(localeID
);
2225 return Locale::createCanonical(localeID
);
2227 return Locale(localeID
);
2233 void LocaleTest::TestCanonicalization(void)
2235 static const struct {
2236 const char *localeID
; /* input */
2237 const char *getNameID
; /* expected getName() result */
2238 const char *canonicalID
; /* expected canonicalize() result */
2240 { "", "", "en_US_POSIX" },
2241 { "C", "c", "en_US_POSIX" },
2242 { "POSIX", "posix", "en_US_POSIX" },
2243 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2244 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2245 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2246 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
2247 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
2248 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
2249 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
2250 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
2251 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
2252 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
2253 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
2254 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
2255 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
2256 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
2257 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
2258 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
2259 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
2260 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
2261 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
2262 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
2263 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
2264 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
2265 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
2266 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
2267 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
2268 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
2269 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
2270 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
2271 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
2272 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
2273 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
2274 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2275 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2276 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2277 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2278 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2279 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2280 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2281 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2282 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
2283 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
2284 // TODO: unify this behavior
2285 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
2286 { "de-1901", "de__1901", "de__1901" }, /* registered name */
2287 { "de-1906", "de__1906", "de__1906" }, /* registered name */
2288 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
2289 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
2290 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
2291 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
2292 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
2293 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
2294 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
2296 /* posix behavior that used to be performed by getName */
2297 { "mr.utf8", "mr.utf8", "mr" },
2298 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2299 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2300 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2301 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2302 { "no-no-ny.utf8@B", "no_NO_NY.utf8@B", "no_NO_NY_B" /* not: "nn_NO" [alan ICU3.0] */ }, /* @ ignored unless variant is empty */
2304 /* fleshing out canonicalization */
2305 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2306 { "en_Hant_IL_VALLEY_GIRL@ currency = EUR; calendar = Japanese ;", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
2307 /* already-canonical ids are not changed */
2308 { "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
2309 /* PRE_EURO and EURO conversions don't affect other keywords */
2310 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
2311 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
2312 /* currency keyword overrides PRE_EURO and EURO currency */
2313 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
2314 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
2315 /* norwegian is just too weird, if we handle things in their full generality */
2316 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2318 /* test cases reflecting internal resource bundle usage */
2319 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2320 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2321 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" }
2324 static const char* label
[] = { "createFromName", "createCanonical", "Locale" };
2328 for (i
=0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2329 for (j
=0; j
<3; ++j
) {
2330 const char* expected
= (j
==1) ? testCases
[i
].canonicalID
: testCases
[i
].getNameID
;
2331 Locale loc
= _canonicalize(j
, testCases
[i
].localeID
);
2332 const char* getName
= loc
.isBogus() ? "BOGUS" : loc
.getName();
2333 if(uprv_strcmp(expected
, getName
) != 0) {
2334 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"",
2335 label
[j
], testCases
[i
].localeID
, getName
, expected
);
2337 logln("Ok: %s(%s) => \"%s\"",
2338 label
[j
], testCases
[i
].localeID
, getName
);
2344 void LocaleTest::TestCurrencyByDate(void)
2346 #if !UCONFIG_NO_FORMATTING
2347 UErrorCode status
= U_ZERO_ERROR
;
2348 UDate date
= uprv_getUTCtime();
2352 UnicodeString tempStr
, resultStr
;
2354 // Cycle through historical currencies
2355 date
= (UDate
)-630720000000.0; // pre 1961 - no currency defined
2356 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2359 errcheckln(status
, "FAIL: didn't return 0 for eo_AM - %s", u_errorName(status
));
2361 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2363 errcheckln(status
, "FAIL: eo_AM didn't return NULL - %s", u_errorName(status
));
2365 status
= U_ZERO_ERROR
;
2367 date
= (UDate
)0.0; // 1970 - one currency defined
2368 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2371 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2373 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2375 resultStr
.setTo("SUR");
2376 if (resultStr
!= tempStr
) {
2377 errcheckln(status
, "FAIL: didn't return SUR for eo_AM - %s", u_errorName(status
));
2380 date
= (UDate
)693792000000.0; // 1992 - one currency defined
2381 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2384 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2386 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2388 resultStr
.setTo("RUR");
2389 if (resultStr
!= tempStr
) {
2390 errcheckln(status
, "FAIL: didn't return RUR for eo_AM - %s", u_errorName(status
));
2393 date
= (UDate
)977616000000.0; // post 1993 - one currency defined
2394 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2397 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2399 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2401 resultStr
.setTo("AMD");
2402 if (resultStr
!= tempStr
) {
2403 errcheckln(status
, "FAIL: didn't return AMD for eo_AM - %s", u_errorName(status
));
2406 // Locale AD has multiple currencies at once
2407 date
= (UDate
)977616000000.0; // year 2001
2408 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2411 errcheckln(status
, "FAIL: didn't return 4 for eo_AD - %s", u_errorName(status
));
2413 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2415 resultStr
.setTo("EUR");
2416 if (resultStr
!= tempStr
) {
2417 errcheckln(status
, "FAIL: didn't return EUR for eo_AD - %s", u_errorName(status
));
2419 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2421 resultStr
.setTo("ESP");
2422 if (resultStr
!= tempStr
) {
2423 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2425 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2427 resultStr
.setTo("FRF");
2428 if (resultStr
!= tempStr
) {
2429 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2431 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 4, TMP
, 4, &status
);
2433 resultStr
.setTo("ADP");
2434 if (resultStr
!= tempStr
) {
2435 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2438 date
= (UDate
)0.0; // year 1970
2439 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2442 errcheckln(status
, "FAIL: didn't return 3 for eo_AD - %s", u_errorName(status
));
2444 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2446 resultStr
.setTo("ESP");
2447 if (resultStr
!= tempStr
) {
2448 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2450 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2452 resultStr
.setTo("FRF");
2453 if (resultStr
!= tempStr
) {
2454 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2456 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2458 resultStr
.setTo("ADP");
2459 if (resultStr
!= tempStr
) {
2460 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2463 date
= (UDate
)-630720000000.0; // year 1950
2464 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2467 errcheckln(status
, "FAIL: didn't return 2 for eo_AD - %s", u_errorName(status
));
2469 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2471 resultStr
.setTo("ESP");
2472 if (resultStr
!= tempStr
) {
2473 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2475 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2477 resultStr
.setTo("ADP");
2478 if (resultStr
!= tempStr
) {
2479 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2482 date
= (UDate
)-2207520000000.0; // year 1900
2483 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2486 errcheckln(status
, "FAIL: didn't return 1 for eo_AD - %s", u_errorName(status
));
2488 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2490 resultStr
.setTo("ESP");
2491 if (resultStr
!= tempStr
) {
2492 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2495 // Locale UA has gap between years 1994 - 1996
2496 date
= (UDate
)788400000000.0;
2497 index
= ucurr_countCurrencies("eo_UA", date
, &status
);
2500 errcheckln(status
, "FAIL: didn't return 0 for eo_UA - %s", u_errorName(status
));
2502 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, index
, TMP
, 4, &status
);
2504 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2506 status
= U_ZERO_ERROR
;
2508 // Test index bounds
2509 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 100, TMP
, 4, &status
);
2511 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2513 status
= U_ZERO_ERROR
;
2515 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 0, TMP
, 4, &status
);
2517 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2519 status
= U_ZERO_ERROR
;
2521 // Test for bogus locale
2522 index
= ucurr_countCurrencies("eo_QQ", date
, &status
);
2525 errcheckln(status
, "FAIL: didn't return 0 for eo_QQ - %s", u_errorName(status
));
2527 status
= U_ZERO_ERROR
;
2528 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 1, TMP
, 4, &status
);
2530 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2532 status
= U_ZERO_ERROR
;
2533 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 0, TMP
, 4, &status
);
2535 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2537 status
= U_ZERO_ERROR
;
2539 // Cycle through histrocial currencies
2540 date
= (UDate
)977616000000.0; // 2001 - one currency
2541 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2544 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2546 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2548 resultStr
.setTo("AOA");
2549 if (resultStr
!= tempStr
) {
2550 errcheckln(status
, "FAIL: didn't return AOA for eo_AO - %s", u_errorName(status
));
2553 date
= (UDate
)819936000000.0; // 1996 - 2 currencies
2554 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2557 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2559 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2561 resultStr
.setTo("AOR");
2562 if (resultStr
!= tempStr
) {
2563 errcheckln(status
, "FAIL: didn't return AOR for eo_AO - %s", u_errorName(status
));
2565 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2567 resultStr
.setTo("AON");
2568 if (resultStr
!= tempStr
) {
2569 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2572 date
= (UDate
)662256000000.0; // 1991 - 2 currencies
2573 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2576 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2578 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2580 resultStr
.setTo("AON");
2581 if (resultStr
!= tempStr
) {
2582 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2584 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2586 resultStr
.setTo("AOK");
2587 if (resultStr
!= tempStr
) {
2588 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2591 date
= (UDate
)315360000000.0; // 1980 - one currency
2592 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2595 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2597 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2599 resultStr
.setTo("AOK");
2600 if (resultStr
!= tempStr
) {
2601 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2604 date
= (UDate
)0.0; // 1970 - no currencies
2605 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2608 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2610 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2612 errcheckln(status
, "FAIL: eo_AO didn't return NULL - %s", u_errorName(status
));
2614 status
= U_ZERO_ERROR
;
2616 // Test with currency keyword override
2617 date
= (UDate
)977616000000.0; // 2001 - two currencies
2618 index
= ucurr_countCurrencies("eo_DE@currency=DEM", date
, &status
);
2621 errcheckln(status
, "FAIL: didn't return 2 for eo_DE@currency=DEM - %s", u_errorName(status
));
2623 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 1, TMP
, 4, &status
);
2625 resultStr
.setTo("EUR");
2626 if (resultStr
!= tempStr
) {
2627 errcheckln(status
, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s", u_errorName(status
));
2629 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 2, TMP
, 4, &status
);
2631 resultStr
.setTo("DEM");
2632 if (resultStr
!= tempStr
) {
2633 errcheckln(status
, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s", u_errorName(status
));
2636 // Test Euro Support
2637 status
= U_ZERO_ERROR
; // reset
2638 date
= uprv_getUTCtime();
2641 ucurr_forLocaleAndDate("en_US", date
, 1, USD
, 4, &status
);
2644 ucurr_forLocaleAndDate("ja_JP", date
, 1, YEN
, 4, &status
);
2646 ucurr_forLocaleAndDate("en_US", date
, 1, TMP
, 4, &status
);
2647 if (u_strcmp(USD
, TMP
) != 0) {
2648 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
2650 ucurr_forLocaleAndDate("en_US_PREEURO", date
, 1, TMP
, 4, &status
);
2651 if (u_strcmp(USD
, TMP
) != 0) {
2652 errcheckln(status
, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status
));
2654 ucurr_forLocaleAndDate("en_US_Q", date
, 1, TMP
, 4, &status
);
2655 if (u_strcmp(USD
, TMP
) != 0) {
2656 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
2658 status
= U_ZERO_ERROR
; // reset
2662 void LocaleTest::TestGetVariantWithKeywords(void)
2664 Locale
l("en_US_VALLEY@foo=value");
2665 const char *variant
= l
.getVariant();
2667 test_assert(strcmp("VALLEY", variant
) == 0);
2669 UErrorCode status
= U_ZERO_ERROR
;
2671 int32_t len
= l
.getKeywordValue("foo", buffer
, 50, status
);
2673 test_assert(strcmp("value", buffer
) == 0);
2676 void LocaleTest::TestIsRightToLeft() {
2677 assertFalse("root LTR", Locale::getRoot().isRightToLeft());
2678 assertFalse("zh LTR", Locale::getChinese().isRightToLeft());
2679 assertTrue("ar RTL", Locale("ar").isRightToLeft());
2680 assertTrue("und-EG RTL", Locale("und-EG").isRightToLeft(), FALSE
, TRUE
);
2681 assertFalse("fa-Cyrl LTR", Locale("fa-Cyrl").isRightToLeft());
2682 assertTrue("en-Hebr RTL", Locale("en-Hebr").isRightToLeft());
2683 assertTrue("ckb RTL", Locale("ckb").isRightToLeft(), FALSE
, TRUE
); // Sorani Kurdish
2684 assertFalse("fil LTR", Locale("fil").isRightToLeft());
2685 assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft());
2688 void LocaleTest::TestBug11421() {
2689 Locale::getDefault().getBaseName();
2691 const Locale
*localeList
= Locale::getAvailableLocales(numLocales
);
2692 for (int localeIndex
= 0; localeIndex
< numLocales
; localeIndex
++) {
2693 const Locale
&loc
= localeList
[localeIndex
];
2694 if (strncmp(loc
.getName(), loc
.getBaseName(), strlen(loc
.getBaseName()))) {
2695 errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"",
2696 __FILE__
, __LINE__
, loc
.getName(), loc
.getBaseName());