1 /********************************************************************
3 * Copyright (c) 1997-2015, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
8 #include "unicode/decimfmt.h"
9 #include "unicode/ucurr.h"
10 #include "unicode/smpdtfmt.h"
11 #include "unicode/dtfmtsym.h"
12 #include "unicode/brkiter.h"
13 #include "unicode/coll.h"
18 #include "unicode/ustring.h"
21 static const char* const rawData
[33][8] = {
24 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
26 { "", "", "", "", "", "", "", "Hans" },
28 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" },
30 { "", "", "", "", "NY", "", "", "" },
32 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" },
34 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" },
36 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" },
38 { "409", "40c", "403", "408", "814", "10", "0", "804" },
40 // display langage (English)
41 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" },
42 // display script (English)
43 { "", "", "", "", "", "", "", "Simplified Han" },
44 // display country (English)
45 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China" },
46 // display variant (English)
47 { "", "", "", "", "NY", "", "", ""},
48 // display name (English)
49 // Updated no_NO_NY English display name for new pattern-based algorithm
50 // (part of Euro support).
51 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplified, China)" },
53 // display langage (French)
54 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
55 // display script (French)
56 { "", "", "", "", "", "", "", "sinogrammes simplifi\\u00E9s" },
57 // display country (French)
58 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine" },
59 // display variant (French)
60 { "", "", "", "", "NY", "", "", "" },
61 // display name (French)
62 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
63 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois (simplifi\\u00E9, Chine)" },
66 /* display language (Catalan) */
67 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E8s" },
68 /* display script (Catalan) */
69 { "", "", "", "", "", "", "", "han simplificat" },
70 /* display country (Catalan) */
71 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina" },
72 /* display variant (Catalan) */
73 { "", "", "", "", "NY", "", "" },
74 /* display name (Catalan) */
75 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E8s (simplificat, Xina)" },
77 // display langage (Greek)[actual values listed below]
78 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
79 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
80 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
81 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
82 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
83 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
85 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
87 // display script (Greek)
88 { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd" },
89 // display country (Greek)[actual values listed below]
90 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
91 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
92 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
93 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
94 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
97 "\\u039A\\u03AF\\u03BD\\u03B1"
99 // display variant (Greek)
100 { "", "", "", "", "NY", "", "" },
101 // display name (Greek)[actual values listed below]
102 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
103 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
104 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
105 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
106 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
107 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
109 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf, \\u039A\\u03AF\\u03BD\\u03B1)"
112 // display langage (<root>)
113 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" },
114 // display script (<root>)
115 { "", "", "", "", "", "", "", ""},
116 // display country (<root>)
117 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" },
118 // display variant (<root>)
119 { "", "", "", "", "Nynorsk", "", "", ""},
120 // display name (<root>)
121 //{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" },
122 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
128 test_assert( Test (should be TRUE) )
133 the macro is ugly but makes the tests pretty.
136 #define test_assert(test) \
139 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \
141 logln("PASS: asserted " #test); \
146 test_assert_print( Test (should be TRUE), printable )
149 test_assert(i==3, toString(i));
151 the macro is ugly but makes the tests pretty.
154 #define test_assert_print(test,print) \
157 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \
159 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \
163 #define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); }
165 LocaleTest::LocaleTest()
171 LocaleTest::~LocaleTest()
173 if (dataTable
!= 0) {
174 for (int32_t i
= 0; i
< 33; i
++) {
175 delete []dataTable
[i
];
182 void LocaleTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
185 TESTCASE_AUTO(TestBug11421
); // Must run early in list to trigger failure.
186 TESTCASE_AUTO(TestBasicGetters
);
187 TESTCASE_AUTO(TestSimpleResourceInfo
);
188 TESTCASE_AUTO(TestDisplayNames
);
189 TESTCASE_AUTO(TestSimpleObjectStuff
);
190 TESTCASE_AUTO(TestPOSIXParsing
);
191 TESTCASE_AUTO(TestGetAvailableLocales
);
192 TESTCASE_AUTO(TestDataDirectory
);
193 TESTCASE_AUTO(TestISO3Fallback
);
194 TESTCASE_AUTO(TestGetLangsAndCountries
);
195 TESTCASE_AUTO(TestSimpleDisplayNames
);
196 TESTCASE_AUTO(TestUninstalledISO3Names
);
197 TESTCASE_AUTO(TestAtypicalLocales
);
198 #if !UCONFIG_NO_FORMATTING
199 TESTCASE_AUTO(TestThaiCurrencyFormat
);
200 TESTCASE_AUTO(TestEuroSupport
);
202 TESTCASE_AUTO(TestToString
);
203 #if !UCONFIG_NO_FORMATTING
204 TESTCASE_AUTO(Test4139940
);
205 TESTCASE_AUTO(Test4143951
);
207 TESTCASE_AUTO(Test4147315
);
208 TESTCASE_AUTO(Test4147317
);
209 TESTCASE_AUTO(Test4147552
);
210 TESTCASE_AUTO(TestVariantParsing
);
211 #if !UCONFIG_NO_FORMATTING
212 TESTCASE_AUTO(Test4105828
);
214 TESTCASE_AUTO(TestSetIsBogus
);
215 TESTCASE_AUTO(TestParallelAPIValues
);
216 TESTCASE_AUTO(TestKeywordVariants
);
217 TESTCASE_AUTO(TestKeywordVariantParsing
);
218 TESTCASE_AUTO(TestSetKeywordValue
);
219 TESTCASE_AUTO(TestGetBaseName
);
220 #if !UCONFIG_NO_FILE_IO
221 TESTCASE_AUTO(TestGetLocale
);
223 TESTCASE_AUTO(TestVariantWithOutCountry
);
224 TESTCASE_AUTO(TestCanonicalization
);
225 TESTCASE_AUTO(TestCurrencyByDate
);
226 TESTCASE_AUTO(TestGetVariantWithKeywords
);
227 TESTCASE_AUTO(TestIsRightToLeft
);
231 void LocaleTest::TestBasicGetters() {
235 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
236 Locale
testLocale("");
237 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
238 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
241 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
243 logln("Testing " + (UnicodeString
)testLocale
.getName() + "...");
245 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
246 errln(" Language code mismatch: " + temp
+ " versus "
247 + dataTable
[LANG
][i
]);
248 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
249 errln(" Script code mismatch: " + temp
+ " versus "
250 + dataTable
[SCRIPT
][i
]);
251 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
252 errln(" Country code mismatch: " + temp
+ " versus "
253 + dataTable
[CTRY
][i
]);
254 if ( (temp
=testLocale
.getVariant()) != (dataTable
[VAR
][i
]))
255 errln(" Variant code mismatch: " + temp
+ " versus "
256 + dataTable
[VAR
][i
]);
257 if ( (temp
=testLocale
.getName()) != (dataTable
[NAME
][i
]))
258 errln(" Locale name mismatch: " + temp
+ " versus "
259 + dataTable
[NAME
][i
]);
262 logln("Same thing without variant codes...");
263 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
264 Locale
testLocale("");
265 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
266 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
]);
269 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
]);
271 logln("Testing " + (temp
=testLocale
.getName()) + "...");
273 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
274 errln("Language code mismatch: " + temp
+ " versus "
275 + dataTable
[LANG
][i
]);
276 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
277 errln("Script code mismatch: " + temp
+ " versus "
278 + dataTable
[SCRIPT
][i
]);
279 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
280 errln("Country code mismatch: " + temp
+ " versus "
281 + dataTable
[CTRY
][i
]);
282 if (testLocale
.getVariant()[0] != 0)
283 errln("Variant code mismatch: something versus \"\"");
286 logln("Testing long language names and getters");
287 Locale test8
= Locale::createFromName("x-klingon-latn-zx.utf32be@special");
289 temp
= test8
.getLanguage();
290 if (temp
!= UnicodeString("x-klingon") )
291 errln("Language code mismatch: " + temp
+ " versus \"x-klingon\"");
293 temp
= test8
.getScript();
294 if (temp
!= UnicodeString("Latn") )
295 errln("Script code mismatch: " + temp
+ " versus \"Latn\"");
297 temp
= test8
.getCountry();
298 if (temp
!= UnicodeString("ZX") )
299 errln("Country code mismatch: " + temp
+ " versus \"ZX\"");
301 temp
= test8
.getVariant();
302 //if (temp != UnicodeString("SPECIAL") )
303 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\"");
304 // As of 3.0, the "@special" will *not* be parsed by uloc_getName()
305 if (temp
!= UnicodeString("") )
306 errln("Variant code mismatch: " + temp
+ " versus \"\"");
308 if (Locale::getDefault() != Locale::createFromName(NULL
))
309 errln("Locale::getDefault() == Locale::createFromName(NULL)");
312 // NOTE: There used to be a special test for locale names that had language or
313 // country codes that were longer than two letters. The new version of Locale
314 // doesn't support anything that isn't an officially recognized language or
315 // country code, so we no longer support this feature.
317 Locale
bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code too long
318 if(!bogusLang
.isBogus()) {
319 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE");
322 bogusLang
=Locale("eo");
323 if( bogusLang
.isBogus() ||
324 strcmp(bogusLang
.getLanguage(), "eo")!=0 ||
325 *bogusLang
.getCountry()!=0 ||
326 *bogusLang
.getVariant()!=0 ||
327 strcmp(bogusLang
.getName(), "eo")!=0
329 errln("assignment to bogus Locale does not unbogus it or sets bad data");
332 Locale
a("eo_DE@currency=DEM");
333 Locale
*pb
=a
.clone();
334 if(pb
==&a
|| *pb
!=a
) {
335 errln("Locale.clone() failed");
340 void LocaleTest::TestParallelAPIValues() {
341 logln("Test synchronization between C and C++ API");
342 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE
) != 0) {
343 errln("Differences for ULOC_CHINESE Locale");
345 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH
) != 0) {
346 errln("Differences for ULOC_ENGLISH Locale");
348 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH
) != 0) {
349 errln("Differences for ULOC_FRENCH Locale");
351 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN
) != 0) {
352 errln("Differences for ULOC_GERMAN Locale");
354 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN
) != 0) {
355 errln("Differences for ULOC_ITALIAN Locale");
357 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE
) != 0) {
358 errln("Differences for ULOC_JAPANESE Locale");
360 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN
) != 0) {
361 errln("Differences for ULOC_KOREAN Locale");
363 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE
) != 0) {
364 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale");
366 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINESE
) != 0) {
367 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale");
371 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA
) != 0) {
372 errln("Differences for ULOC_CANADA Locale");
374 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH
) != 0) {
375 errln("Differences for ULOC_CANADA_FRENCH Locale");
377 if (strcmp(Locale::getChina().getName(), ULOC_CHINA
) != 0) {
378 errln("Differences for ULOC_CHINA Locale");
380 if (strcmp(Locale::getPRC().getName(), ULOC_PRC
) != 0) {
381 errln("Differences for ULOC_PRC Locale");
383 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE
) != 0) {
384 errln("Differences for ULOC_FRANCE Locale");
386 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY
) != 0) {
387 errln("Differences for ULOC_GERMANY Locale");
389 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY
) != 0) {
390 errln("Differences for ULOC_ITALY Locale");
392 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN
) != 0) {
393 errln("Differences for ULOC_JAPAN Locale");
395 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA
) != 0) {
396 errln("Differences for ULOC_KOREA Locale");
398 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN
) != 0) {
399 errln("Differences for ULOC_TAIWAN Locale");
401 if (strcmp(Locale::getUK().getName(), ULOC_UK
) != 0) {
402 errln("Differences for ULOC_UK Locale");
404 if (strcmp(Locale::getUS().getName(), ULOC_US
) != 0) {
405 errln("Differences for ULOC_US Locale");
410 void LocaleTest::TestSimpleResourceInfo() {
413 UErrorCode err
= U_ZERO_ERROR
;
416 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
417 Locale
testLocale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
418 logln("Testing " + (temp
=testLocale
.getName()) + "...");
420 if ( (temp
=testLocale
.getISO3Language()) != (dataTable
[LANG3
][i
]))
421 errln(" ISO-3 language code mismatch: " + temp
422 + " versus " + dataTable
[LANG3
][i
]);
423 if ( (temp
=testLocale
.getISO3Country()) != (dataTable
[CTRY3
][i
]))
424 errln(" ISO-3 country code mismatch: " + temp
425 + " versus " + dataTable
[CTRY3
][i
]);
427 sprintf(temp2
, "%x", (int)testLocale
.getLCID());
428 if (UnicodeString(temp2
) != dataTable
[LCID
][i
])
429 errln((UnicodeString
)" LCID mismatch: " + temp2
+ " versus "
430 + dataTable
[LCID
][i
]);
434 errln((UnicodeString
)"Some error on number " + i
+ u_errorName(err
));
440 if(strcmp(locale
.getName(), "en") != 0||
441 strcmp(locale
.getLanguage(), "en") != 0) {
442 errln("construction of Locale(en) failed\n");
449 * Jitterbug 2439 -- markus 20030425
451 * The lookup of display names must not fall back through the default
452 * locale because that yields useless results.
455 LocaleTest::TestDisplayNames()
457 Locale
english("en", "US");
458 Locale
french("fr", "FR");
459 Locale
croatian("ca", "ES");
460 Locale
greek("el", "GR");
462 logln(" In locale = en_US...");
463 doTestDisplayNames(english
, DLANG_EN
);
464 logln(" In locale = fr_FR...");
465 doTestDisplayNames(french
, DLANG_FR
);
466 logln(" In locale = ca_ES...");
467 doTestDisplayNames(croatian
, DLANG_CA
);
468 logln(" In locale = el_GR...");
469 doTestDisplayNames(greek
, DLANG_EL
);
472 UErrorCode status
= U_ZERO_ERROR
;
474 #if !UCONFIG_NO_FORMATTING
475 DecimalFormatSymbols
symb(status
);
476 /* Check to see if ICU supports this locale */
477 if (symb
.getLocale(ULOC_VALID_LOCALE
, status
) != Locale("root")) {
478 /* test that the default locale has a display name for its own language */
479 /* Currently, there is no language information in the "tl" data file so this test will fail if default locale is "tl" */
480 if (uprv_strcmp(Locale().getLanguage(), "tl") != 0) {
481 Locale().getDisplayLanguage(Locale(), s
);
482 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
483 /* check <=3 to reject getting the language code as a display name */
484 dataerrln("unable to get a display string for the language of the default locale: " + s
);
488 * API coverage improvements: call
489 * Locale::getDisplayLanguage(UnicodeString &) and
490 * Locale::getDisplayCountry(UnicodeString &)
493 Locale().getDisplayLanguage(s
);
494 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
495 dataerrln("unable to get a display string for the language of the default locale [2]: " + s
);
500 logln("Default locale %s is unsupported by ICU\n", Locale().getName());
505 french
.getDisplayCountry(s
);
507 errln("unable to get any default-locale display string for the country of fr_FR\n");
510 Locale("zh", "Hant").getDisplayScript(s
);
512 errln("unable to get any default-locale display string for the country of zh_Hant\n");
516 void LocaleTest::TestSimpleObjectStuff() {
517 Locale
test1("aa", "AA");
518 Locale
test2("aa", "AA");
520 Locale
test4("zz", "ZZ");
521 Locale
test5("aa", "AA", "");
522 Locale
test6("aa", "AA", "ANTARES");
523 Locale
test7("aa", "AA", "JUPITER");
524 Locale test8
= Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that
526 // now list them all for debugging usage.
527 test_dumpLocale(test1
);
528 test_dumpLocale(test2
);
529 test_dumpLocale(test3
);
530 test_dumpLocale(test4
);
531 test_dumpLocale(test5
);
532 test_dumpLocale(test6
);
533 test_dumpLocale(test7
);
534 test_dumpLocale(test8
);
536 // Make sure things compare to themselves!
537 test_assert(test1
== test1
);
538 test_assert(test2
== test2
);
539 test_assert(test3
== test3
);
540 test_assert(test4
== test4
);
541 test_assert(test5
== test5
);
542 test_assert(test6
== test6
);
543 test_assert(test7
== test7
);
544 test_assert(test8
== test8
);
546 // make sure things are not equal to themselves.
547 test_assert(!(test1
!= test1
));
548 test_assert(!(test2
!= test2
));
549 test_assert(!(test3
!= test3
));
550 test_assert(!(test4
!= test4
));
551 test_assert(!(test5
!= test5
));
552 test_assert(!(test6
!= test6
));
553 test_assert(!(test7
!= test7
));
554 test_assert(!(test8
!= test8
));
556 // make sure things that are equal to each other don't show up as unequal.
557 test_assert(!(test1
!= test2
));
558 test_assert(!(test2
!= test1
));
559 test_assert(!(test1
!= test3
));
560 test_assert(!(test2
!= test3
));
561 test_assert(test5
== test1
);
562 test_assert(test6
!= test2
);
563 test_assert(test6
!= test5
);
565 test_assert(test6
!= test7
);
567 // test for things that shouldn't compare equal.
568 test_assert(!(test1
== test4
));
569 test_assert(!(test2
== test4
));
570 test_assert(!(test3
== test4
));
572 test_assert(test7
== test8
);
574 // test for hash codes to be the same.
575 int32_t hash1
= test1
.hashCode();
576 int32_t hash2
= test2
.hashCode();
577 int32_t hash3
= test3
.hashCode();
579 test_assert(hash1
== hash2
);
580 test_assert(hash1
== hash3
);
581 test_assert(hash2
== hash3
);
583 // test that the assignment operator works.
585 logln("test4=test1;");
586 test_dumpLocale(test4
);
587 test_assert(test4
== test4
);
589 test_assert(!(test1
!= test4
));
590 test_assert(!(test2
!= test4
));
591 test_assert(!(test3
!= test4
));
592 test_assert(test1
== test4
);
593 test_assert(test4
== test1
);
595 // test assignments with a variant
596 logln("test7 = test6");
598 test_dumpLocale(test7
);
599 test_assert(test7
== test7
);
600 test_assert(test7
== test6
);
601 test_assert(test7
!= test5
);
603 logln("test6 = test1");
605 test_dumpLocale(test6
);
606 test_assert(test6
!= test7
);
607 test_assert(test6
== test1
);
608 test_assert(test6
== test6
);
611 // A class which exposes constructors that are implemented in terms of the POSIX parsing code.
612 class POSIXLocale
: public Locale
615 POSIXLocale(const UnicodeString
& l
)
619 ch
= new char[l
.length() + 1];
620 ch
[l
.extract(0, 0x7fffffff, ch
, "")] = 0;
624 POSIXLocale(const char *l
)
631 void LocaleTest::TestPOSIXParsing()
633 POSIXLocale
test1("ab_AB");
634 POSIXLocale
test2(UnicodeString("ab_AB"));
635 Locale
test3("ab","AB");
637 POSIXLocale
test4("ab_AB_Antares");
638 POSIXLocale
test5(UnicodeString("ab_AB_Antares"));
639 Locale
test6("ab", "AB", "Antares");
641 test_dumpLocale(test1
);
642 test_dumpLocale(test2
);
643 test_dumpLocale(test3
);
644 test_dumpLocale(test4
);
645 test_dumpLocale(test5
);
646 test_dumpLocale(test6
);
648 test_assert(test1
== test1
);
650 test_assert(test1
== test2
);
651 test_assert(test2
== test3
);
652 test_assert(test3
== test1
);
654 test_assert(test4
== test5
);
655 test_assert(test5
== test6
);
656 test_assert(test6
== test4
);
658 test_assert(test1
!= test4
);
659 test_assert(test5
!= test3
);
660 test_assert(test5
!= test2
);
662 int32_t hash1
= test1
.hashCode();
663 int32_t hash2
= test2
.hashCode();
664 int32_t hash3
= test3
.hashCode();
666 test_assert(hash1
== hash2
);
667 test_assert(hash2
== hash3
);
668 test_assert(hash3
== hash1
);
671 void LocaleTest::TestGetAvailableLocales()
673 int32_t locCount
= 0;
674 const Locale
* locList
= Locale::getAvailableLocales(locCount
);
677 dataerrln("getAvailableLocales() returned an empty list!");
679 logln(UnicodeString("Number of locales returned = ") + locCount
);
681 for(int32_t i
= 0; i
< locCount
; ++i
)
682 logln(locList
[i
].getName());
684 // I have no idea how to test this function...
687 // This test isn't applicable anymore - getISO3Language is
688 // independent of the data directory
689 void LocaleTest::TestDataDirectory()
692 char oldDirectory[80];
694 UErrorCode err = U_ZERO_ERROR;
695 UnicodeString testValue;
697 temp = Locale::getDataDirectory();
698 strcpy(oldDirectory, temp);
699 logln(UnicodeString("oldDirectory = ") + oldDirectory);
701 Locale test(Locale::US);
702 test.getISO3Language(testValue);
703 logln("first fetch of language retrieved " + testValue);
704 if (testValue != "eng")
705 errln("Initial check of ISO3 language failed: expected \"eng\", got \"" + testValue + "\"");
709 path=IntlTest::getTestDirectory();
710 Locale::setDataDirectory( path );
713 test.getISO3Language(testValue);
714 logln("second fetch of language retrieved " + testValue);
715 if (testValue != "xxx")
716 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue + "\"");
718 Locale::setDataDirectory(oldDirectory);
719 test.getISO3Language(testValue);
720 logln("third fetch of language retrieved " + testValue);
721 if (testValue != "eng")
722 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testValue + "\"");
726 //===========================================================
728 void LocaleTest::doTestDisplayNames(Locale
& displayLocale
, int32_t compareIndex
) {
731 for (int32_t i
= 0; i
<= MAX_LOCALES
; i
++) {
732 Locale
testLocale("");
733 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
734 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
737 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
739 logln(" Testing " + (temp
=testLocale
.getName()) + "...");
741 UnicodeString testLang
;
742 UnicodeString testScript
;
743 UnicodeString testCtry
;
744 UnicodeString testVar
;
745 UnicodeString testName
;
747 testLocale
.getDisplayLanguage(displayLocale
, testLang
);
748 testLocale
.getDisplayScript(displayLocale
, testScript
);
749 testLocale
.getDisplayCountry(displayLocale
, testCtry
);
750 testLocale
.getDisplayVariant(displayLocale
, testVar
);
751 testLocale
.getDisplayName(displayLocale
, testName
);
753 UnicodeString expectedLang
;
754 UnicodeString expectedScript
;
755 UnicodeString expectedCtry
;
756 UnicodeString expectedVar
;
757 UnicodeString expectedName
;
759 expectedLang
= dataTable
[compareIndex
][i
];
760 if (expectedLang
.length() == 0)
761 expectedLang
= dataTable
[DLANG_EN
][i
];
763 expectedScript
= dataTable
[compareIndex
+ 1][i
];
764 if (expectedScript
.length() == 0)
765 expectedScript
= dataTable
[DSCRIPT_EN
][i
];
767 expectedCtry
= dataTable
[compareIndex
+ 2][i
];
768 if (expectedCtry
.length() == 0)
769 expectedCtry
= dataTable
[DCTRY_EN
][i
];
771 expectedVar
= dataTable
[compareIndex
+ 3][i
];
772 if (expectedVar
.length() == 0)
773 expectedVar
= dataTable
[DVAR_EN
][i
];
775 expectedName
= dataTable
[compareIndex
+ 4][i
];
776 if (expectedName
.length() == 0)
777 expectedName
= dataTable
[DNAME_EN
][i
];
779 if (testLang
!= expectedLang
)
780 dataerrln("Display language (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testLang
+ " expected " + expectedLang
);
781 if (testScript
!= expectedScript
)
782 dataerrln("Display script (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testScript
+ " expected " + expectedScript
);
783 if (testCtry
!= expectedCtry
)
784 dataerrln("Display country (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testCtry
+ " expected " + expectedCtry
);
785 if (testVar
!= expectedVar
)
786 dataerrln("Display variant (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testVar
+ " expected " + expectedVar
);
787 if (testName
!= expectedName
)
788 dataerrln("Display name (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testName
+ " expected " + expectedName
);
792 //---------------------------------------------------
793 // table of valid data
794 //---------------------------------------------------
798 void LocaleTest::setUpDataTable()
800 if (dataTable
== 0) {
801 dataTable
= new UnicodeString
*[33];
803 for (int32_t i
= 0; i
< 33; i
++) {
804 dataTable
[i
] = new UnicodeString
[8];
805 for (int32_t j
= 0; j
< 8; j
++) {
806 dataTable
[i
][j
] = CharsToUnicodeString(rawData
[i
][j
]);
812 // ====================
816 * @bug 4011756 4011380
819 LocaleTest::TestISO3Fallback()
821 Locale
test("xx", "YY");
825 result
= test
.getISO3Language();
827 // Conform to C API usage
829 if (!result
|| (result
[0] != 0))
830 errln("getISO3Language() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
832 result
= test
.getISO3Country();
834 if (!result
|| (result
[0] != 0))
835 errln("getISO3Country() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
839 * @bug 4106155 4118587
842 LocaleTest::TestGetLangsAndCountries()
844 // It didn't seem right to just do an exhaustive test of everything here, so I check
845 // for the following things:
846 // 1) Does each list have the right total number of entries?
847 // 2) Does each list contain certain language and country codes we think are important
848 // (the G7 countries, plus a couple others)?
849 // 3) Does each list have every entry formatted correctly? (i.e., two characters,
850 // all lower case for the language codes, all upper case for the country codes)
851 // 4) Is each list in sorted order?
852 int32_t testCount
= 0;
853 const char * const * test
= Locale::getISOLanguages();
854 const char spotCheck1
[ ][4] = { "en", "es", "fr", "de", "it",
855 "ja", "ko", "zh", "th", "he",
856 "id", "iu", "ug", "yi", "za" };
860 for(testCount
= 0;test
[testCount
];testCount
++)
863 /* TODO: Change this test to be more like the cloctst version? */
864 if (testCount
!= 560)
865 errln("Expected getISOLanguages() to return 560 languages; it returned %d", testCount
);
867 for (i
= 0; i
< 15; i
++) {
869 for (j
= 0; j
< testCount
; j
++)
870 if (uprv_strcmp(test
[j
],spotCheck1
[i
])== 0)
872 if (j
== testCount
|| (uprv_strcmp(test
[j
],spotCheck1
[i
])!=0))
873 errln("Couldn't find " + (UnicodeString
)spotCheck1
[i
] + " in language list.");
876 for (i
= 0; i
< testCount
; i
++) {
877 UnicodeString
testee(test
[i
],"");
878 UnicodeString
lc(test
[i
],"");
879 if (testee
!= lc
.toLower())
880 errln(lc
+ " is not all lower case.");
881 if ( (testee
.length() != 2) && (testee
.length() != 3))
882 errln(testee
+ " is not two or three characters long.");
883 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
884 errln(testee
+ " appears in an out-of-order position in the list.");
887 test
= Locale::getISOCountries();
888 UnicodeString spotCheck2
[] = { "US", "CA", "GB", "FR", "DE",
889 "IT", "JP", "KR", "CN", "TW",
891 int32_t spot2Len
= 11;
892 for(testCount
=0;test
[testCount
];testCount
++)
895 if (testCount
!= 249){
896 errln("Expected getISOCountries to return 249 countries; it returned %d", testCount
);
898 for (i
= 0; i
< spot2Len
; i
++) {
900 for (j
= 0; j
< testCount
; j
++)
902 UnicodeString
testee(test
[j
],"");
904 if (testee
== spotCheck2
[i
])
907 UnicodeString
testee(test
[j
],"");
908 if (j
== testCount
|| testee
!= spotCheck2
[i
])
909 errln("Couldn't find " + spotCheck2
[i
] + " in country list.");
912 for (i
= 0; i
< testCount
; i
++) {
913 UnicodeString
testee(test
[i
],"");
914 UnicodeString
uc(test
[i
],"");
915 if (testee
!= uc
.toUpper())
916 errln(testee
+ " is not all upper case.");
917 if (testee
.length() != 2)
918 errln(testee
+ " is not two characters long.");
919 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
920 errln(testee
+ " appears in an out-of-order position in the list.");
923 // This getAvailableLocales and getISO3Language
925 int32_t numOfLocales
;
927 const Locale
*pLocales
= Locale::getAvailableLocales(numOfLocales
);
929 for (int i
= 0; i
< numOfLocales
; i
++) {
930 const Locale
&loc(pLocales
[i
]);
934 loc
.getDisplayName (enLoc
, name
);
935 name
.extract (0, 200, szName
, sizeof(szName
));
937 if (strlen(loc
.getISO3Language()) == 0) {
938 errln("getISO3Language() returned an empty string for: " + name
);
948 LocaleTest::TestSimpleDisplayNames()
950 // This test is different from TestDisplayNames because TestDisplayNames checks
951 // fallback behavior, combination of language and country names to form locale
952 // names, and other stuff like that. This test just checks specific language
953 // and country codes to make sure we have the correct names for them.
954 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
955 UnicodeString languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
958 for (int32_t i
= 0; i
< 6; i
++) {
960 Locale
l(languageCodes
[i
], "", "");
961 l
.getDisplayLanguage(Locale::getUS(), test
);
962 if (test
!= languageNames
[i
])
963 dataerrln("Got wrong display name for " + UnicodeString(languageCodes
[i
]) + ": Expected \"" +
964 languageNames
[i
] + "\", got \"" + test
+ "\".");
972 LocaleTest::TestUninstalledISO3Names()
974 // This test checks to make sure getISO3Language and getISO3Country work right
975 // even for locales that are not installed.
976 const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
978 const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
979 "ssw", "twi", "zul" };
983 for (i
= 0; i
< 8; i
++) {
984 UErrorCode err
= U_ZERO_ERROR
;
987 Locale
l(iso2Languages
[i
], "", "");
988 test
= l
.getISO3Language();
989 if((test
!= iso3Languages
[i
]) || U_FAILURE(err
))
990 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages
[i
]) + ": Expected \"" +
991 iso3Languages
[i
] + "\", got \"" + test
+ "\"." + UnicodeString(u_errorName(err
)));
994 char iso2Countries
[][4] = { "AF", "BW", "KZ", "MO", "MN",
996 char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
997 "SLB", "TCA", "ZWE" };
999 for (i
= 0; i
< 8; i
++) {
1000 UErrorCode err
= U_ZERO_ERROR
;
1001 Locale
l("", iso2Countries
[i
], "");
1002 UnicodeString
test(l
.getISO3Country(), "");
1003 if (test
!= iso3Countries
[i
])
1004 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries
[i
]) + ": Expected \"" +
1005 UnicodeString(iso3Countries
[i
]) + "\", got \"" + test
+ "\"." + u_errorName(err
));
1011 * I could not reproduce this bug. I'm pretty convinced it was fixed with the
1012 * big locale-data reorg of 10/28/97. The lookup logic for language and country
1013 * display names was also changed at that time in that check-in. --rtg 3/20/98
1016 LocaleTest::TestAtypicalLocales()
1018 Locale localesToTest
[] = { Locale("de", "CA"),
1028 UnicodeString englishDisplayNames
[] = { "German (Canada)",
1029 "Japanese (South Africa)",
1032 "Spanish (Germany)",
1035 "Dominican Republic",
1037 UnicodeString frenchDisplayNames
[]= { "allemand (Canada)",
1038 "japonais (Afrique du Sud)",
1041 "espagnol (Allemagne)",
1043 CharsToUnicodeString("Su\\u00E8de"),
1044 CharsToUnicodeString("R\\u00E9publique dominicaine"),
1046 UnicodeString spanishDisplayNames
[] = {
1047 CharsToUnicodeString("alem\\u00E1n (Canad\\u00E1)"),
1048 CharsToUnicodeString("japon\\u00E9s (Sud\\u00E1frica)"),
1049 CharsToUnicodeString("ruso (M\\u00E9xico)"),
1050 CharsToUnicodeString("ingl\\u00E9s (Francia)"),
1051 CharsToUnicodeString("espa\\u00F1ol (Alemania)"),
1054 CharsToUnicodeString("Rep\\u00FAblica Dominicana"),
1055 CharsToUnicodeString("B\\u00E9lgica") };
1056 // De-Anglicizing root required the change from
1057 // English display names to ISO Codes - ram 2003/09/26
1058 UnicodeString invDisplayNames
[] = { "German (Canada)",
1059 "Japanese (South Africa)",
1062 "Spanish (Germany)",
1065 "Dominican Republic",
1069 UErrorCode status
= U_ZERO_ERROR
;
1071 Locale::setDefault(Locale::getUS(), status
);
1072 for (i
= 0; i
< 9; ++i
) {
1074 localesToTest
[i
].getDisplayName(Locale::getUS(), name
);
1076 if (name
!= englishDisplayNames
[i
])
1078 dataerrln("Lookup in English failed: expected \"" + englishDisplayNames
[i
]
1079 + "\", got \"" + name
+ "\"");
1080 logln("Locale name was-> " + (name
=localesToTest
[i
].getName()));
1084 for (i
= 0; i
< 9; i
++) {
1086 localesToTest
[i
].getDisplayName(Locale("es", "ES"), name
);
1088 if (name
!= spanishDisplayNames
[i
])
1089 dataerrln("Lookup in Spanish failed: expected \"" + spanishDisplayNames
[i
]
1090 + "\", got \"" + name
+ "\"");
1093 for (i
= 0; i
< 9; i
++) {
1095 localesToTest
[i
].getDisplayName(Locale::getFrance(), name
);
1097 if (name
!= frenchDisplayNames
[i
])
1098 dataerrln("Lookup in French failed: expected \"" + frenchDisplayNames
[i
]
1099 + "\", got \"" + name
+ "\"");
1102 for (i
= 0; i
< 9; i
++) {
1104 localesToTest
[i
].getDisplayName(Locale("inv", "IN"), name
);
1105 logln(name
+ " Locale fallback to be, and data fallback to root");
1106 if (name
!= invDisplayNames
[i
])
1107 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1108 + "\", got \"" + prettify(name
) + "\"");
1109 localesToTest
[i
].getDisplayName(Locale("inv", "BD"), name
);
1110 logln(name
+ " Data fallback to root");
1111 if (name
!= invDisplayNames
[i
])
1112 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1113 + "\", got \"" + prettify(name
)+ "\"");
1115 Locale::setDefault(saveLocale
, status
);
1118 #if !UCONFIG_NO_FORMATTING
1122 * This would be better tested by the LocaleDataTest. Will move it when I
1123 * get the LocaleDataTest working again.
1126 LocaleTest::TestThaiCurrencyFormat()
1128 UErrorCode status
= U_ZERO_ERROR
;
1129 DecimalFormat
*thaiCurrency
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(
1130 Locale("th", "TH"), status
);
1131 UnicodeString
posPrefix("THB", 3, US_INV
); // per cldrbug 7618
1134 if(U_FAILURE(status
) || !thaiCurrency
)
1136 dataerrln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status
)));
1139 if (thaiCurrency
->getPositivePrefix(temp
) != posPrefix
)
1140 errln("Thai currency prefix wrong: expected THB, got \"" +
1141 thaiCurrency
->getPositivePrefix(temp
) + "\"");
1142 if (thaiCurrency
->getPositiveSuffix(temp
) != "")
1143 errln("Thai currency suffix wrong: expected \"\", got \"" +
1144 thaiCurrency
->getPositiveSuffix(temp
) + "\"");
1146 delete thaiCurrency
;
1151 * Confirm that Euro support works. This test is pretty rudimentary; all it does
1152 * is check that any locales with the EURO variant format a number using the
1153 * Euro currency symbol.
1155 * ASSUME: All locales encode the Euro character "\u20AC".
1156 * If this is changed to use the single-character Euro symbol, this
1157 * test must be updated.
1161 LocaleTest::TestEuroSupport()
1163 UChar euro
= 0x20ac;
1164 const UnicodeString
EURO_CURRENCY(&euro
, 1, 1); // Look for this UnicodeString in formatted Euro currency
1165 const char* localeArr
[] = {
1189 const char** locales
= localeArr
;
1191 UErrorCode status
= U_ZERO_ERROR
;
1195 for (;*locales
!=NULL
;locales
++) {
1196 Locale
loc (*locales
);
1198 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(loc
, status
);
1201 if (U_FAILURE(status
)) {
1202 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales
);
1206 nf
->format(271828.182845, pos
);
1208 nf
->format(-271828.182845, neg
);
1209 if (pos
.indexOf(EURO_CURRENCY
) >= 0 &&
1210 neg
.indexOf(EURO_CURRENCY
) >= 0) {
1211 logln("Ok: " + (temp
=loc
.getName()) +
1212 ": " + pos
+ " / " + neg
);
1215 errln("Fail: " + (temp
=loc
.getName()) +
1216 " formats without " + EURO_CURRENCY
+
1217 ": " + pos
+ " / " + neg
+
1218 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***");
1224 UnicodeString
dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar
)0x00a4), resultStr
;
1226 status
= U_ZERO_ERROR
;
1228 ucurr_forLocale("en_US", tmp
, 4, &status
);
1229 resultStr
.setTo(tmp
);
1230 if (dollarStr
!= resultStr
) {
1231 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
1233 ucurr_forLocale("en_US_EURO", tmp
, 4, &status
);
1234 resultStr
.setTo(tmp
);
1235 if (euroStr
!= resultStr
) {
1236 errcheckln(status
, "Fail: en_US_EURO didn't return EUR - %s", u_errorName(status
));
1238 ucurr_forLocale("en_GB_EURO", tmp
, 4, &status
);
1239 resultStr
.setTo(tmp
);
1240 if (euroStr
!= resultStr
) {
1241 errcheckln(status
, "Fail: en_GB_EURO didn't return EUR - %s", u_errorName(status
));
1243 ucurr_forLocale("en_US_PREEURO", tmp
, 4, &status
);
1244 resultStr
.setTo(tmp
);
1245 if (dollarStr
!= resultStr
) {
1246 errcheckln(status
, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status
));
1248 ucurr_forLocale("en_US_Q", tmp
, 4, &status
);
1249 resultStr
.setTo(tmp
);
1250 if (dollarStr
!= resultStr
) {
1251 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
1253 int32_t invalidLen
= ucurr_forLocale("en_QQ", tmp
, 4, &status
);
1254 if (invalidLen
|| U_SUCCESS(status
)) {
1255 errln("Fail: en_QQ didn't return NULL");
1263 * toString() doesn't work with language_VARIANT.
1266 LocaleTest::TestToString() {
1268 Locale("xx", "", ""),
1269 Locale("", "YY", ""),
1270 Locale("", "", "ZZ"),
1271 Locale("xx", "YY", ""),
1272 Locale("xx", "", "ZZ"),
1273 Locale("", "YY", "ZZ"),
1274 Locale("xx", "YY", "ZZ"),
1277 const char DATA_S
[][20] = {
1287 for (int32_t i
=0; i
< 7; ++i
) {
1289 name
= DATA
[i
].getName();
1291 if (strcmp(name
, DATA_S
[i
]) != 0)
1293 errln("Fail: Locale.getName(), got:" + UnicodeString(name
) + ", expected: " + DATA_S
[i
]);
1296 logln("Pass: Locale.getName(), got:" + UnicodeString(name
) );
1300 #if !UCONFIG_NO_FORMATTING
1304 * Couldn't reproduce this bug -- probably was fixed earlier.
1306 * ORIGINAL BUG REPORT:
1307 * -- basically, hungarian for monday shouldn't have an \u00f4
1308 * (o circumflex)in it instead it should be an o with 2 inclined
1309 * (right) lines over it..
1311 * You may wonder -- why do all this -- why not just add a line to
1312 * LocaleData? Well, I could see by inspection that the locale file had the
1313 * right character in it, so I wanted to check the rest of the pipeline -- a
1314 * very remote possibility, but I wanted to be sure. The other possibility
1315 * is that something is wrong with the font mapping subsystem, but we can't
1319 LocaleTest::Test4139940()
1321 Locale
mylocale("hu", "", "");
1322 UDate mydate
= date(98,3,13); // A Monday
1323 UErrorCode status
= U_ZERO_ERROR
;
1324 SimpleDateFormat
df_full("EEEE", mylocale
, status
);
1325 if(U_FAILURE(status
)){
1326 dataerrln(UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: ") + UnicodeString(u_errorName(status
)));
1330 FieldPosition
pos(FieldPosition::DONT_CARE
);
1331 df_full
.format(mydate
, str
, pos
);
1332 // Make sure that o circumflex (\u00F4) is NOT there, and
1333 // o double acute (\u0151) IS.
1336 if (str
.indexOf(oda
) < 0 || str
.indexOf(ocf
) >= 0) {
1337 /* If the default locale is "th" this test will fail because of the buddhist calendar. */
1338 if (strcmp(Locale::getDefault().getLanguage(), "th") != 0) {
1339 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
1340 str
.indexOf(oda
), str
.indexOf(ocf
));
1342 logln(UnicodeString("An error is produce in buddhist calendar."));
1344 logln(UnicodeString("String is: ") + str
);
1349 LocaleTest::date(int32_t y
, int32_t m
, int32_t d
, int32_t hr
, int32_t min
, int32_t sec
)
1351 UErrorCode status
= U_ZERO_ERROR
;
1352 Calendar
*cal
= Calendar::createInstance(status
);
1356 cal
->set(1900 + y
, m
, d
, hr
, min
, sec
); // Add 1900 to follow java.util.Date protocol
1357 UDate dt
= cal
->getTime(status
);
1358 if (U_FAILURE(status
))
1367 * Russian first day of week should be Monday. Confirmed.
1370 LocaleTest::Test4143951()
1372 UErrorCode status
= U_ZERO_ERROR
;
1373 Calendar
*cal
= Calendar::createInstance(Locale("ru", "", ""), status
);
1374 if(U_SUCCESS(status
)) {
1375 if (cal
->getFirstDayOfWeek(status
) != UCAL_MONDAY
) {
1376 dataerrln("Fail: First day of week in Russia should be Monday");
1386 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes.
1387 * Should throw an exception for unknown locales
1390 LocaleTest::Test4147315()
1393 // Try with codes that are the wrong length but happen to match text
1394 // at a valid offset in the mapping table
1395 Locale
locale("xxx", "CCC");
1397 const char *result
= locale
.getISO3Country();
1399 // Change to conform to C api usage
1400 if((result
==NULL
)||(result
[0] != 0))
1401 errln("ERROR: getISO3Country() returns: " + UnicodeString(result
,"") +
1402 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1407 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
1408 * Should throw an exception for unknown locales
1411 LocaleTest::Test4147317()
1414 // Try with codes that are the wrong length but happen to match text
1415 // at a valid offset in the mapping table
1416 Locale
locale("xxx", "CCC");
1418 const char *result
= locale
.getISO3Language();
1420 // Change to conform to C api usage
1421 if((result
==NULL
)||(result
[0] != 0))
1422 errln("ERROR: getISO3Language() returns: " + UnicodeString(result
,"") +
1423 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1430 LocaleTest::Test4147552()
1432 Locale locales
[] = { Locale("no", "NO"),
1433 Locale("no", "NO", "B"),
1434 Locale("no", "NO", "NY")
1437 UnicodeString
edn("Norwegian (Norway, B)");
1438 UnicodeString englishDisplayNames
[] = {
1439 "Norwegian (Norway)",
1441 // "Norwegian (Norway,B)",
1442 //"Norwegian (Norway,NY)"
1443 "Norwegian (Norway, NY)"
1445 UnicodeString
ndn("norsk (Norge, B");
1446 UnicodeString norwegianDisplayNames
[] = {
1451 //"Norsk (Noreg, Nynorsk)"
1453 UErrorCode status
= U_ZERO_ERROR
;
1456 Locale::setDefault(Locale::getEnglish(), status
);
1457 for (int32_t i
= 0; i
< 3; ++i
) {
1458 Locale loc
= locales
[i
];
1460 if (loc
.getDisplayName(temp
) != englishDisplayNames
[i
])
1461 dataerrln("English display-name mismatch: expected " +
1462 englishDisplayNames
[i
] + ", got " + loc
.getDisplayName(temp
));
1463 if (loc
.getDisplayName(loc
, temp
) != norwegianDisplayNames
[i
])
1464 dataerrln("Norwegian display-name mismatch: expected " +
1465 norwegianDisplayNames
[i
] + ", got " +
1466 loc
.getDisplayName(loc
, temp
));
1468 Locale::setDefault(saveLocale
, status
);
1472 LocaleTest::TestVariantParsing()
1474 Locale
en_US_custom("en", "US", "De Anza_Cupertino_California_United States_Earth");
1476 UnicodeString
dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)");
1477 UnicodeString
dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH");
1481 en_US_custom
.getDisplayVariant(Locale::getUS(), got
);
1482 if(got
!= dispVar
) {
1483 errln("FAIL: getDisplayVariant()");
1484 errln("Wanted: " + dispVar
);
1485 errln("Got : " + got
);
1488 en_US_custom
.getDisplayName(Locale::getUS(), got
);
1489 if(got
!= dispName
) {
1490 dataerrln("FAIL: getDisplayName()");
1491 dataerrln("Wanted: " + dispName
);
1492 dataerrln("Got : " + got
);
1495 Locale
shortVariant("fr", "FR", "foo");
1496 shortVariant
.getDisplayVariant(got
);
1499 errln("FAIL: getDisplayVariant()");
1500 errln("Wanted: foo");
1501 errln("Got : " + got
);
1504 Locale
bogusVariant("fr", "FR", "_foo");
1505 bogusVariant
.getDisplayVariant(got
);
1508 errln("FAIL: getDisplayVariant()");
1509 errln("Wanted: foo");
1510 errln("Got : " + got
);
1513 Locale
bogusVariant2("fr", "FR", "foo_");
1514 bogusVariant2
.getDisplayVariant(got
);
1517 errln("FAIL: getDisplayVariant()");
1518 errln("Wanted: foo");
1519 errln("Got : " + got
);
1522 Locale
bogusVariant3("fr", "FR", "_foo_");
1523 bogusVariant3
.getDisplayVariant(got
);
1526 errln("FAIL: getDisplayVariant()");
1527 errln("Wanted: foo");
1528 errln("Got : " + got
);
1532 #if !UCONFIG_NO_FORMATTING
1536 * Currency symbol in zh is wrong. We will test this at the NumberFormat
1537 * end to test the whole pipe.
1540 LocaleTest::Test4105828()
1542 Locale LOC
[] = { Locale::getChinese(), Locale("zh", "CN", ""),
1543 Locale("zh", "TW", ""), Locale("zh", "HK", "") };
1544 UErrorCode status
= U_ZERO_ERROR
;
1545 for (int32_t i
= 0; i
< 4; ++i
) {
1546 NumberFormat
*fmt
= NumberFormat::createPercentInstance(LOC
[i
], status
);
1547 if(U_FAILURE(status
)) {
1548 dataerrln("Couldn't create NumberFormat - %s", u_errorName(status
));
1551 UnicodeString result
;
1552 FieldPosition
pos(0);
1553 fmt
->format((int32_t)1, result
, pos
);
1555 if(result
!= "100%") {
1556 errln(UnicodeString("Percent for ") + LOC
[i
].getDisplayName(temp
) + " should be 100%, got " + result
);
1564 // Tests setBogus and isBogus APIs for Locale
1567 LocaleTest::TestSetIsBogus() {
1570 if(l
.isBogus() != TRUE
) {
1571 errln("After setting bogus, didn't return TRUE");
1573 l
= "en_US"; // This should reset bogus
1574 if(l
.isBogus() != FALSE
) {
1575 errln("After resetting bogus, didn't return FALSE");
1581 LocaleTest::TestKeywordVariants(void) {
1582 static const struct {
1583 const char *localeID
;
1584 const char *expectedLocaleID
;
1585 //const char *expectedLocaleIDNoKeywords;
1586 //const char *expectedCanonicalID;
1587 const char *expectedKeywords
[10];
1588 int32_t numKeywords
;
1589 UErrorCode expectedStatus
;
1592 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1593 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1595 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1596 {"calendar", "collation", "currency"},
1604 //"de_DE@currency=EUR",
1605 {"","","","","","",""},
1607 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1610 UErrorCode status
= U_ZERO_ERROR
;
1612 int32_t i
= 0, j
= 0;
1613 const char *result
= NULL
;
1614 StringEnumeration
*keywords
;
1615 int32_t keyCount
= 0;
1616 const char *keyword
= NULL
;
1617 const UnicodeString
*keywordString
;
1618 int32_t keywordLen
= 0;
1620 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1621 status
= U_ZERO_ERROR
;
1622 Locale
l(testCases
[i
].localeID
);
1623 keywords
= l
.createKeywords(status
);
1625 if(status
!= testCases
[i
].expectedStatus
) {
1626 err("Expected to get status %s. Got %s instead\n",
1627 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1629 status
= U_ZERO_ERROR
;
1631 if((keyCount
= keywords
->count(status
)) != testCases
[i
].numKeywords
) {
1632 err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1637 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1640 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1641 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1644 if((keywordString
= keywords
->snext(status
)) == NULL
) {
1647 if(*keywordString
!= UnicodeString(testCases
[i
].expectedKeywords
[j
], "")) {
1648 err("Expected to get keyword UnicodeString %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1653 if(j
== keyCount
/ 2) {
1654 // replace keywords with a clone of itself
1655 StringEnumeration
*k2
= keywords
->clone();
1656 if(k2
== NULL
|| keyCount
!= k2
->count(status
)) {
1657 errln("KeywordEnumeration.clone() failed");
1664 keywords
->reset(status
); // Make sure that reset works.
1666 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1669 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1670 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1677 result
= l
.getName();
1678 if(uprv_strcmp(testCases
[i
].expectedLocaleID
, result
) != 0) {
1679 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n",
1680 testCases
[i
].expectedLocaleID
, testCases
[i
].localeID
, result
);
1688 LocaleTest::TestKeywordVariantParsing(void) {
1689 static const struct {
1690 const char *localeID
;
1691 const char *keyword
;
1692 const char *expectedValue
;
1694 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook" },
1695 { "de_DE", "collation", ""},
1696 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" },
1697 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation", "PHONEBOOk" },
1700 UErrorCode status
= U_ZERO_ERROR
;
1703 int32_t resultLen
= 0;
1706 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1708 Locale
l(testCases
[i
].localeID
);
1709 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1710 (void)resultLen
; // Suppress unused variable warning.
1711 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1712 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1713 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1719 LocaleTest::TestSetKeywordValue(void) {
1720 static const struct {
1721 const char *keyword
;
1724 { "collation", "phonebook" },
1725 { "currency", "euro" },
1726 { "calendar", "buddhist" }
1729 UErrorCode status
= U_ZERO_ERROR
;
1732 int32_t resultLen
= 0;
1735 Locale
l(Locale::getGerman());
1737 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1738 l
.setKeywordValue(testCases
[i
].keyword
, testCases
[i
].value
, status
);
1739 if(U_FAILURE(status
)) {
1740 err("FAIL: Locale::setKeywordValue failed - %s\n", u_errorName(status
));
1744 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1745 (void)resultLen
; // Suppress unused variable warning.
1746 if(uprv_strcmp(testCases
[i
].value
, buffer
) != 0) {
1747 err("Expected to extract \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1748 testCases
[i
].value
, testCases
[i
].keyword
, buffer
);
1754 LocaleTest::TestGetBaseName(void) {
1755 static const struct {
1756 const char *localeID
;
1757 const char *baseName
;
1759 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
1760 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
1761 { "ja@calendar = buddhist", "ja" },
1762 { "de-u-co-phonebk", "de"}
1767 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1768 Locale
loc(testCases
[i
].localeID
);
1769 if(strcmp(testCases
[i
].baseName
, loc
.getBaseName())) {
1770 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
1771 testCases
[i
].localeID
, testCases
[i
].baseName
, loc
.getBaseName());
1776 // Verify that adding a keyword to an existing Locale doesn't change the base name.
1777 UErrorCode status
= U_ZERO_ERROR
;
1778 Locale
loc2("en-US");
1779 if (strcmp("en_US", loc2
.getBaseName())) {
1780 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
1782 loc2
.setKeywordValue("key", "value", status
);
1783 if (strcmp("en_US@key=value", loc2
.getName())) {
1784 errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getName());
1786 if (strcmp("en_US", loc2
.getBaseName())) {
1787 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
1792 * Compare two locale IDs. If they are equal, return 0. If `string'
1793 * starts with `prefix' plus an additional element, that is, string ==
1794 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
1796 static UBool
_loccmp(const char* string
, const char* prefix
) {
1797 int32_t slen
= (int32_t)strlen(string
),
1798 plen
= (int32_t)strlen(prefix
);
1799 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
1800 /* 'root' is "less than" everything */
1801 if (uprv_strcmp(prefix
, "root") == 0) {
1802 return (uprv_strcmp(string
, "root") == 0) ? 0 : 1;
1804 if (c
) return -1; /* mismatch */
1805 if (slen
== plen
) return 0;
1806 if (string
[plen
] == '_') return 1;
1807 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
1811 * Check the relationship between requested locales, and report problems.
1812 * The caller specifies the expected relationships between requested
1813 * and valid (expReqValid) and between valid and actual (expValidActual).
1814 * Possible values are:
1815 * "gt" strictly greater than, e.g., en_US > en
1816 * "ge" greater or equal, e.g., en >= en
1817 * "eq" equal, e.g., en == en
1819 void LocaleTest::_checklocs(const char* label
,
1821 const Locale
& validLoc
,
1822 const Locale
& actualLoc
,
1823 const char* expReqValid
,
1824 const char* expValidActual
) {
1825 const char* valid
= validLoc
.getName();
1826 const char* actual
= actualLoc
.getName();
1827 int32_t reqValid
= _loccmp(req
, valid
);
1828 int32_t validActual
= _loccmp(valid
, actual
);
1829 if (((0 == uprv_strcmp(expReqValid
, "gt") && reqValid
> 0) ||
1830 (0 == uprv_strcmp(expReqValid
, "ge") && reqValid
>= 0) ||
1831 (0 == uprv_strcmp(expReqValid
, "eq") && reqValid
== 0)) &&
1832 ((0 == uprv_strcmp(expValidActual
, "gt") && validActual
> 0) ||
1833 (0 == uprv_strcmp(expValidActual
, "ge") && validActual
>= 0) ||
1834 (0 == uprv_strcmp(expValidActual
, "eq") && validActual
== 0))) {
1835 logln("%s; req=%s, valid=%s, actual=%s",
1836 label
, req
, valid
, actual
);
1838 dataerrln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
1839 label
, req
, valid
, actual
,
1840 expReqValid
, expValidActual
);
1844 void LocaleTest::TestGetLocale(void) {
1845 #if !UCONFIG_NO_SERVICE
1847 Locale valid
, actual
, reqLoc
;
1850 #if !UCONFIG_NO_FORMATTING
1852 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1853 req
= "en_US_BROOKLYN";
1854 Calendar
* cal
= Calendar::createInstance(Locale::createFromName(req
), ec
);
1855 if (U_FAILURE(ec
)) {
1856 dataerrln("FAIL: Calendar::createInstance failed - %s", u_errorName(ec
));
1858 valid
= cal
->getLocale(ULOC_VALID_LOCALE
, ec
);
1859 actual
= cal
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1860 if (U_FAILURE(ec
)) {
1861 errln("FAIL: Calendar::getLocale() failed");
1863 _checklocs("Calendar", req
, valid
, actual
);
1865 /* Make sure that it fails correctly */
1866 ec
= U_FILE_ACCESS_ERROR
;
1867 if (cal
->getLocale(ULOC_VALID_LOCALE
, ec
).getName()[0] != 0) {
1868 errln("FAIL: Calendar::getLocale() failed to fail correctly. It should have returned \"\"");
1876 // DecimalFormat, DecimalFormatSymbols
1877 #if !UCONFIG_NO_FORMATTING
1879 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1881 NumberFormat
* nf
= NumberFormat::createInstance(Locale::createFromName(req
), ec
);
1882 if (U_FAILURE(ec
)) {
1883 dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec
));
1885 DecimalFormat
* dec
= dynamic_cast<DecimalFormat
*>(nf
);
1887 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
1890 valid
= dec
->getLocale(ULOC_VALID_LOCALE
, ec
);
1891 actual
= dec
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1892 if (U_FAILURE(ec
)) {
1893 errln("FAIL: DecimalFormat::getLocale() failed");
1895 _checklocs("DecimalFormat", req
, valid
, actual
);
1898 const DecimalFormatSymbols
* sym
= dec
->getDecimalFormatSymbols();
1900 errln("FAIL: getDecimalFormatSymbols returned NULL");
1903 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1904 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1905 if (U_FAILURE(ec
)) {
1906 errln("FAIL: DecimalFormatSymbols::getLocale() failed");
1908 _checklocs("DecimalFormatSymbols", req
, valid
, actual
);
1915 // DateFormat, DateFormatSymbols
1916 #if !UCONFIG_NO_FORMATTING
1918 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1919 req
= "de_CH_LUCERNE";
1921 DateFormat::createDateInstance(DateFormat::kDefault
,
1922 Locale::createFromName(req
));
1924 dataerrln("Error calling DateFormat::createDateInstance()");
1926 SimpleDateFormat
* dat
= dynamic_cast<SimpleDateFormat
*>(df
);
1928 errln("FAIL: DateFormat::createInstance does not return a SimpleDateFormat");
1931 valid
= dat
->getLocale(ULOC_VALID_LOCALE
, ec
);
1932 actual
= dat
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1933 if (U_FAILURE(ec
)) {
1934 errln("FAIL: SimpleDateFormat::getLocale() failed");
1936 _checklocs("SimpleDateFormat", req
, valid
, actual
);
1939 const DateFormatSymbols
* sym
= dat
->getDateFormatSymbols();
1941 errln("FAIL: getDateFormatSymbols returned NULL");
1944 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1945 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1946 if (U_FAILURE(ec
)) {
1947 errln("FAIL: DateFormatSymbols::getLocale() failed");
1949 _checklocs("DateFormatSymbols", req
, valid
, actual
);
1957 #if !UCONFIG_NO_BREAK_ITERATION
1959 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1960 req
= "es_ES_BARCELONA";
1961 reqLoc
= Locale::createFromName(req
);
1962 BreakIterator
* brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1963 if (U_FAILURE(ec
)) {
1964 dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_errorName(ec
));
1966 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1967 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1968 if (U_FAILURE(ec
)) {
1969 errln("FAIL: BreakIterator::getLocale() failed");
1971 _checklocs("BreakIterator", req
, valid
, actual
);
1974 // After registering something, the behavior should be different
1975 URegistryKey key
= BreakIterator::registerInstance(brk
, reqLoc
, UBRK_WORD
, ec
);
1976 brk
= 0; // registerInstance adopts
1977 if (U_FAILURE(ec
)) {
1978 errln("FAIL: BreakIterator::registerInstance() failed");
1980 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1981 if (U_FAILURE(ec
)) {
1982 errln("FAIL: BreakIterator::createWordInstance failed");
1984 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1985 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1986 if (U_FAILURE(ec
)) {
1987 errln("FAIL: BreakIterator::getLocale() failed");
1989 // N.B.: now expect valid==actual==req
1990 _checklocs("BreakIterator(registered)",
1991 req
, valid
, actual
, "eq", "eq");
1994 // No matter what, unregister
1995 BreakIterator::unregister(key
, ec
);
1996 if (U_FAILURE(ec
)) {
1997 errln("FAIL: BreakIterator::unregister() failed");
2003 // After unregistering, should behave normally again
2004 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2005 if (U_FAILURE(ec
)) {
2006 errln("FAIL: BreakIterator::createWordInstance failed");
2008 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2009 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2010 if (U_FAILURE(ec
)) {
2011 errln("FAIL: BreakIterator::getLocale() failed");
2013 _checklocs("BreakIterator(unregistered)", req
, valid
, actual
);
2022 #if !UCONFIG_NO_COLLATION
2024 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2026 checkRegisteredCollators(NULL
); // Don't expect any extras
2028 req
= "hi_IN_BHOPAL";
2029 reqLoc
= Locale::createFromName(req
);
2030 Collator
* coll
= Collator::createInstance(reqLoc
, ec
);
2031 if (U_FAILURE(ec
)) {
2032 dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(ec
));
2034 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2035 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2036 if (U_FAILURE(ec
)) {
2037 errln("FAIL: Collator::getLocale() failed");
2039 _checklocs("Collator", req
, valid
, actual
);
2042 // After registering something, the behavior should be different
2043 URegistryKey key
= Collator::registerInstance(coll
, reqLoc
, ec
);
2044 coll
= 0; // registerInstance adopts
2045 if (U_FAILURE(ec
)) {
2046 errln("FAIL: Collator::registerInstance() failed");
2048 coll
= Collator::createInstance(reqLoc
, ec
);
2049 if (U_FAILURE(ec
)) {
2050 errln("FAIL: Collator::createWordInstance failed");
2052 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2053 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2054 if (U_FAILURE(ec
)) {
2055 errln("FAIL: Collator::getLocale() failed");
2057 // N.B.: now expect valid==actual==req
2058 _checklocs("Collator(registered)",
2059 req
, valid
, actual
, "eq", "eq");
2062 checkRegisteredCollators(req
); // include hi_IN_BHOPAL
2064 // No matter what, unregister
2065 Collator::unregister(key
, ec
);
2066 if (U_FAILURE(ec
)) {
2067 errln("FAIL: Collator::unregister() failed");
2073 // After unregistering, should behave normally again
2074 coll
= Collator::createInstance(reqLoc
, ec
);
2075 if (U_FAILURE(ec
)) {
2076 errln("FAIL: Collator::createInstance failed");
2078 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2079 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2080 if (U_FAILURE(ec
)) {
2081 errln("FAIL: Collator::getLocale() failed");
2083 _checklocs("Collator(unregistered)", req
, valid
, actual
);
2089 checkRegisteredCollators(NULL
); // extra should be gone again
2095 #if !UCONFIG_NO_COLLATION
2097 * Compare Collator::getAvailableLocales(int) [ "old", returning an array ]
2098 * with Collator::getAvailableLocales() [ "new", returning a StringEnumeration ]
2099 * These should be identical (check their API docs) EXCEPT that
2100 * if expectExtra is non-NULL, it will be in the "new" array but not "old".
2101 * Does not return any status but calls errln on error.
2102 * @param expectExtra an extra locale, will be in "new" but not "old". Or NULL.
2104 void LocaleTest::checkRegisteredCollators(const char *expectExtra
) {
2105 UErrorCode status
= U_ZERO_ERROR
;
2106 int32_t count1
=0,count2
=0;
2107 Hashtable
oldHash(status
);
2108 Hashtable
newHash(status
);
2109 TEST_ASSERT_STATUS(status
);
2111 UnicodeString
expectStr(expectExtra
?expectExtra
:"n/a", "");
2113 // the 'old' list (non enumeration)
2114 const Locale
* oldList
= Collator::getAvailableLocales(count1
);
2115 if(oldList
== NULL
) {
2116 dataerrln("Error: Collator::getAvailableLocales(count) returned NULL");
2120 // the 'new' list (enumeration)
2121 LocalPointer
<StringEnumeration
> newEnum(Collator::getAvailableLocales());
2122 if(newEnum
.isNull()) {
2123 errln("Error: collator::getAvailableLocales() returned NULL");
2127 // OK. Let's add all of the OLD
2128 // then check for any in the NEW not in OLD
2129 // then check for any in OLD not in NEW.
2131 // 1. add all of OLD
2132 for(int32_t i
=0;i
<count1
;i
++) {
2133 const UnicodeString
key(oldList
[i
].getName(), "");
2134 int32_t oldI
= oldHash
.puti(key
, 1, status
);
2136 errln("Error: duplicate key %s in Collator::getAvailableLocales(count) list.\n",
2137 oldList
[i
].getName());
2140 if(expectExtra
!= NULL
&& !strcmp(expectExtra
, oldList
[i
].getName())) {
2141 errln("Inexplicably, Collator::getAvailableCollators(count) had registered collator %s. This shouldn't happen, so I am going to consider it an error.\n", expectExtra
);
2145 // 2. add all of NEW
2146 const UnicodeString
*locStr
;
2147 UBool foundExpected
= FALSE
;
2148 while((locStr
= newEnum
->snext(status
)) && U_SUCCESS(status
)) {
2151 if(expectExtra
!= NULL
&& expectStr
== *locStr
) {
2152 foundExpected
= TRUE
;
2153 logln(UnicodeString("Found expected registered collator: ","") + expectStr
);
2155 (void)foundExpected
; // Hush unused variable compiler warning.
2157 if( oldHash
.geti(*locStr
) == 0 ) {
2158 if(expectExtra
!= NULL
&& expectStr
==*locStr
) {
2159 logln(UnicodeString("As expected, Collator::getAvailableLocales(count) is missing registered collator ") + expectStr
);
2161 errln(UnicodeString("Error: Collator::getAvailableLocales(count) is missing: ","")
2165 newHash
.puti(*locStr
, 1, status
);
2168 // 3. check all of OLD again
2169 for(int32_t i
=0;i
<count1
;i
++) {
2170 const UnicodeString
key(oldList
[i
].getName(), "");
2171 int32_t newI
= newHash
.geti(key
);
2173 errln(UnicodeString("Error: Collator::getAvailableLocales() is missing: ","")
2178 int32_t expectCount2
= count1
;
2179 if(expectExtra
!= NULL
) {
2180 expectCount2
++; // if an extra item registered, bump the expect count
2183 assertEquals("Collator::getAvail() count", expectCount2
, count2
);
2189 void LocaleTest::TestVariantWithOutCountry(void) {
2190 Locale
loc("en","","POSIX");
2191 if (0 != strcmp(loc
.getVariant(), "POSIX")) {
2192 errln("FAIL: en__POSIX didn't get parsed correctly - name is %s - expected %s got %s", loc
.getName(), "POSIX", loc
.getVariant());
2194 Locale
loc2("en","","FOUR");
2195 if (0 != strcmp(loc2
.getVariant(), "FOUR")) {
2196 errln("FAIL: en__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc2
.getName(), "FOUR", loc2
.getVariant());
2198 Locale
loc3("en","Latn","","FOUR");
2199 if (0 != strcmp(loc3
.getVariant(), "FOUR")) {
2200 errln("FAIL: en_Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc3
.getName(), "FOUR", loc3
.getVariant());
2202 Locale
loc4("","Latn","","FOUR");
2203 if (0 != strcmp(loc4
.getVariant(), "FOUR")) {
2204 errln("FAIL: _Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc4
.getName(), "FOUR", loc4
.getVariant());
2206 Locale
loc5("","Latn","US","FOUR");
2207 if (0 != strcmp(loc5
.getVariant(), "FOUR")) {
2208 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc5
.getName(), "FOUR", loc5
.getVariant());
2210 Locale
loc6("de-1901");
2211 if (0 != strcmp(loc6
.getVariant(), "1901")) {
2212 errln("FAIL: de-1901 didn't get parsed correctly - name is %s - expected %s got %s", loc6
.getName(), "1901", loc6
.getVariant());
2216 static Locale
_canonicalize(int32_t selector
, /* 0==createFromName, 1==createCanonical, 2==Locale ct */
2217 const char* localeID
) {
2220 return Locale::createFromName(localeID
);
2222 return Locale::createCanonical(localeID
);
2224 return Locale(localeID
);
2230 void LocaleTest::TestCanonicalization(void)
2232 static const struct {
2233 const char *localeID
; /* input */
2234 const char *getNameID
; /* expected getName() result */
2235 const char *canonicalID
; /* expected canonicalize() result */
2237 { "", "", "en_US_POSIX" },
2238 { "C", "c", "en_US_POSIX" },
2239 { "POSIX", "posix", "en_US_POSIX" },
2240 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2241 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2242 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2243 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
2244 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
2245 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
2246 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
2247 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
2248 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
2249 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
2250 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
2251 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
2252 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
2253 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
2254 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
2255 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
2256 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
2257 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
2258 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
2259 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
2260 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
2261 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
2262 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
2263 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
2264 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
2265 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
2266 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
2267 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
2268 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
2269 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
2270 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
2271 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2272 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2273 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2274 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2275 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2276 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2277 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2278 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2279 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
2280 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
2281 // TODO: unify this behavior
2282 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
2283 { "de-1901", "de__1901", "de__1901" }, /* registered name */
2284 { "de-1906", "de__1906", "de__1906" }, /* registered name */
2285 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
2286 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
2287 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
2288 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
2289 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
2290 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
2291 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
2293 /* posix behavior that used to be performed by getName */
2294 { "mr.utf8", "mr.utf8", "mr" },
2295 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2296 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2297 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2298 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2299 { "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 */
2301 /* fleshing out canonicalization */
2302 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2303 { "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" },
2304 /* already-canonical ids are not changed */
2305 { "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" },
2306 /* PRE_EURO and EURO conversions don't affect other keywords */
2307 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
2308 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
2309 /* currency keyword overrides PRE_EURO and EURO currency */
2310 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
2311 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
2312 /* norwegian is just too weird, if we handle things in their full generality */
2313 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2315 /* test cases reflecting internal resource bundle usage */
2316 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2317 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2318 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" }
2321 static const char* label
[] = { "createFromName", "createCanonical", "Locale" };
2325 for (i
=0; i
< (int)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
2326 for (j
=0; j
<3; ++j
) {
2327 const char* expected
= (j
==1) ? testCases
[i
].canonicalID
: testCases
[i
].getNameID
;
2328 Locale loc
= _canonicalize(j
, testCases
[i
].localeID
);
2329 const char* getName
= loc
.isBogus() ? "BOGUS" : loc
.getName();
2330 if(uprv_strcmp(expected
, getName
) != 0) {
2331 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"",
2332 label
[j
], testCases
[i
].localeID
, getName
, expected
);
2334 logln("Ok: %s(%s) => \"%s\"",
2335 label
[j
], testCases
[i
].localeID
, getName
);
2341 void LocaleTest::TestCurrencyByDate(void)
2343 #if !UCONFIG_NO_FORMATTING
2344 UErrorCode status
= U_ZERO_ERROR
;
2345 UDate date
= uprv_getUTCtime();
2349 UnicodeString tempStr
, resultStr
;
2351 // Cycle through historical currencies
2352 date
= (UDate
)-630720000000.0; // pre 1961 - no currency defined
2353 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2356 errcheckln(status
, "FAIL: didn't return 0 for eo_AM - %s", u_errorName(status
));
2358 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2360 errcheckln(status
, "FAIL: eo_AM didn't return NULL - %s", u_errorName(status
));
2362 status
= U_ZERO_ERROR
;
2364 date
= (UDate
)0.0; // 1970 - one currency defined
2365 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2368 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2370 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2372 resultStr
.setTo("SUR");
2373 if (resultStr
!= tempStr
) {
2374 errcheckln(status
, "FAIL: didn't return SUR for eo_AM - %s", u_errorName(status
));
2377 date
= (UDate
)693792000000.0; // 1992 - one currency defined
2378 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2381 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2383 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2385 resultStr
.setTo("RUR");
2386 if (resultStr
!= tempStr
) {
2387 errcheckln(status
, "FAIL: didn't return RUR for eo_AM - %s", u_errorName(status
));
2390 date
= (UDate
)977616000000.0; // post 1993 - one currency defined
2391 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2394 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2396 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2398 resultStr
.setTo("AMD");
2399 if (resultStr
!= tempStr
) {
2400 errcheckln(status
, "FAIL: didn't return AMD for eo_AM - %s", u_errorName(status
));
2403 // Locale AD has multiple currencies at once
2404 date
= (UDate
)977616000000.0; // year 2001
2405 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2408 errcheckln(status
, "FAIL: didn't return 4 for eo_AD - %s", u_errorName(status
));
2410 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2412 resultStr
.setTo("EUR");
2413 if (resultStr
!= tempStr
) {
2414 errcheckln(status
, "FAIL: didn't return EUR for eo_AD - %s", u_errorName(status
));
2416 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2418 resultStr
.setTo("ESP");
2419 if (resultStr
!= tempStr
) {
2420 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2422 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2424 resultStr
.setTo("FRF");
2425 if (resultStr
!= tempStr
) {
2426 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2428 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 4, TMP
, 4, &status
);
2430 resultStr
.setTo("ADP");
2431 if (resultStr
!= tempStr
) {
2432 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2435 date
= (UDate
)0.0; // year 1970
2436 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2439 errcheckln(status
, "FAIL: didn't return 3 for eo_AD - %s", u_errorName(status
));
2441 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2443 resultStr
.setTo("ESP");
2444 if (resultStr
!= tempStr
) {
2445 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2447 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2449 resultStr
.setTo("FRF");
2450 if (resultStr
!= tempStr
) {
2451 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2453 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2455 resultStr
.setTo("ADP");
2456 if (resultStr
!= tempStr
) {
2457 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2460 date
= (UDate
)-630720000000.0; // year 1950
2461 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2464 errcheckln(status
, "FAIL: didn't return 2 for eo_AD - %s", u_errorName(status
));
2466 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2468 resultStr
.setTo("ESP");
2469 if (resultStr
!= tempStr
) {
2470 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2472 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2474 resultStr
.setTo("ADP");
2475 if (resultStr
!= tempStr
) {
2476 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2479 date
= (UDate
)-2207520000000.0; // year 1900
2480 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2483 errcheckln(status
, "FAIL: didn't return 1 for eo_AD - %s", u_errorName(status
));
2485 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2487 resultStr
.setTo("ESP");
2488 if (resultStr
!= tempStr
) {
2489 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2492 // Locale UA has gap between years 1994 - 1996
2493 date
= (UDate
)788400000000.0;
2494 index
= ucurr_countCurrencies("eo_UA", date
, &status
);
2497 errcheckln(status
, "FAIL: didn't return 0 for eo_UA - %s", u_errorName(status
));
2499 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, index
, TMP
, 4, &status
);
2501 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2503 status
= U_ZERO_ERROR
;
2505 // Test index bounds
2506 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 100, TMP
, 4, &status
);
2508 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2510 status
= U_ZERO_ERROR
;
2512 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 0, TMP
, 4, &status
);
2514 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2516 status
= U_ZERO_ERROR
;
2518 // Test for bogus locale
2519 index
= ucurr_countCurrencies("eo_QQ", date
, &status
);
2522 errcheckln(status
, "FAIL: didn't return 0 for eo_QQ - %s", u_errorName(status
));
2524 status
= U_ZERO_ERROR
;
2525 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 1, TMP
, 4, &status
);
2527 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2529 status
= U_ZERO_ERROR
;
2530 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 0, TMP
, 4, &status
);
2532 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2534 status
= U_ZERO_ERROR
;
2536 // Cycle through histrocial currencies
2537 date
= (UDate
)977616000000.0; // 2001 - one currency
2538 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2541 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2543 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2545 resultStr
.setTo("AOA");
2546 if (resultStr
!= tempStr
) {
2547 errcheckln(status
, "FAIL: didn't return AOA for eo_AO - %s", u_errorName(status
));
2550 date
= (UDate
)819936000000.0; // 1996 - 2 currencies
2551 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2554 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2556 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2558 resultStr
.setTo("AOR");
2559 if (resultStr
!= tempStr
) {
2560 errcheckln(status
, "FAIL: didn't return AOR for eo_AO - %s", u_errorName(status
));
2562 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2564 resultStr
.setTo("AON");
2565 if (resultStr
!= tempStr
) {
2566 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2569 date
= (UDate
)662256000000.0; // 1991 - 2 currencies
2570 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2573 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2575 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2577 resultStr
.setTo("AON");
2578 if (resultStr
!= tempStr
) {
2579 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2581 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2583 resultStr
.setTo("AOK");
2584 if (resultStr
!= tempStr
) {
2585 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2588 date
= (UDate
)315360000000.0; // 1980 - one currency
2589 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2592 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2594 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2596 resultStr
.setTo("AOK");
2597 if (resultStr
!= tempStr
) {
2598 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2601 date
= (UDate
)0.0; // 1970 - no currencies
2602 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2605 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2607 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2609 errcheckln(status
, "FAIL: eo_AO didn't return NULL - %s", u_errorName(status
));
2611 status
= U_ZERO_ERROR
;
2613 // Test with currency keyword override
2614 date
= (UDate
)977616000000.0; // 2001 - two currencies
2615 index
= ucurr_countCurrencies("eo_DE@currency=DEM", date
, &status
);
2618 errcheckln(status
, "FAIL: didn't return 2 for eo_DE@currency=DEM - %s", u_errorName(status
));
2620 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 1, TMP
, 4, &status
);
2622 resultStr
.setTo("EUR");
2623 if (resultStr
!= tempStr
) {
2624 errcheckln(status
, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s", u_errorName(status
));
2626 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 2, TMP
, 4, &status
);
2628 resultStr
.setTo("DEM");
2629 if (resultStr
!= tempStr
) {
2630 errcheckln(status
, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s", u_errorName(status
));
2633 // Test Euro Support
2634 status
= U_ZERO_ERROR
; // reset
2635 date
= uprv_getUTCtime();
2638 ucurr_forLocaleAndDate("en_US", date
, 1, USD
, 4, &status
);
2641 ucurr_forLocaleAndDate("ja_JP", date
, 1, YEN
, 4, &status
);
2643 ucurr_forLocaleAndDate("en_US", date
, 1, TMP
, 4, &status
);
2644 if (u_strcmp(USD
, TMP
) != 0) {
2645 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
2647 ucurr_forLocaleAndDate("en_US_PREEURO", date
, 1, TMP
, 4, &status
);
2648 if (u_strcmp(USD
, TMP
) != 0) {
2649 errcheckln(status
, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status
));
2651 ucurr_forLocaleAndDate("en_US_Q", date
, 1, TMP
, 4, &status
);
2652 if (u_strcmp(USD
, TMP
) != 0) {
2653 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
2655 status
= U_ZERO_ERROR
; // reset
2659 void LocaleTest::TestGetVariantWithKeywords(void)
2661 Locale
l("en_US_VALLEY@foo=value");
2662 const char *variant
= l
.getVariant();
2664 test_assert(strcmp("VALLEY", variant
) == 0);
2666 UErrorCode status
= U_ZERO_ERROR
;
2668 int32_t len
= l
.getKeywordValue("foo", buffer
, 50, status
);
2670 test_assert(strcmp("value", buffer
) == 0);
2673 void LocaleTest::TestIsRightToLeft() {
2674 assertFalse("root LTR", Locale::getRoot().isRightToLeft());
2675 assertFalse("zh LTR", Locale::getChinese().isRightToLeft());
2676 assertTrue("ar RTL", Locale("ar").isRightToLeft());
2677 assertTrue("und-EG RTL", Locale("und-EG").isRightToLeft(), FALSE
, TRUE
);
2678 assertFalse("fa-Cyrl LTR", Locale("fa-Cyrl").isRightToLeft());
2679 assertTrue("en-Hebr RTL", Locale("en-Hebr").isRightToLeft());
2680 assertTrue("ckb RTL", Locale("ckb").isRightToLeft(), FALSE
, TRUE
); // Sorani Kurdish
2681 assertFalse("fil LTR", Locale("fil").isRightToLeft());
2682 assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft());
2685 void LocaleTest::TestBug11421() {
2686 Locale::getDefault().getBaseName();
2688 const Locale
*localeList
= Locale::getAvailableLocales(numLocales
);
2689 for (int localeIndex
= 0; localeIndex
< numLocales
; localeIndex
++) {
2690 const Locale
&loc
= localeList
[localeIndex
];
2691 if (strncmp(loc
.getName(), loc
.getBaseName(), strlen(loc
.getBaseName()))) {
2692 errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"",
2693 __FILE__
, __LINE__
, loc
.getName(), loc
.getBaseName());