1 /********************************************************************
3 * Copyright (c) 1997-2016, 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"
19 #include "unicode/ustring.h"
22 static const char* const rawData
[33][8] = {
25 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
27 { "", "", "", "", "", "", "", "Hans" },
29 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" },
31 { "", "", "", "", "NY", "", "", "" },
33 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" },
35 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" },
37 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" },
39 { "409", "40c", "403", "408", "814", "10", "0", "804" },
41 // display langage (English)
42 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" },
43 // display script (English)
44 { "", "", "", "", "", "", "", "Simplified Han" },
45 // display country (English)
46 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China" },
47 // display variant (English)
48 { "", "", "", "", "NY", "", "", ""},
49 // display name (English)
50 // Updated no_NO_NY English display name for new pattern-based algorithm
51 // (part of Euro support).
52 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplified, China)" },
54 // display langage (French)
55 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
56 // display script (French)
57 { "", "", "", "", "", "", "", "sinogrammes simplifi\\u00E9s" },
58 // display country (French)
59 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine" },
60 // display variant (French)
61 { "", "", "", "", "NY", "", "", "" },
62 // display name (French)
63 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
64 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois (simplifi\\u00E9, Chine)" },
67 /* display language (Catalan) */
68 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E8s" },
69 /* display script (Catalan) */
70 { "", "", "", "", "", "", "", "han simplificat" },
71 /* display country (Catalan) */
72 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina" },
73 /* display variant (Catalan) */
74 { "", "", "", "", "NY", "", "" },
75 /* display name (Catalan) */
76 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E8s (simplificat, Xina)" },
78 // display langage (Greek)[actual values listed below]
79 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
80 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
81 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
82 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
83 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
84 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
86 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
88 // display script (Greek)
89 { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd" },
90 // display country (Greek)[actual values listed below]
91 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
92 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
93 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
94 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
95 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
98 "\\u039A\\u03AF\\u03BD\\u03B1"
100 // display variant (Greek)
101 { "", "", "", "", "NY", "", "" },
102 // display name (Greek)[actual values listed below]
103 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
104 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
105 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
106 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
107 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
108 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
110 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf, \\u039A\\u03AF\\u03BD\\u03B1)"
113 // display langage (<root>)
114 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" },
115 // display script (<root>)
116 { "", "", "", "", "", "", "", ""},
117 // display country (<root>)
118 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" },
119 // display variant (<root>)
120 { "", "", "", "", "Nynorsk", "", "", ""},
121 // display name (<root>)
122 //{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" },
123 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
129 test_assert( Test (should be TRUE) )
134 the macro is ugly but makes the tests pretty.
137 #define test_assert(test) \
140 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \
142 logln("PASS: asserted " #test); \
147 test_assert_print( Test (should be TRUE), printable )
150 test_assert(i==3, toString(i));
152 the macro is ugly but makes the tests pretty.
155 #define test_assert_print(test,print) \
158 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \
160 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \
164 #define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); }
166 LocaleTest::LocaleTest()
172 LocaleTest::~LocaleTest()
174 if (dataTable
!= 0) {
175 for (int32_t i
= 0; i
< 33; i
++) {
176 delete []dataTable
[i
];
183 void LocaleTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
186 TESTCASE_AUTO(TestBug11421
); // Must run early in list to trigger failure.
187 TESTCASE_AUTO(TestBasicGetters
);
188 TESTCASE_AUTO(TestSimpleResourceInfo
);
189 TESTCASE_AUTO(TestDisplayNames
);
190 TESTCASE_AUTO(TestSimpleObjectStuff
);
191 TESTCASE_AUTO(TestPOSIXParsing
);
192 TESTCASE_AUTO(TestGetAvailableLocales
);
193 TESTCASE_AUTO(TestDataDirectory
);
194 TESTCASE_AUTO(TestISO3Fallback
);
195 TESTCASE_AUTO(TestGetLangsAndCountries
);
196 TESTCASE_AUTO(TestSimpleDisplayNames
);
197 TESTCASE_AUTO(TestUninstalledISO3Names
);
198 TESTCASE_AUTO(TestAtypicalLocales
);
199 #if !UCONFIG_NO_FORMATTING
200 TESTCASE_AUTO(TestThaiCurrencyFormat
);
201 TESTCASE_AUTO(TestEuroSupport
);
203 TESTCASE_AUTO(TestToString
);
204 #if !UCONFIG_NO_FORMATTING
205 TESTCASE_AUTO(Test4139940
);
206 TESTCASE_AUTO(Test4143951
);
208 TESTCASE_AUTO(Test4147315
);
209 TESTCASE_AUTO(Test4147317
);
210 TESTCASE_AUTO(Test4147552
);
211 TESTCASE_AUTO(TestVariantParsing
);
212 #if !UCONFIG_NO_FORMATTING
213 TESTCASE_AUTO(Test4105828
);
215 TESTCASE_AUTO(TestSetIsBogus
);
216 TESTCASE_AUTO(TestParallelAPIValues
);
217 TESTCASE_AUTO(TestKeywordVariants
);
218 TESTCASE_AUTO(TestKeywordVariantParsing
);
219 TESTCASE_AUTO(TestSetKeywordValue
);
220 TESTCASE_AUTO(TestGetBaseName
);
221 #if !UCONFIG_NO_FILE_IO
222 TESTCASE_AUTO(TestGetLocale
);
224 TESTCASE_AUTO(TestVariantWithOutCountry
);
225 TESTCASE_AUTO(TestCanonicalization
);
226 TESTCASE_AUTO(TestCurrencyByDate
);
227 TESTCASE_AUTO(TestGetVariantWithKeywords
);
228 TESTCASE_AUTO(TestIsRightToLeft
);
232 void LocaleTest::TestBasicGetters() {
236 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
237 Locale
testLocale("");
238 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
239 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
242 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
244 logln("Testing " + (UnicodeString
)testLocale
.getName() + "...");
246 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
247 errln(" Language code mismatch: " + temp
+ " versus "
248 + dataTable
[LANG
][i
]);
249 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
250 errln(" Script code mismatch: " + temp
+ " versus "
251 + dataTable
[SCRIPT
][i
]);
252 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
253 errln(" Country code mismatch: " + temp
+ " versus "
254 + dataTable
[CTRY
][i
]);
255 if ( (temp
=testLocale
.getVariant()) != (dataTable
[VAR
][i
]))
256 errln(" Variant code mismatch: " + temp
+ " versus "
257 + dataTable
[VAR
][i
]);
258 if ( (temp
=testLocale
.getName()) != (dataTable
[NAME
][i
]))
259 errln(" Locale name mismatch: " + temp
+ " versus "
260 + dataTable
[NAME
][i
]);
263 logln("Same thing without variant codes...");
264 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
265 Locale
testLocale("");
266 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
267 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
]);
270 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
]);
272 logln("Testing " + (temp
=testLocale
.getName()) + "...");
274 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
275 errln("Language code mismatch: " + temp
+ " versus "
276 + dataTable
[LANG
][i
]);
277 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
278 errln("Script code mismatch: " + temp
+ " versus "
279 + dataTable
[SCRIPT
][i
]);
280 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
281 errln("Country code mismatch: " + temp
+ " versus "
282 + dataTable
[CTRY
][i
]);
283 if (testLocale
.getVariant()[0] != 0)
284 errln("Variant code mismatch: something versus \"\"");
287 logln("Testing long language names and getters");
288 Locale test8
= Locale::createFromName("x-klingon-latn-zx.utf32be@special");
290 temp
= test8
.getLanguage();
291 if (temp
!= UnicodeString("x-klingon") )
292 errln("Language code mismatch: " + temp
+ " versus \"x-klingon\"");
294 temp
= test8
.getScript();
295 if (temp
!= UnicodeString("Latn") )
296 errln("Script code mismatch: " + temp
+ " versus \"Latn\"");
298 temp
= test8
.getCountry();
299 if (temp
!= UnicodeString("ZX") )
300 errln("Country code mismatch: " + temp
+ " versus \"ZX\"");
302 temp
= test8
.getVariant();
303 //if (temp != UnicodeString("SPECIAL") )
304 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\"");
305 // As of 3.0, the "@special" will *not* be parsed by uloc_getName()
306 if (temp
!= UnicodeString("") )
307 errln("Variant code mismatch: " + temp
+ " versus \"\"");
309 if (Locale::getDefault() != Locale::createFromName(NULL
))
310 errln("Locale::getDefault() == Locale::createFromName(NULL)");
313 // NOTE: There used to be a special test for locale names that had language or
314 // country codes that were longer than two letters. The new version of Locale
315 // doesn't support anything that isn't an officially recognized language or
316 // country code, so we no longer support this feature.
318 Locale
bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code too long
319 if(!bogusLang
.isBogus()) {
320 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE");
323 bogusLang
=Locale("eo");
324 if( bogusLang
.isBogus() ||
325 strcmp(bogusLang
.getLanguage(), "eo")!=0 ||
326 *bogusLang
.getCountry()!=0 ||
327 *bogusLang
.getVariant()!=0 ||
328 strcmp(bogusLang
.getName(), "eo")!=0
330 errln("assignment to bogus Locale does not unbogus it or sets bad data");
333 Locale
a("eo_DE@currency=DEM");
334 Locale
*pb
=a
.clone();
335 if(pb
==&a
|| *pb
!=a
) {
336 errln("Locale.clone() failed");
341 void LocaleTest::TestParallelAPIValues() {
342 logln("Test synchronization between C and C++ API");
343 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE
) != 0) {
344 errln("Differences for ULOC_CHINESE Locale");
346 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH
) != 0) {
347 errln("Differences for ULOC_ENGLISH Locale");
349 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH
) != 0) {
350 errln("Differences for ULOC_FRENCH Locale");
352 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN
) != 0) {
353 errln("Differences for ULOC_GERMAN Locale");
355 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN
) != 0) {
356 errln("Differences for ULOC_ITALIAN Locale");
358 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE
) != 0) {
359 errln("Differences for ULOC_JAPANESE Locale");
361 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN
) != 0) {
362 errln("Differences for ULOC_KOREAN Locale");
364 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE
) != 0) {
365 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale");
367 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINESE
) != 0) {
368 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale");
372 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA
) != 0) {
373 errln("Differences for ULOC_CANADA Locale");
375 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH
) != 0) {
376 errln("Differences for ULOC_CANADA_FRENCH Locale");
378 if (strcmp(Locale::getChina().getName(), ULOC_CHINA
) != 0) {
379 errln("Differences for ULOC_CHINA Locale");
381 if (strcmp(Locale::getPRC().getName(), ULOC_PRC
) != 0) {
382 errln("Differences for ULOC_PRC Locale");
384 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE
) != 0) {
385 errln("Differences for ULOC_FRANCE Locale");
387 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY
) != 0) {
388 errln("Differences for ULOC_GERMANY Locale");
390 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY
) != 0) {
391 errln("Differences for ULOC_ITALY Locale");
393 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN
) != 0) {
394 errln("Differences for ULOC_JAPAN Locale");
396 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA
) != 0) {
397 errln("Differences for ULOC_KOREA Locale");
399 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN
) != 0) {
400 errln("Differences for ULOC_TAIWAN Locale");
402 if (strcmp(Locale::getUK().getName(), ULOC_UK
) != 0) {
403 errln("Differences for ULOC_UK Locale");
405 if (strcmp(Locale::getUS().getName(), ULOC_US
) != 0) {
406 errln("Differences for ULOC_US Locale");
411 void LocaleTest::TestSimpleResourceInfo() {
414 UErrorCode err
= U_ZERO_ERROR
;
417 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
418 Locale
testLocale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
419 logln("Testing " + (temp
=testLocale
.getName()) + "...");
421 if ( (temp
=testLocale
.getISO3Language()) != (dataTable
[LANG3
][i
]))
422 errln(" ISO-3 language code mismatch: " + temp
423 + " versus " + dataTable
[LANG3
][i
]);
424 if ( (temp
=testLocale
.getISO3Country()) != (dataTable
[CTRY3
][i
]))
425 errln(" ISO-3 country code mismatch: " + temp
426 + " versus " + dataTable
[CTRY3
][i
]);
428 sprintf(temp2
, "%x", (int)testLocale
.getLCID());
429 if (UnicodeString(temp2
) != dataTable
[LCID
][i
])
430 errln((UnicodeString
)" LCID mismatch: " + temp2
+ " versus "
431 + dataTable
[LCID
][i
]);
435 errln((UnicodeString
)"Some error on number " + i
+ u_errorName(err
));
441 if(strcmp(locale
.getName(), "en") != 0||
442 strcmp(locale
.getLanguage(), "en") != 0) {
443 errln("construction of Locale(en) failed\n");
450 * Jitterbug 2439 -- markus 20030425
452 * The lookup of display names must not fall back through the default
453 * locale because that yields useless results.
456 LocaleTest::TestDisplayNames()
458 Locale
english("en", "US");
459 Locale
french("fr", "FR");
460 Locale
croatian("ca", "ES");
461 Locale
greek("el", "GR");
463 logln(" In locale = en_US...");
464 doTestDisplayNames(english
, DLANG_EN
);
465 logln(" In locale = fr_FR...");
466 doTestDisplayNames(french
, DLANG_FR
);
467 logln(" In locale = ca_ES...");
468 doTestDisplayNames(croatian
, DLANG_CA
);
469 logln(" In locale = el_GR...");
470 doTestDisplayNames(greek
, DLANG_EL
);
473 UErrorCode status
= U_ZERO_ERROR
;
475 #if !UCONFIG_NO_FORMATTING
476 DecimalFormatSymbols
symb(status
);
477 /* Check to see if ICU supports this locale */
478 if (symb
.getLocale(ULOC_VALID_LOCALE
, status
) != Locale("root")) {
479 /* test that the default locale has a display name for its own language */
480 /* Currently, there is no language information in the "tl" data file so this test will fail if default locale is "tl" */
481 if (uprv_strcmp(Locale().getLanguage(), "tl") != 0) {
482 Locale().getDisplayLanguage(Locale(), s
);
483 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
484 /* check <=3 to reject getting the language code as a display name */
485 dataerrln("unable to get a display string for the language of the default locale: " + s
);
489 * API coverage improvements: call
490 * Locale::getDisplayLanguage(UnicodeString &) and
491 * Locale::getDisplayCountry(UnicodeString &)
494 Locale().getDisplayLanguage(s
);
495 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
496 dataerrln("unable to get a display string for the language of the default locale [2]: " + s
);
501 logln("Default locale %s is unsupported by ICU\n", Locale().getName());
506 french
.getDisplayCountry(s
);
508 errln("unable to get any default-locale display string for the country of fr_FR\n");
511 Locale("zh", "Hant").getDisplayScript(s
);
513 errln("unable to get any default-locale display string for the country of zh_Hant\n");
517 void LocaleTest::TestSimpleObjectStuff() {
518 Locale
test1("aa", "AA");
519 Locale
test2("aa", "AA");
521 Locale
test4("zz", "ZZ");
522 Locale
test5("aa", "AA", "");
523 Locale
test6("aa", "AA", "ANTARES");
524 Locale
test7("aa", "AA", "JUPITER");
525 Locale test8
= Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that
527 // now list them all for debugging usage.
528 test_dumpLocale(test1
);
529 test_dumpLocale(test2
);
530 test_dumpLocale(test3
);
531 test_dumpLocale(test4
);
532 test_dumpLocale(test5
);
533 test_dumpLocale(test6
);
534 test_dumpLocale(test7
);
535 test_dumpLocale(test8
);
537 // Make sure things compare to themselves!
538 test_assert(test1
== test1
);
539 test_assert(test2
== test2
);
540 test_assert(test3
== test3
);
541 test_assert(test4
== test4
);
542 test_assert(test5
== test5
);
543 test_assert(test6
== test6
);
544 test_assert(test7
== test7
);
545 test_assert(test8
== test8
);
547 // make sure things are not equal to themselves.
548 test_assert(!(test1
!= test1
));
549 test_assert(!(test2
!= test2
));
550 test_assert(!(test3
!= test3
));
551 test_assert(!(test4
!= test4
));
552 test_assert(!(test5
!= test5
));
553 test_assert(!(test6
!= test6
));
554 test_assert(!(test7
!= test7
));
555 test_assert(!(test8
!= test8
));
557 // make sure things that are equal to each other don't show up as unequal.
558 test_assert(!(test1
!= test2
));
559 test_assert(!(test2
!= test1
));
560 test_assert(!(test1
!= test3
));
561 test_assert(!(test2
!= test3
));
562 test_assert(test5
== test1
);
563 test_assert(test6
!= test2
);
564 test_assert(test6
!= test5
);
566 test_assert(test6
!= test7
);
568 // test for things that shouldn't compare equal.
569 test_assert(!(test1
== test4
));
570 test_assert(!(test2
== test4
));
571 test_assert(!(test3
== test4
));
573 test_assert(test7
== test8
);
575 // test for hash codes to be the same.
576 int32_t hash1
= test1
.hashCode();
577 int32_t hash2
= test2
.hashCode();
578 int32_t hash3
= test3
.hashCode();
580 test_assert(hash1
== hash2
);
581 test_assert(hash1
== hash3
);
582 test_assert(hash2
== hash3
);
584 // test that the assignment operator works.
586 logln("test4=test1;");
587 test_dumpLocale(test4
);
588 test_assert(test4
== test4
);
590 test_assert(!(test1
!= test4
));
591 test_assert(!(test2
!= test4
));
592 test_assert(!(test3
!= test4
));
593 test_assert(test1
== test4
);
594 test_assert(test4
== test1
);
596 // test assignments with a variant
597 logln("test7 = test6");
599 test_dumpLocale(test7
);
600 test_assert(test7
== test7
);
601 test_assert(test7
== test6
);
602 test_assert(test7
!= test5
);
604 logln("test6 = test1");
606 test_dumpLocale(test6
);
607 test_assert(test6
!= test7
);
608 test_assert(test6
== test1
);
609 test_assert(test6
== test6
);
612 // A class which exposes constructors that are implemented in terms of the POSIX parsing code.
613 class POSIXLocale
: public Locale
616 POSIXLocale(const UnicodeString
& l
)
620 ch
= new char[l
.length() + 1];
621 ch
[l
.extract(0, 0x7fffffff, ch
, "")] = 0;
625 POSIXLocale(const char *l
)
632 void LocaleTest::TestPOSIXParsing()
634 POSIXLocale
test1("ab_AB");
635 POSIXLocale
test2(UnicodeString("ab_AB"));
636 Locale
test3("ab","AB");
638 POSIXLocale
test4("ab_AB_Antares");
639 POSIXLocale
test5(UnicodeString("ab_AB_Antares"));
640 Locale
test6("ab", "AB", "Antares");
642 test_dumpLocale(test1
);
643 test_dumpLocale(test2
);
644 test_dumpLocale(test3
);
645 test_dumpLocale(test4
);
646 test_dumpLocale(test5
);
647 test_dumpLocale(test6
);
649 test_assert(test1
== test1
);
651 test_assert(test1
== test2
);
652 test_assert(test2
== test3
);
653 test_assert(test3
== test1
);
655 test_assert(test4
== test5
);
656 test_assert(test5
== test6
);
657 test_assert(test6
== test4
);
659 test_assert(test1
!= test4
);
660 test_assert(test5
!= test3
);
661 test_assert(test5
!= test2
);
663 int32_t hash1
= test1
.hashCode();
664 int32_t hash2
= test2
.hashCode();
665 int32_t hash3
= test3
.hashCode();
667 test_assert(hash1
== hash2
);
668 test_assert(hash2
== hash3
);
669 test_assert(hash3
== hash1
);
672 void LocaleTest::TestGetAvailableLocales()
674 int32_t locCount
= 0;
675 const Locale
* locList
= Locale::getAvailableLocales(locCount
);
678 dataerrln("getAvailableLocales() returned an empty list!");
680 logln(UnicodeString("Number of locales returned = ") + locCount
);
682 for(int32_t i
= 0; i
< locCount
; ++i
)
683 logln(locList
[i
].getName());
685 // I have no idea how to test this function...
688 // This test isn't applicable anymore - getISO3Language is
689 // independent of the data directory
690 void LocaleTest::TestDataDirectory()
693 char oldDirectory[80];
695 UErrorCode err = U_ZERO_ERROR;
696 UnicodeString testValue;
698 temp = Locale::getDataDirectory();
699 strcpy(oldDirectory, temp);
700 logln(UnicodeString("oldDirectory = ") + oldDirectory);
702 Locale test(Locale::US);
703 test.getISO3Language(testValue);
704 logln("first fetch of language retrieved " + testValue);
705 if (testValue != "eng")
706 errln("Initial check of ISO3 language failed: expected \"eng\", got \"" + testValue + "\"");
710 path=IntlTest::getTestDirectory();
711 Locale::setDataDirectory( path );
714 test.getISO3Language(testValue);
715 logln("second fetch of language retrieved " + testValue);
716 if (testValue != "xxx")
717 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue + "\"");
719 Locale::setDataDirectory(oldDirectory);
720 test.getISO3Language(testValue);
721 logln("third fetch of language retrieved " + testValue);
722 if (testValue != "eng")
723 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testValue + "\"");
727 //===========================================================
729 void LocaleTest::doTestDisplayNames(Locale
& displayLocale
, int32_t compareIndex
) {
732 for (int32_t i
= 0; i
<= MAX_LOCALES
; i
++) {
733 Locale
testLocale("");
734 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
735 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
738 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
740 logln(" Testing " + (temp
=testLocale
.getName()) + "...");
742 UnicodeString testLang
;
743 UnicodeString testScript
;
744 UnicodeString testCtry
;
745 UnicodeString testVar
;
746 UnicodeString testName
;
748 testLocale
.getDisplayLanguage(displayLocale
, testLang
);
749 testLocale
.getDisplayScript(displayLocale
, testScript
);
750 testLocale
.getDisplayCountry(displayLocale
, testCtry
);
751 testLocale
.getDisplayVariant(displayLocale
, testVar
);
752 testLocale
.getDisplayName(displayLocale
, testName
);
754 UnicodeString expectedLang
;
755 UnicodeString expectedScript
;
756 UnicodeString expectedCtry
;
757 UnicodeString expectedVar
;
758 UnicodeString expectedName
;
760 expectedLang
= dataTable
[compareIndex
][i
];
761 if (expectedLang
.length() == 0)
762 expectedLang
= dataTable
[DLANG_EN
][i
];
764 expectedScript
= dataTable
[compareIndex
+ 1][i
];
765 if (expectedScript
.length() == 0)
766 expectedScript
= dataTable
[DSCRIPT_EN
][i
];
768 expectedCtry
= dataTable
[compareIndex
+ 2][i
];
769 if (expectedCtry
.length() == 0)
770 expectedCtry
= dataTable
[DCTRY_EN
][i
];
772 expectedVar
= dataTable
[compareIndex
+ 3][i
];
773 if (expectedVar
.length() == 0)
774 expectedVar
= dataTable
[DVAR_EN
][i
];
776 expectedName
= dataTable
[compareIndex
+ 4][i
];
777 if (expectedName
.length() == 0)
778 expectedName
= dataTable
[DNAME_EN
][i
];
780 if (testLang
!= expectedLang
)
781 dataerrln("Display language (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testLang
+ " expected " + expectedLang
);
782 if (testScript
!= expectedScript
)
783 dataerrln("Display script (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testScript
+ " expected " + expectedScript
);
784 if (testCtry
!= expectedCtry
)
785 dataerrln("Display country (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testCtry
+ " expected " + expectedCtry
);
786 if (testVar
!= expectedVar
)
787 dataerrln("Display variant (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testVar
+ " expected " + expectedVar
);
788 if (testName
!= expectedName
)
789 dataerrln("Display name (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testName
+ " expected " + expectedName
);
793 //---------------------------------------------------
794 // table of valid data
795 //---------------------------------------------------
799 void LocaleTest::setUpDataTable()
801 if (dataTable
== 0) {
802 dataTable
= new UnicodeString
*[33];
804 for (int32_t i
= 0; i
< 33; i
++) {
805 dataTable
[i
] = new UnicodeString
[8];
806 for (int32_t j
= 0; j
< 8; j
++) {
807 dataTable
[i
][j
] = CharsToUnicodeString(rawData
[i
][j
]);
813 // ====================
817 * @bug 4011756 4011380
820 LocaleTest::TestISO3Fallback()
822 Locale
test("xx", "YY");
826 result
= test
.getISO3Language();
828 // Conform to C API usage
830 if (!result
|| (result
[0] != 0))
831 errln("getISO3Language() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
833 result
= test
.getISO3Country();
835 if (!result
|| (result
[0] != 0))
836 errln("getISO3Country() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
840 * @bug 4106155 4118587
843 LocaleTest::TestGetLangsAndCountries()
845 // It didn't seem right to just do an exhaustive test of everything here, so I check
846 // for the following things:
847 // 1) Does each list have the right total number of entries?
848 // 2) Does each list contain certain language and country codes we think are important
849 // (the G7 countries, plus a couple others)?
850 // 3) Does each list have every entry formatted correctly? (i.e., two characters,
851 // all lower case for the language codes, all upper case for the country codes)
852 // 4) Is each list in sorted order?
853 int32_t testCount
= 0;
854 const char * const * test
= Locale::getISOLanguages();
855 const char spotCheck1
[ ][4] = { "en", "es", "fr", "de", "it",
856 "ja", "ko", "zh", "th", "he",
857 "id", "iu", "ug", "yi", "za" };
861 for(testCount
= 0;test
[testCount
];testCount
++)
864 /* TODO: Change this test to be more like the cloctst version? */
865 if (testCount
!= 594)
866 errln("Expected getISOLanguages() to return 594 languages; it returned %d", testCount
);
868 for (i
= 0; i
< 15; i
++) {
870 for (j
= 0; j
< testCount
; j
++)
871 if (uprv_strcmp(test
[j
],spotCheck1
[i
])== 0)
873 if (j
== testCount
|| (uprv_strcmp(test
[j
],spotCheck1
[i
])!=0))
874 errln("Couldn't find " + (UnicodeString
)spotCheck1
[i
] + " in language list.");
877 for (i
= 0; i
< testCount
; i
++) {
878 UnicodeString
testee(test
[i
],"");
879 UnicodeString
lc(test
[i
],"");
880 if (testee
!= lc
.toLower())
881 errln(lc
+ " is not all lower case.");
882 if ( (testee
.length() != 2) && (testee
.length() != 3))
883 errln(testee
+ " is not two or three characters long.");
884 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
885 errln(testee
+ " appears in an out-of-order position in the list.");
888 test
= Locale::getISOCountries();
889 UnicodeString spotCheck2
[] = { "US", "CA", "GB", "FR", "DE",
890 "IT", "JP", "KR", "CN", "TW",
892 int32_t spot2Len
= 11;
893 for(testCount
=0;test
[testCount
];testCount
++)
896 if (testCount
!= 256){
897 errln("Expected getISOCountries to return 256 countries; it returned %d", testCount
);
899 for (i
= 0; i
< spot2Len
; i
++) {
901 for (j
= 0; j
< testCount
; j
++)
903 UnicodeString
testee(test
[j
],"");
905 if (testee
== spotCheck2
[i
])
908 UnicodeString
testee(test
[j
],"");
909 if (j
== testCount
|| testee
!= spotCheck2
[i
])
910 errln("Couldn't find " + spotCheck2
[i
] + " in country list.");
913 for (i
= 0; i
< testCount
; i
++) {
914 UnicodeString
testee(test
[i
],"");
915 UnicodeString
uc(test
[i
],"");
916 if (testee
!= uc
.toUpper())
917 errln(testee
+ " is not all upper case.");
918 if (testee
.length() != 2)
919 errln(testee
+ " is not two characters long.");
920 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
921 errln(testee
+ " appears in an out-of-order position in the list.");
924 // This getAvailableLocales and getISO3Language
926 int32_t numOfLocales
;
928 const Locale
*pLocales
= Locale::getAvailableLocales(numOfLocales
);
930 for (int i
= 0; i
< numOfLocales
; i
++) {
931 const Locale
&loc(pLocales
[i
]);
935 loc
.getDisplayName (enLoc
, name
);
936 name
.extract (0, 200, szName
, sizeof(szName
));
938 if (strlen(loc
.getISO3Language()) == 0) {
939 errln("getISO3Language() returned an empty string for: " + name
);
949 LocaleTest::TestSimpleDisplayNames()
951 // This test is different from TestDisplayNames because TestDisplayNames checks
952 // fallback behavior, combination of language and country names to form locale
953 // names, and other stuff like that. This test just checks specific language
954 // and country codes to make sure we have the correct names for them.
955 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
956 UnicodeString languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
959 for (int32_t i
= 0; i
< 6; i
++) {
961 Locale
l(languageCodes
[i
], "", "");
962 l
.getDisplayLanguage(Locale::getUS(), test
);
963 if (test
!= languageNames
[i
])
964 dataerrln("Got wrong display name for " + UnicodeString(languageCodes
[i
]) + ": Expected \"" +
965 languageNames
[i
] + "\", got \"" + test
+ "\".");
973 LocaleTest::TestUninstalledISO3Names()
975 // This test checks to make sure getISO3Language and getISO3Country work right
976 // even for locales that are not installed.
977 const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
979 const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
980 "ssw", "twi", "zul" };
984 for (i
= 0; i
< 8; i
++) {
985 UErrorCode err
= U_ZERO_ERROR
;
988 Locale
l(iso2Languages
[i
], "", "");
989 test
= l
.getISO3Language();
990 if((test
!= iso3Languages
[i
]) || U_FAILURE(err
))
991 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages
[i
]) + ": Expected \"" +
992 iso3Languages
[i
] + "\", got \"" + test
+ "\"." + UnicodeString(u_errorName(err
)));
995 char iso2Countries
[][4] = { "AF", "BW", "KZ", "MO", "MN",
997 char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
998 "SLB", "TCA", "ZWE" };
1000 for (i
= 0; i
< 8; i
++) {
1001 UErrorCode err
= U_ZERO_ERROR
;
1002 Locale
l("", iso2Countries
[i
], "");
1003 UnicodeString
test(l
.getISO3Country(), "");
1004 if (test
!= iso3Countries
[i
])
1005 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries
[i
]) + ": Expected \"" +
1006 UnicodeString(iso3Countries
[i
]) + "\", got \"" + test
+ "\"." + u_errorName(err
));
1012 * I could not reproduce this bug. I'm pretty convinced it was fixed with the
1013 * big locale-data reorg of 10/28/97. The lookup logic for language and country
1014 * display names was also changed at that time in that check-in. --rtg 3/20/98
1017 LocaleTest::TestAtypicalLocales()
1019 Locale localesToTest
[] = { Locale("de", "CA"),
1029 UnicodeString englishDisplayNames
[] = { "German (Canada)",
1030 "Japanese (South Africa)",
1033 "Spanish (Germany)",
1036 "Dominican Republic",
1038 UnicodeString frenchDisplayNames
[]= { "allemand (Canada)",
1039 "japonais (Afrique du Sud)",
1042 "espagnol (Allemagne)",
1044 CharsToUnicodeString("Su\\u00E8de"),
1045 CharsToUnicodeString("R\\u00E9publique dominicaine"),
1047 UnicodeString spanishDisplayNames
[] = {
1048 CharsToUnicodeString("alem\\u00E1n (Canad\\u00E1)"),
1049 CharsToUnicodeString("japon\\u00E9s (Sud\\u00E1frica)"),
1050 CharsToUnicodeString("ruso (M\\u00E9xico)"),
1051 CharsToUnicodeString("ingl\\u00E9s (Francia)"),
1052 CharsToUnicodeString("espa\\u00F1ol (Alemania)"),
1055 CharsToUnicodeString("Rep\\u00FAblica Dominicana"),
1056 CharsToUnicodeString("B\\u00E9lgica") };
1057 // De-Anglicizing root required the change from
1058 // English display names to ISO Codes - ram 2003/09/26
1059 UnicodeString invDisplayNames
[] = { "German (Canada)",
1060 "Japanese (South Africa)",
1063 "Spanish (Germany)",
1066 "Dominican Republic",
1070 UErrorCode status
= U_ZERO_ERROR
;
1072 Locale::setDefault(Locale::getUS(), status
);
1073 for (i
= 0; i
< 9; ++i
) {
1075 localesToTest
[i
].getDisplayName(Locale::getUS(), name
);
1077 if (name
!= englishDisplayNames
[i
])
1079 dataerrln("Lookup in English failed: expected \"" + englishDisplayNames
[i
]
1080 + "\", got \"" + name
+ "\"");
1081 logln("Locale name was-> " + (name
=localesToTest
[i
].getName()));
1085 for (i
= 0; i
< 9; i
++) {
1087 localesToTest
[i
].getDisplayName(Locale("es", "ES"), name
);
1089 if (name
!= spanishDisplayNames
[i
])
1090 dataerrln("Lookup in Spanish failed: expected \"" + spanishDisplayNames
[i
]
1091 + "\", got \"" + name
+ "\"");
1094 for (i
= 0; i
< 9; i
++) {
1096 localesToTest
[i
].getDisplayName(Locale::getFrance(), name
);
1098 if (name
!= frenchDisplayNames
[i
])
1099 dataerrln("Lookup in French failed: expected \"" + frenchDisplayNames
[i
]
1100 + "\", got \"" + name
+ "\"");
1103 for (i
= 0; i
< 9; i
++) {
1105 localesToTest
[i
].getDisplayName(Locale("inv", "IN"), name
);
1106 logln(name
+ " Locale fallback to be, and data fallback to root");
1107 if (name
!= invDisplayNames
[i
])
1108 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1109 + "\", got \"" + prettify(name
) + "\"");
1110 localesToTest
[i
].getDisplayName(Locale("inv", "BD"), name
);
1111 logln(name
+ " Data fallback to root");
1112 if (name
!= invDisplayNames
[i
])
1113 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1114 + "\", got \"" + prettify(name
)+ "\"");
1116 Locale::setDefault(saveLocale
, status
);
1119 #if !UCONFIG_NO_FORMATTING
1123 * This would be better tested by the LocaleDataTest. Will move it when I
1124 * get the LocaleDataTest working again.
1127 LocaleTest::TestThaiCurrencyFormat()
1129 UErrorCode status
= U_ZERO_ERROR
;
1130 DecimalFormat
*thaiCurrency
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(
1131 Locale("th", "TH"), status
);
1132 UnicodeString
posPrefix("THB", 3, US_INV
); // per cldrbug 7618
1135 if(U_FAILURE(status
) || !thaiCurrency
)
1137 dataerrln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status
)));
1140 if (thaiCurrency
->getPositivePrefix(temp
) != posPrefix
)
1141 errln("Thai currency prefix wrong: expected THB, got \"" +
1142 thaiCurrency
->getPositivePrefix(temp
) + "\"");
1143 if (thaiCurrency
->getPositiveSuffix(temp
) != "")
1144 errln("Thai currency suffix wrong: expected \"\", got \"" +
1145 thaiCurrency
->getPositiveSuffix(temp
) + "\"");
1147 delete thaiCurrency
;
1152 * Confirm that Euro support works. This test is pretty rudimentary; all it does
1153 * is check that any locales with the EURO variant format a number using the
1154 * Euro currency symbol.
1156 * ASSUME: All locales encode the Euro character "\u20AC".
1157 * If this is changed to use the single-character Euro symbol, this
1158 * test must be updated.
1162 LocaleTest::TestEuroSupport()
1164 UChar euro
= 0x20ac;
1165 const UnicodeString
EURO_CURRENCY(&euro
, 1, 1); // Look for this UnicodeString in formatted Euro currency
1166 const char* localeArr
[] = {
1190 const char** locales
= localeArr
;
1192 UErrorCode status
= U_ZERO_ERROR
;
1196 for (;*locales
!=NULL
;locales
++) {
1197 Locale
loc (*locales
);
1199 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(loc
, status
);
1202 if (U_FAILURE(status
)) {
1203 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales
);
1207 nf
->format(271828.182845, pos
);
1209 nf
->format(-271828.182845, neg
);
1210 if (pos
.indexOf(EURO_CURRENCY
) >= 0 &&
1211 neg
.indexOf(EURO_CURRENCY
) >= 0) {
1212 logln("Ok: " + (temp
=loc
.getName()) +
1213 ": " + pos
+ " / " + neg
);
1216 errln("Fail: " + (temp
=loc
.getName()) +
1217 " formats without " + EURO_CURRENCY
+
1218 ": " + pos
+ " / " + neg
+
1219 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***");
1225 UnicodeString
dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar
)0x00a4), resultStr
;
1227 status
= U_ZERO_ERROR
;
1229 ucurr_forLocale("en_US", tmp
, 4, &status
);
1230 resultStr
.setTo(tmp
);
1231 if (dollarStr
!= resultStr
) {
1232 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
1234 ucurr_forLocale("en_US_EURO", tmp
, 4, &status
);
1235 resultStr
.setTo(tmp
);
1236 if (euroStr
!= resultStr
) {
1237 errcheckln(status
, "Fail: en_US_EURO didn't return EUR - %s", u_errorName(status
));
1239 ucurr_forLocale("en_GB_EURO", tmp
, 4, &status
);
1240 resultStr
.setTo(tmp
);
1241 if (euroStr
!= resultStr
) {
1242 errcheckln(status
, "Fail: en_GB_EURO didn't return EUR - %s", u_errorName(status
));
1244 ucurr_forLocale("en_US_PREEURO", tmp
, 4, &status
);
1245 resultStr
.setTo(tmp
);
1246 if (dollarStr
!= resultStr
) {
1247 errcheckln(status
, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status
));
1249 ucurr_forLocale("en_US_Q", tmp
, 4, &status
);
1250 resultStr
.setTo(tmp
);
1251 if (dollarStr
!= resultStr
) {
1252 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
1254 int32_t invalidLen
= ucurr_forLocale("en_QQ", tmp
, 4, &status
);
1255 if (invalidLen
|| U_SUCCESS(status
)) {
1256 errln("Fail: en_QQ didn't return NULL");
1264 * toString() doesn't work with language_VARIANT.
1267 LocaleTest::TestToString() {
1269 Locale("xx", "", ""),
1270 Locale("", "YY", ""),
1271 Locale("", "", "ZZ"),
1272 Locale("xx", "YY", ""),
1273 Locale("xx", "", "ZZ"),
1274 Locale("", "YY", "ZZ"),
1275 Locale("xx", "YY", "ZZ"),
1278 const char DATA_S
[][20] = {
1288 for (int32_t i
=0; i
< 7; ++i
) {
1290 name
= DATA
[i
].getName();
1292 if (strcmp(name
, DATA_S
[i
]) != 0)
1294 errln("Fail: Locale.getName(), got:" + UnicodeString(name
) + ", expected: " + DATA_S
[i
]);
1297 logln("Pass: Locale.getName(), got:" + UnicodeString(name
) );
1301 #if !UCONFIG_NO_FORMATTING
1305 * Couldn't reproduce this bug -- probably was fixed earlier.
1307 * ORIGINAL BUG REPORT:
1308 * -- basically, hungarian for monday shouldn't have an \u00f4
1309 * (o circumflex)in it instead it should be an o with 2 inclined
1310 * (right) lines over it..
1312 * You may wonder -- why do all this -- why not just add a line to
1313 * LocaleData? Well, I could see by inspection that the locale file had the
1314 * right character in it, so I wanted to check the rest of the pipeline -- a
1315 * very remote possibility, but I wanted to be sure. The other possibility
1316 * is that something is wrong with the font mapping subsystem, but we can't
1320 LocaleTest::Test4139940()
1322 Locale
mylocale("hu", "", "");
1323 UDate mydate
= date(98,3,13); // A Monday
1324 UErrorCode status
= U_ZERO_ERROR
;
1325 SimpleDateFormat
df_full("EEEE", mylocale
, status
);
1326 if(U_FAILURE(status
)){
1327 dataerrln(UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: ") + UnicodeString(u_errorName(status
)));
1331 FieldPosition
pos(FieldPosition::DONT_CARE
);
1332 df_full
.format(mydate
, str
, pos
);
1333 // Make sure that o circumflex (\u00F4) is NOT there, and
1334 // o double acute (\u0151) IS.
1337 if (str
.indexOf(oda
) < 0 || str
.indexOf(ocf
) >= 0) {
1338 /* If the default locale is "th" this test will fail because of the buddhist calendar. */
1339 if (strcmp(Locale::getDefault().getLanguage(), "th") != 0) {
1340 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
1341 str
.indexOf(oda
), str
.indexOf(ocf
));
1343 logln(UnicodeString("An error is produce in buddhist calendar."));
1345 logln(UnicodeString("String is: ") + str
);
1350 LocaleTest::date(int32_t y
, int32_t m
, int32_t d
, int32_t hr
, int32_t min
, int32_t sec
)
1352 UErrorCode status
= U_ZERO_ERROR
;
1353 Calendar
*cal
= Calendar::createInstance(status
);
1357 cal
->set(1900 + y
, m
, d
, hr
, min
, sec
); // Add 1900 to follow java.util.Date protocol
1358 UDate dt
= cal
->getTime(status
);
1359 if (U_FAILURE(status
))
1368 * Russian first day of week should be Monday. Confirmed.
1371 LocaleTest::Test4143951()
1373 UErrorCode status
= U_ZERO_ERROR
;
1374 Calendar
*cal
= Calendar::createInstance(Locale("ru", "", ""), status
);
1375 if(U_SUCCESS(status
)) {
1376 if (cal
->getFirstDayOfWeek(status
) != UCAL_MONDAY
) {
1377 dataerrln("Fail: First day of week in Russia should be Monday");
1387 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes.
1388 * Should throw an exception for unknown locales
1391 LocaleTest::Test4147315()
1394 // Try with codes that are the wrong length but happen to match text
1395 // at a valid offset in the mapping table
1396 Locale
locale("xxx", "CCC");
1398 const char *result
= locale
.getISO3Country();
1400 // Change to conform to C api usage
1401 if((result
==NULL
)||(result
[0] != 0))
1402 errln("ERROR: getISO3Country() returns: " + UnicodeString(result
,"") +
1403 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1408 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
1409 * Should throw an exception for unknown locales
1412 LocaleTest::Test4147317()
1415 // Try with codes that are the wrong length but happen to match text
1416 // at a valid offset in the mapping table
1417 Locale
locale("xxx", "CCC");
1419 const char *result
= locale
.getISO3Language();
1421 // Change to conform to C api usage
1422 if((result
==NULL
)||(result
[0] != 0))
1423 errln("ERROR: getISO3Language() returns: " + UnicodeString(result
,"") +
1424 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1431 LocaleTest::Test4147552()
1433 Locale locales
[] = { Locale("no", "NO"),
1434 Locale("no", "NO", "B"),
1435 Locale("no", "NO", "NY")
1438 UnicodeString
edn("Norwegian (Norway, B)");
1439 UnicodeString englishDisplayNames
[] = {
1440 "Norwegian (Norway)",
1442 // "Norwegian (Norway,B)",
1443 //"Norwegian (Norway,NY)"
1444 "Norwegian (Norway, NY)"
1446 UnicodeString
ndn("norsk (Norge, B");
1447 UnicodeString norwegianDisplayNames
[] = {
1452 //"Norsk (Noreg, Nynorsk)"
1454 UErrorCode status
= U_ZERO_ERROR
;
1457 Locale::setDefault(Locale::getEnglish(), status
);
1458 for (int32_t i
= 0; i
< 3; ++i
) {
1459 Locale loc
= locales
[i
];
1461 if (loc
.getDisplayName(temp
) != englishDisplayNames
[i
])
1462 dataerrln("English display-name mismatch: expected " +
1463 englishDisplayNames
[i
] + ", got " + loc
.getDisplayName(temp
));
1464 if (loc
.getDisplayName(loc
, temp
) != norwegianDisplayNames
[i
])
1465 dataerrln("Norwegian display-name mismatch: expected " +
1466 norwegianDisplayNames
[i
] + ", got " +
1467 loc
.getDisplayName(loc
, temp
));
1469 Locale::setDefault(saveLocale
, status
);
1473 LocaleTest::TestVariantParsing()
1475 Locale
en_US_custom("en", "US", "De Anza_Cupertino_California_United States_Earth");
1477 UnicodeString
dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)");
1478 UnicodeString
dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH");
1482 en_US_custom
.getDisplayVariant(Locale::getUS(), got
);
1483 if(got
!= dispVar
) {
1484 errln("FAIL: getDisplayVariant()");
1485 errln("Wanted: " + dispVar
);
1486 errln("Got : " + got
);
1489 en_US_custom
.getDisplayName(Locale::getUS(), got
);
1490 if(got
!= dispName
) {
1491 dataerrln("FAIL: getDisplayName()");
1492 dataerrln("Wanted: " + dispName
);
1493 dataerrln("Got : " + got
);
1496 Locale
shortVariant("fr", "FR", "foo");
1497 shortVariant
.getDisplayVariant(got
);
1500 errln("FAIL: getDisplayVariant()");
1501 errln("Wanted: foo");
1502 errln("Got : " + got
);
1505 Locale
bogusVariant("fr", "FR", "_foo");
1506 bogusVariant
.getDisplayVariant(got
);
1509 errln("FAIL: getDisplayVariant()");
1510 errln("Wanted: foo");
1511 errln("Got : " + got
);
1514 Locale
bogusVariant2("fr", "FR", "foo_");
1515 bogusVariant2
.getDisplayVariant(got
);
1518 errln("FAIL: getDisplayVariant()");
1519 errln("Wanted: foo");
1520 errln("Got : " + got
);
1523 Locale
bogusVariant3("fr", "FR", "_foo_");
1524 bogusVariant3
.getDisplayVariant(got
);
1527 errln("FAIL: getDisplayVariant()");
1528 errln("Wanted: foo");
1529 errln("Got : " + got
);
1533 #if !UCONFIG_NO_FORMATTING
1537 * Currency symbol in zh is wrong. We will test this at the NumberFormat
1538 * end to test the whole pipe.
1541 LocaleTest::Test4105828()
1543 Locale LOC
[] = { Locale::getChinese(), Locale("zh", "CN", ""),
1544 Locale("zh", "TW", ""), Locale("zh", "HK", "") };
1545 UErrorCode status
= U_ZERO_ERROR
;
1546 for (int32_t i
= 0; i
< 4; ++i
) {
1547 NumberFormat
*fmt
= NumberFormat::createPercentInstance(LOC
[i
], status
);
1548 if(U_FAILURE(status
)) {
1549 dataerrln("Couldn't create NumberFormat - %s", u_errorName(status
));
1552 UnicodeString result
;
1553 FieldPosition
pos(0);
1554 fmt
->format((int32_t)1, result
, pos
);
1556 if(result
!= "100%") {
1557 errln(UnicodeString("Percent for ") + LOC
[i
].getDisplayName(temp
) + " should be 100%, got " + result
);
1565 // Tests setBogus and isBogus APIs for Locale
1568 LocaleTest::TestSetIsBogus() {
1571 if(l
.isBogus() != TRUE
) {
1572 errln("After setting bogus, didn't return TRUE");
1574 l
= "en_US"; // This should reset bogus
1575 if(l
.isBogus() != FALSE
) {
1576 errln("After resetting bogus, didn't return FALSE");
1582 LocaleTest::TestKeywordVariants(void) {
1583 static const struct {
1584 const char *localeID
;
1585 const char *expectedLocaleID
;
1586 //const char *expectedLocaleIDNoKeywords;
1587 //const char *expectedCanonicalID;
1588 const char *expectedKeywords
[10];
1589 int32_t numKeywords
;
1590 UErrorCode expectedStatus
;
1593 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1594 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1596 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1597 {"calendar", "collation", "currency"},
1605 //"de_DE@currency=EUR",
1606 {"","","","","","",""},
1608 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1611 UErrorCode status
= U_ZERO_ERROR
;
1613 int32_t i
= 0, j
= 0;
1614 const char *result
= NULL
;
1615 StringEnumeration
*keywords
;
1616 int32_t keyCount
= 0;
1617 const char *keyword
= NULL
;
1618 const UnicodeString
*keywordString
;
1619 int32_t keywordLen
= 0;
1621 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1622 status
= U_ZERO_ERROR
;
1623 Locale
l(testCases
[i
].localeID
);
1624 keywords
= l
.createKeywords(status
);
1626 if(status
!= testCases
[i
].expectedStatus
) {
1627 err("Expected to get status %s. Got %s instead\n",
1628 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1630 status
= U_ZERO_ERROR
;
1632 if((keyCount
= keywords
->count(status
)) != testCases
[i
].numKeywords
) {
1633 err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1638 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1641 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1642 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1645 if((keywordString
= keywords
->snext(status
)) == NULL
) {
1648 if(*keywordString
!= UnicodeString(testCases
[i
].expectedKeywords
[j
], "")) {
1649 err("Expected to get keyword UnicodeString %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1654 if(j
== keyCount
/ 2) {
1655 // replace keywords with a clone of itself
1656 StringEnumeration
*k2
= keywords
->clone();
1657 if(k2
== NULL
|| keyCount
!= k2
->count(status
)) {
1658 errln("KeywordEnumeration.clone() failed");
1665 keywords
->reset(status
); // Make sure that reset works.
1667 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1670 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1671 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1678 result
= l
.getName();
1679 if(uprv_strcmp(testCases
[i
].expectedLocaleID
, result
) != 0) {
1680 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n",
1681 testCases
[i
].expectedLocaleID
, testCases
[i
].localeID
, result
);
1689 LocaleTest::TestKeywordVariantParsing(void) {
1690 static const struct {
1691 const char *localeID
;
1692 const char *keyword
;
1693 const char *expectedValue
;
1695 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook" },
1696 { "de_DE", "collation", ""},
1697 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" },
1698 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation", "PHONEBOOk" },
1701 UErrorCode status
= U_ZERO_ERROR
;
1704 int32_t resultLen
= 0;
1707 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1709 Locale
l(testCases
[i
].localeID
);
1710 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1711 (void)resultLen
; // Suppress unused variable warning.
1712 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1713 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1714 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1720 LocaleTest::TestSetKeywordValue(void) {
1721 static const struct {
1722 const char *keyword
;
1725 { "collation", "phonebook" },
1726 { "currency", "euro" },
1727 { "calendar", "buddhist" }
1730 UErrorCode status
= U_ZERO_ERROR
;
1733 int32_t resultLen
= 0;
1736 Locale
l(Locale::getGerman());
1738 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1739 l
.setKeywordValue(testCases
[i
].keyword
, testCases
[i
].value
, status
);
1740 if(U_FAILURE(status
)) {
1741 err("FAIL: Locale::setKeywordValue failed - %s\n", u_errorName(status
));
1745 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1746 (void)resultLen
; // Suppress unused variable warning.
1747 if(uprv_strcmp(testCases
[i
].value
, buffer
) != 0) {
1748 err("Expected to extract \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1749 testCases
[i
].value
, testCases
[i
].keyword
, buffer
);
1755 LocaleTest::TestGetBaseName(void) {
1756 static const struct {
1757 const char *localeID
;
1758 const char *baseName
;
1760 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
1761 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
1762 { "ja@calendar = buddhist", "ja" },
1763 { "de-u-co-phonebk", "de"}
1768 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1769 Locale
loc(testCases
[i
].localeID
);
1770 if(strcmp(testCases
[i
].baseName
, loc
.getBaseName())) {
1771 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
1772 testCases
[i
].localeID
, testCases
[i
].baseName
, loc
.getBaseName());
1777 // Verify that adding a keyword to an existing Locale doesn't change the base name.
1778 UErrorCode status
= U_ZERO_ERROR
;
1779 Locale
loc2("en-US");
1780 if (strcmp("en_US", loc2
.getBaseName())) {
1781 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
1783 loc2
.setKeywordValue("key", "value", status
);
1784 if (strcmp("en_US@key=value", loc2
.getName())) {
1785 errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getName());
1787 if (strcmp("en_US", loc2
.getBaseName())) {
1788 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
1793 * Compare two locale IDs. If they are equal, return 0. If `string'
1794 * starts with `prefix' plus an additional element, that is, string ==
1795 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
1797 static UBool
_loccmp(const char* string
, const char* prefix
) {
1798 int32_t slen
= (int32_t)strlen(string
),
1799 plen
= (int32_t)strlen(prefix
);
1800 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
1801 /* 'root' is "less than" everything */
1802 if (uprv_strcmp(prefix
, "root") == 0) {
1803 return (uprv_strcmp(string
, "root") == 0) ? 0 : 1;
1805 if (c
) return -1; /* mismatch */
1806 if (slen
== plen
) return 0;
1807 if (string
[plen
] == '_') return 1;
1808 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
1812 * Check the relationship between requested locales, and report problems.
1813 * The caller specifies the expected relationships between requested
1814 * and valid (expReqValid) and between valid and actual (expValidActual).
1815 * Possible values are:
1816 * "gt" strictly greater than, e.g., en_US > en
1817 * "ge" greater or equal, e.g., en >= en
1818 * "eq" equal, e.g., en == en
1820 void LocaleTest::_checklocs(const char* label
,
1822 const Locale
& validLoc
,
1823 const Locale
& actualLoc
,
1824 const char* expReqValid
,
1825 const char* expValidActual
) {
1826 const char* valid
= validLoc
.getName();
1827 const char* actual
= actualLoc
.getName();
1828 int32_t reqValid
= _loccmp(req
, valid
);
1829 int32_t validActual
= _loccmp(valid
, actual
);
1830 if (((0 == uprv_strcmp(expReqValid
, "gt") && reqValid
> 0) ||
1831 (0 == uprv_strcmp(expReqValid
, "ge") && reqValid
>= 0) ||
1832 (0 == uprv_strcmp(expReqValid
, "eq") && reqValid
== 0)) &&
1833 ((0 == uprv_strcmp(expValidActual
, "gt") && validActual
> 0) ||
1834 (0 == uprv_strcmp(expValidActual
, "ge") && validActual
>= 0) ||
1835 (0 == uprv_strcmp(expValidActual
, "eq") && validActual
== 0))) {
1836 logln("%s; req=%s, valid=%s, actual=%s",
1837 label
, req
, valid
, actual
);
1839 dataerrln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
1840 label
, req
, valid
, actual
,
1841 expReqValid
, expValidActual
);
1845 void LocaleTest::TestGetLocale(void) {
1846 #if !UCONFIG_NO_SERVICE
1848 Locale valid
, actual
, reqLoc
;
1851 #if !UCONFIG_NO_FORMATTING
1853 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1854 req
= "en_US_BROOKLYN";
1855 Calendar
* cal
= Calendar::createInstance(Locale::createFromName(req
), ec
);
1856 if (U_FAILURE(ec
)) {
1857 dataerrln("FAIL: Calendar::createInstance failed - %s", u_errorName(ec
));
1859 valid
= cal
->getLocale(ULOC_VALID_LOCALE
, ec
);
1860 actual
= cal
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1861 if (U_FAILURE(ec
)) {
1862 errln("FAIL: Calendar::getLocale() failed");
1864 _checklocs("Calendar", req
, valid
, actual
);
1866 /* Make sure that it fails correctly */
1867 ec
= U_FILE_ACCESS_ERROR
;
1868 if (cal
->getLocale(ULOC_VALID_LOCALE
, ec
).getName()[0] != 0) {
1869 errln("FAIL: Calendar::getLocale() failed to fail correctly. It should have returned \"\"");
1877 // DecimalFormat, DecimalFormatSymbols
1878 #if !UCONFIG_NO_FORMATTING
1880 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1882 NumberFormat
* nf
= NumberFormat::createInstance(Locale::createFromName(req
), ec
);
1883 if (U_FAILURE(ec
)) {
1884 dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec
));
1886 DecimalFormat
* dec
= dynamic_cast<DecimalFormat
*>(nf
);
1888 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
1891 valid
= dec
->getLocale(ULOC_VALID_LOCALE
, ec
);
1892 actual
= dec
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1893 if (U_FAILURE(ec
)) {
1894 errln("FAIL: DecimalFormat::getLocale() failed");
1896 _checklocs("DecimalFormat", req
, valid
, actual
);
1899 const DecimalFormatSymbols
* sym
= dec
->getDecimalFormatSymbols();
1901 errln("FAIL: getDecimalFormatSymbols returned NULL");
1904 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1905 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1906 if (U_FAILURE(ec
)) {
1907 errln("FAIL: DecimalFormatSymbols::getLocale() failed");
1909 _checklocs("DecimalFormatSymbols", req
, valid
, actual
);
1916 // DateFormat, DateFormatSymbols
1917 #if !UCONFIG_NO_FORMATTING
1919 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1920 req
= "de_CH_LUCERNE";
1922 DateFormat::createDateInstance(DateFormat::kDefault
,
1923 Locale::createFromName(req
));
1925 dataerrln("Error calling DateFormat::createDateInstance()");
1927 SimpleDateFormat
* dat
= dynamic_cast<SimpleDateFormat
*>(df
);
1929 errln("FAIL: DateFormat::createInstance does not return a SimpleDateFormat");
1932 valid
= dat
->getLocale(ULOC_VALID_LOCALE
, ec
);
1933 actual
= dat
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1934 if (U_FAILURE(ec
)) {
1935 errln("FAIL: SimpleDateFormat::getLocale() failed");
1937 _checklocs("SimpleDateFormat", req
, valid
, actual
);
1940 const DateFormatSymbols
* sym
= dat
->getDateFormatSymbols();
1942 errln("FAIL: getDateFormatSymbols returned NULL");
1945 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1946 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1947 if (U_FAILURE(ec
)) {
1948 errln("FAIL: DateFormatSymbols::getLocale() failed");
1950 _checklocs("DateFormatSymbols", req
, valid
, actual
);
1958 #if !UCONFIG_NO_BREAK_ITERATION
1960 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
1961 req
= "es_ES_BARCELONA";
1962 reqLoc
= Locale::createFromName(req
);
1963 BreakIterator
* brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1964 if (U_FAILURE(ec
)) {
1965 dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_errorName(ec
));
1967 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1968 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1969 if (U_FAILURE(ec
)) {
1970 errln("FAIL: BreakIterator::getLocale() failed");
1972 _checklocs("BreakIterator", req
, valid
, actual
);
1975 // After registering something, the behavior should be different
1976 URegistryKey key
= BreakIterator::registerInstance(brk
, reqLoc
, UBRK_WORD
, ec
);
1977 brk
= 0; // registerInstance adopts
1978 if (U_FAILURE(ec
)) {
1979 errln("FAIL: BreakIterator::registerInstance() failed");
1981 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1982 if (U_FAILURE(ec
)) {
1983 errln("FAIL: BreakIterator::createWordInstance failed");
1985 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1986 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1987 if (U_FAILURE(ec
)) {
1988 errln("FAIL: BreakIterator::getLocale() failed");
1990 // N.B.: now expect valid==actual==req
1991 _checklocs("BreakIterator(registered)",
1992 req
, valid
, actual
, "eq", "eq");
1995 // No matter what, unregister
1996 BreakIterator::unregister(key
, ec
);
1997 if (U_FAILURE(ec
)) {
1998 errln("FAIL: BreakIterator::unregister() failed");
2004 // After unregistering, should behave normally again
2005 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2006 if (U_FAILURE(ec
)) {
2007 errln("FAIL: BreakIterator::createWordInstance failed");
2009 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2010 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2011 if (U_FAILURE(ec
)) {
2012 errln("FAIL: BreakIterator::getLocale() failed");
2014 _checklocs("BreakIterator(unregistered)", req
, valid
, actual
);
2023 #if !UCONFIG_NO_COLLATION
2025 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2027 checkRegisteredCollators(NULL
); // Don't expect any extras
2029 req
= "hi_IN_BHOPAL";
2030 reqLoc
= Locale::createFromName(req
);
2031 Collator
* coll
= Collator::createInstance(reqLoc
, ec
);
2032 if (U_FAILURE(ec
)) {
2033 dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(ec
));
2035 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2036 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2037 if (U_FAILURE(ec
)) {
2038 errln("FAIL: Collator::getLocale() failed");
2040 _checklocs("Collator", req
, valid
, actual
);
2043 // After registering something, the behavior should be different
2044 URegistryKey key
= Collator::registerInstance(coll
, reqLoc
, ec
);
2045 coll
= 0; // registerInstance adopts
2046 if (U_FAILURE(ec
)) {
2047 errln("FAIL: Collator::registerInstance() failed");
2049 coll
= Collator::createInstance(reqLoc
, ec
);
2050 if (U_FAILURE(ec
)) {
2051 errln("FAIL: Collator::createWordInstance failed");
2053 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2054 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2055 if (U_FAILURE(ec
)) {
2056 errln("FAIL: Collator::getLocale() failed");
2058 // N.B.: now expect valid==actual==req
2059 _checklocs("Collator(registered)",
2060 req
, valid
, actual
, "eq", "eq");
2063 checkRegisteredCollators(req
); // include hi_IN_BHOPAL
2065 // No matter what, unregister
2066 Collator::unregister(key
, ec
);
2067 if (U_FAILURE(ec
)) {
2068 errln("FAIL: Collator::unregister() failed");
2074 // After unregistering, should behave normally again
2075 coll
= Collator::createInstance(reqLoc
, ec
);
2076 if (U_FAILURE(ec
)) {
2077 errln("FAIL: Collator::createInstance failed");
2079 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2080 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2081 if (U_FAILURE(ec
)) {
2082 errln("FAIL: Collator::getLocale() failed");
2084 _checklocs("Collator(unregistered)", req
, valid
, actual
);
2090 checkRegisteredCollators(NULL
); // extra should be gone again
2096 #if !UCONFIG_NO_COLLATION
2098 * Compare Collator::getAvailableLocales(int) [ "old", returning an array ]
2099 * with Collator::getAvailableLocales() [ "new", returning a StringEnumeration ]
2100 * These should be identical (check their API docs) EXCEPT that
2101 * if expectExtra is non-NULL, it will be in the "new" array but not "old".
2102 * Does not return any status but calls errln on error.
2103 * @param expectExtra an extra locale, will be in "new" but not "old". Or NULL.
2105 void LocaleTest::checkRegisteredCollators(const char *expectExtra
) {
2106 UErrorCode status
= U_ZERO_ERROR
;
2107 int32_t count1
=0,count2
=0;
2108 Hashtable
oldHash(status
);
2109 Hashtable
newHash(status
);
2110 TEST_ASSERT_STATUS(status
);
2112 UnicodeString
expectStr(expectExtra
?expectExtra
:"n/a", "");
2114 // the 'old' list (non enumeration)
2115 const Locale
* oldList
= Collator::getAvailableLocales(count1
);
2116 if(oldList
== NULL
) {
2117 dataerrln("Error: Collator::getAvailableLocales(count) returned NULL");
2121 // the 'new' list (enumeration)
2122 LocalPointer
<StringEnumeration
> newEnum(Collator::getAvailableLocales());
2123 if(newEnum
.isNull()) {
2124 errln("Error: collator::getAvailableLocales() returned NULL");
2128 // OK. Let's add all of the OLD
2129 // then check for any in the NEW not in OLD
2130 // then check for any in OLD not in NEW.
2132 // 1. add all of OLD
2133 for(int32_t i
=0;i
<count1
;i
++) {
2134 const UnicodeString
key(oldList
[i
].getName(), "");
2135 int32_t oldI
= oldHash
.puti(key
, 1, status
);
2137 errln("Error: duplicate key %s in Collator::getAvailableLocales(count) list.\n",
2138 oldList
[i
].getName());
2141 if(expectExtra
!= NULL
&& !strcmp(expectExtra
, oldList
[i
].getName())) {
2142 errln("Inexplicably, Collator::getAvailableCollators(count) had registered collator %s. This shouldn't happen, so I am going to consider it an error.\n", expectExtra
);
2146 // 2. add all of NEW
2147 const UnicodeString
*locStr
;
2148 UBool foundExpected
= FALSE
;
2149 while((locStr
= newEnum
->snext(status
)) && U_SUCCESS(status
)) {
2152 if(expectExtra
!= NULL
&& expectStr
== *locStr
) {
2153 foundExpected
= TRUE
;
2154 logln(UnicodeString("Found expected registered collator: ","") + expectStr
);
2156 (void)foundExpected
; // Hush unused variable compiler warning.
2158 if( oldHash
.geti(*locStr
) == 0 ) {
2159 if(expectExtra
!= NULL
&& expectStr
==*locStr
) {
2160 logln(UnicodeString("As expected, Collator::getAvailableLocales(count) is missing registered collator ") + expectStr
);
2162 errln(UnicodeString("Error: Collator::getAvailableLocales(count) is missing: ","")
2166 newHash
.puti(*locStr
, 1, status
);
2169 // 3. check all of OLD again
2170 for(int32_t i
=0;i
<count1
;i
++) {
2171 const UnicodeString
key(oldList
[i
].getName(), "");
2172 int32_t newI
= newHash
.geti(key
);
2174 errln(UnicodeString("Error: Collator::getAvailableLocales() is missing: ","")
2179 int32_t expectCount2
= count1
;
2180 if(expectExtra
!= NULL
) {
2181 expectCount2
++; // if an extra item registered, bump the expect count
2184 assertEquals("Collator::getAvail() count", expectCount2
, count2
);
2190 void LocaleTest::TestVariantWithOutCountry(void) {
2191 Locale
loc("en","","POSIX");
2192 if (0 != strcmp(loc
.getVariant(), "POSIX")) {
2193 errln("FAIL: en__POSIX didn't get parsed correctly - name is %s - expected %s got %s", loc
.getName(), "POSIX", loc
.getVariant());
2195 Locale
loc2("en","","FOUR");
2196 if (0 != strcmp(loc2
.getVariant(), "FOUR")) {
2197 errln("FAIL: en__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc2
.getName(), "FOUR", loc2
.getVariant());
2199 Locale
loc3("en","Latn","","FOUR");
2200 if (0 != strcmp(loc3
.getVariant(), "FOUR")) {
2201 errln("FAIL: en_Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc3
.getName(), "FOUR", loc3
.getVariant());
2203 Locale
loc4("","Latn","","FOUR");
2204 if (0 != strcmp(loc4
.getVariant(), "FOUR")) {
2205 errln("FAIL: _Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc4
.getName(), "FOUR", loc4
.getVariant());
2207 Locale
loc5("","Latn","US","FOUR");
2208 if (0 != strcmp(loc5
.getVariant(), "FOUR")) {
2209 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc5
.getName(), "FOUR", loc5
.getVariant());
2211 Locale
loc6("de-1901");
2212 if (0 != strcmp(loc6
.getVariant(), "1901")) {
2213 errln("FAIL: de-1901 didn't get parsed correctly - name is %s - expected %s got %s", loc6
.getName(), "1901", loc6
.getVariant());
2217 static Locale
_canonicalize(int32_t selector
, /* 0==createFromName, 1==createCanonical, 2==Locale ct */
2218 const char* localeID
) {
2221 return Locale::createFromName(localeID
);
2223 return Locale::createCanonical(localeID
);
2225 return Locale(localeID
);
2231 void LocaleTest::TestCanonicalization(void)
2233 static const struct {
2234 const char *localeID
; /* input */
2235 const char *getNameID
; /* expected getName() result */
2236 const char *canonicalID
; /* expected canonicalize() result */
2238 { "", "", "en_US_POSIX" },
2239 { "C", "c", "en_US_POSIX" },
2240 { "POSIX", "posix", "en_US_POSIX" },
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_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2244 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
2245 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
2246 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
2247 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
2248 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
2249 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
2250 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
2251 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
2252 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
2253 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
2254 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
2255 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
2256 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
2257 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
2258 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
2259 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
2260 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
2261 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
2262 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
2263 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
2264 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
2265 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
2266 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
2267 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
2268 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
2269 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
2270 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
2271 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
2272 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2273 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2274 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2275 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2276 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2277 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2278 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2279 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2280 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
2281 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
2282 // TODO: unify this behavior
2283 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
2284 { "de-1901", "de__1901", "de__1901" }, /* registered name */
2285 { "de-1906", "de__1906", "de__1906" }, /* registered name */
2286 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */
2287 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */
2288 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */
2289 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
2290 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
2291 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
2292 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
2294 /* posix behavior that used to be performed by getName */
2295 { "mr.utf8", "mr.utf8", "mr" },
2296 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2297 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2298 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2299 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2300 { "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 */
2302 /* fleshing out canonicalization */
2303 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2304 { "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" },
2305 /* already-canonical ids are not changed */
2306 { "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" },
2307 /* PRE_EURO and EURO conversions don't affect other keywords */
2308 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
2309 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
2310 /* currency keyword overrides PRE_EURO and EURO currency */
2311 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
2312 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
2313 /* norwegian is just too weird, if we handle things in their full generality */
2314 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2316 /* test cases reflecting internal resource bundle usage */
2317 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2318 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2319 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" }
2322 static const char* label
[] = { "createFromName", "createCanonical", "Locale" };
2326 for (i
=0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2327 for (j
=0; j
<3; ++j
) {
2328 const char* expected
= (j
==1) ? testCases
[i
].canonicalID
: testCases
[i
].getNameID
;
2329 Locale loc
= _canonicalize(j
, testCases
[i
].localeID
);
2330 const char* getName
= loc
.isBogus() ? "BOGUS" : loc
.getName();
2331 if(uprv_strcmp(expected
, getName
) != 0) {
2332 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"",
2333 label
[j
], testCases
[i
].localeID
, getName
, expected
);
2335 logln("Ok: %s(%s) => \"%s\"",
2336 label
[j
], testCases
[i
].localeID
, getName
);
2342 void LocaleTest::TestCurrencyByDate(void)
2344 #if !UCONFIG_NO_FORMATTING
2345 UErrorCode status
= U_ZERO_ERROR
;
2346 UDate date
= uprv_getUTCtime();
2350 UnicodeString tempStr
, resultStr
;
2352 // Cycle through historical currencies
2353 date
= (UDate
)-630720000000.0; // pre 1961 - no currency defined
2354 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2357 errcheckln(status
, "FAIL: didn't return 0 for eo_AM - %s", u_errorName(status
));
2359 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2361 errcheckln(status
, "FAIL: eo_AM didn't return NULL - %s", u_errorName(status
));
2363 status
= U_ZERO_ERROR
;
2365 date
= (UDate
)0.0; // 1970 - one currency defined
2366 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2369 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2371 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2373 resultStr
.setTo("SUR");
2374 if (resultStr
!= tempStr
) {
2375 errcheckln(status
, "FAIL: didn't return SUR for eo_AM - %s", u_errorName(status
));
2378 date
= (UDate
)693792000000.0; // 1992 - one currency defined
2379 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2382 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2384 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2386 resultStr
.setTo("RUR");
2387 if (resultStr
!= tempStr
) {
2388 errcheckln(status
, "FAIL: didn't return RUR for eo_AM - %s", u_errorName(status
));
2391 date
= (UDate
)977616000000.0; // post 1993 - one currency defined
2392 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2395 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2397 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2399 resultStr
.setTo("AMD");
2400 if (resultStr
!= tempStr
) {
2401 errcheckln(status
, "FAIL: didn't return AMD for eo_AM - %s", u_errorName(status
));
2404 // Locale AD has multiple currencies at once
2405 date
= (UDate
)977616000000.0; // year 2001
2406 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2409 errcheckln(status
, "FAIL: didn't return 4 for eo_AD - %s", u_errorName(status
));
2411 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2413 resultStr
.setTo("EUR");
2414 if (resultStr
!= tempStr
) {
2415 errcheckln(status
, "FAIL: didn't return EUR for eo_AD - %s", u_errorName(status
));
2417 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2419 resultStr
.setTo("ESP");
2420 if (resultStr
!= tempStr
) {
2421 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2423 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2425 resultStr
.setTo("FRF");
2426 if (resultStr
!= tempStr
) {
2427 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2429 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 4, TMP
, 4, &status
);
2431 resultStr
.setTo("ADP");
2432 if (resultStr
!= tempStr
) {
2433 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2436 date
= (UDate
)0.0; // year 1970
2437 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2440 errcheckln(status
, "FAIL: didn't return 3 for eo_AD - %s", u_errorName(status
));
2442 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2444 resultStr
.setTo("ESP");
2445 if (resultStr
!= tempStr
) {
2446 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2448 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2450 resultStr
.setTo("FRF");
2451 if (resultStr
!= tempStr
) {
2452 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2454 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2456 resultStr
.setTo("ADP");
2457 if (resultStr
!= tempStr
) {
2458 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2461 date
= (UDate
)-630720000000.0; // year 1950
2462 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2465 errcheckln(status
, "FAIL: didn't return 2 for eo_AD - %s", u_errorName(status
));
2467 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2469 resultStr
.setTo("ESP");
2470 if (resultStr
!= tempStr
) {
2471 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2473 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2475 resultStr
.setTo("ADP");
2476 if (resultStr
!= tempStr
) {
2477 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2480 date
= (UDate
)-2207520000000.0; // year 1900
2481 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2484 errcheckln(status
, "FAIL: didn't return 1 for eo_AD - %s", u_errorName(status
));
2486 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2488 resultStr
.setTo("ESP");
2489 if (resultStr
!= tempStr
) {
2490 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2493 // Locale UA has gap between years 1994 - 1996
2494 date
= (UDate
)788400000000.0;
2495 index
= ucurr_countCurrencies("eo_UA", date
, &status
);
2498 errcheckln(status
, "FAIL: didn't return 0 for eo_UA - %s", u_errorName(status
));
2500 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, index
, TMP
, 4, &status
);
2502 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2504 status
= U_ZERO_ERROR
;
2506 // Test index bounds
2507 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 100, TMP
, 4, &status
);
2509 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2511 status
= U_ZERO_ERROR
;
2513 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 0, TMP
, 4, &status
);
2515 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2517 status
= U_ZERO_ERROR
;
2519 // Test for bogus locale
2520 index
= ucurr_countCurrencies("eo_QQ", date
, &status
);
2523 errcheckln(status
, "FAIL: didn't return 0 for eo_QQ - %s", u_errorName(status
));
2525 status
= U_ZERO_ERROR
;
2526 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 1, TMP
, 4, &status
);
2528 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2530 status
= U_ZERO_ERROR
;
2531 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 0, TMP
, 4, &status
);
2533 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2535 status
= U_ZERO_ERROR
;
2537 // Cycle through histrocial currencies
2538 date
= (UDate
)977616000000.0; // 2001 - one currency
2539 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2542 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2544 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2546 resultStr
.setTo("AOA");
2547 if (resultStr
!= tempStr
) {
2548 errcheckln(status
, "FAIL: didn't return AOA for eo_AO - %s", u_errorName(status
));
2551 date
= (UDate
)819936000000.0; // 1996 - 2 currencies
2552 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2555 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2557 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2559 resultStr
.setTo("AOR");
2560 if (resultStr
!= tempStr
) {
2561 errcheckln(status
, "FAIL: didn't return AOR for eo_AO - %s", u_errorName(status
));
2563 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2565 resultStr
.setTo("AON");
2566 if (resultStr
!= tempStr
) {
2567 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2570 date
= (UDate
)662256000000.0; // 1991 - 2 currencies
2571 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2574 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2576 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2578 resultStr
.setTo("AON");
2579 if (resultStr
!= tempStr
) {
2580 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2582 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2584 resultStr
.setTo("AOK");
2585 if (resultStr
!= tempStr
) {
2586 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2589 date
= (UDate
)315360000000.0; // 1980 - one currency
2590 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2593 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2595 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2597 resultStr
.setTo("AOK");
2598 if (resultStr
!= tempStr
) {
2599 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2602 date
= (UDate
)0.0; // 1970 - no currencies
2603 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2606 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2608 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2610 errcheckln(status
, "FAIL: eo_AO didn't return NULL - %s", u_errorName(status
));
2612 status
= U_ZERO_ERROR
;
2614 // Test with currency keyword override
2615 date
= (UDate
)977616000000.0; // 2001 - two currencies
2616 index
= ucurr_countCurrencies("eo_DE@currency=DEM", date
, &status
);
2619 errcheckln(status
, "FAIL: didn't return 2 for eo_DE@currency=DEM - %s", u_errorName(status
));
2621 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 1, TMP
, 4, &status
);
2623 resultStr
.setTo("EUR");
2624 if (resultStr
!= tempStr
) {
2625 errcheckln(status
, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s", u_errorName(status
));
2627 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 2, TMP
, 4, &status
);
2629 resultStr
.setTo("DEM");
2630 if (resultStr
!= tempStr
) {
2631 errcheckln(status
, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s", u_errorName(status
));
2634 // Test Euro Support
2635 status
= U_ZERO_ERROR
; // reset
2636 date
= uprv_getUTCtime();
2639 ucurr_forLocaleAndDate("en_US", date
, 1, USD
, 4, &status
);
2642 ucurr_forLocaleAndDate("ja_JP", date
, 1, YEN
, 4, &status
);
2644 ucurr_forLocaleAndDate("en_US", date
, 1, TMP
, 4, &status
);
2645 if (u_strcmp(USD
, TMP
) != 0) {
2646 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
2648 ucurr_forLocaleAndDate("en_US_PREEURO", date
, 1, TMP
, 4, &status
);
2649 if (u_strcmp(USD
, TMP
) != 0) {
2650 errcheckln(status
, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status
));
2652 ucurr_forLocaleAndDate("en_US_Q", date
, 1, TMP
, 4, &status
);
2653 if (u_strcmp(USD
, TMP
) != 0) {
2654 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
2656 status
= U_ZERO_ERROR
; // reset
2660 void LocaleTest::TestGetVariantWithKeywords(void)
2662 Locale
l("en_US_VALLEY@foo=value");
2663 const char *variant
= l
.getVariant();
2665 test_assert(strcmp("VALLEY", variant
) == 0);
2667 UErrorCode status
= U_ZERO_ERROR
;
2669 int32_t len
= l
.getKeywordValue("foo", buffer
, 50, status
);
2671 test_assert(strcmp("value", buffer
) == 0);
2674 void LocaleTest::TestIsRightToLeft() {
2675 assertFalse("root LTR", Locale::getRoot().isRightToLeft());
2676 assertFalse("zh LTR", Locale::getChinese().isRightToLeft());
2677 assertTrue("ar RTL", Locale("ar").isRightToLeft());
2678 assertTrue("und-EG RTL", Locale("und-EG").isRightToLeft(), FALSE
, TRUE
);
2679 assertFalse("fa-Cyrl LTR", Locale("fa-Cyrl").isRightToLeft());
2680 assertTrue("en-Hebr RTL", Locale("en-Hebr").isRightToLeft());
2681 assertTrue("ckb RTL", Locale("ckb").isRightToLeft(), FALSE
, TRUE
); // Sorani Kurdish
2682 assertFalse("fil LTR", Locale("fil").isRightToLeft());
2683 assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft());
2686 void LocaleTest::TestBug11421() {
2687 Locale::getDefault().getBaseName();
2689 const Locale
*localeList
= Locale::getAvailableLocales(numLocales
);
2690 for (int localeIndex
= 0; localeIndex
< numLocales
; localeIndex
++) {
2691 const Locale
&loc
= localeList
[localeIndex
];
2692 if (strncmp(loc
.getName(), loc
.getBaseName(), strlen(loc
.getBaseName()))) {
2693 errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"",
2694 __FILE__
, __LINE__
, loc
.getName(), loc
.getBaseName());