1 /********************************************************************
3 * Copyright (c) 1997-2006, 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"
17 const char* rawData
[33][8] = {
20 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
22 { "", "", "", "", "", "", "", "Hans" },
24 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" },
26 { "", "", "", "", "NY", "", "", "" },
28 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" },
30 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" },
32 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" },
34 { "409", "40c", "403", "408", "814", "10", "0", "804" },
36 // display langage (English)
37 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" },
38 // display script (English)
39 { "", "", "", "", "", "", "", "Simplified Han" },
40 // display country (English)
41 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China" },
42 // display variant (English)
43 { "", "", "", "", "NY", "", "", ""},
44 // display name (English)
45 // Updated no_NO_NY English display name for new pattern-based algorithm
46 // (part of Euro support).
47 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplified Han, China)" },
49 // display langage (French)
50 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
51 // display script (French)
52 { "", "", "", "", "", "", "", "id\\u00E9ogrammes han (variante simplifi\\u00E9e)" },
53 // display country (French)
54 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine" },
55 // display variant (French)
56 { "", "", "", "", "NY", "", "", "" },
57 // display name (French)
58 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
59 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois (id\\u00E9ogrammes han (variante simplifi\\u00E9e), Chine)" }, // STILL not right
62 /* display language (Catalan) */
63 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E9s" },
64 /* display script (Catalan) */
65 { "", "", "", "", "", "", "", "Hans" },
66 /* display country (Catalan) */
67 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina" },
68 /* display variant (Catalan) */
69 { "", "", "", "", "NY", "", "" },
70 /* display name (Catalan) */
71 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E9s (Hans, Xina)" },
73 // display langage (Greek)[actual values listed below]
74 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
75 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
76 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
77 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
78 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
79 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
81 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
83 // display script (Greek)
84 { "", "", "", "", "", "", "", "Hans" },
85 // display country (Greek)[actual values listed below]
86 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
87 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
88 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
89 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
90 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
93 "\\u039A\\u03AF\\u03BD\\u03B1"
95 // display variant (Greek)
96 { "", "", "", "", "NY", "", "" },
97 // display name (Greek)[actual values listed below]
98 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
99 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
100 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
101 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
102 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
103 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
105 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (Hans, \\u039A\\u03AF\\u03BD\\u03B1)"
108 // display langage (<root>)
109 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" },
110 // display script (<root>)
111 { "", "", "", "", "", "", "", ""},
112 // display country (<root>)
113 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" },
114 // display variant (<root>)
115 { "", "", "", "", "Nynorsk", "", "", ""},
116 // display name (<root>)
117 //{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" },
118 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
124 test_assert( Test (should be TRUE) )
129 the macro is ugly but makes the tests pretty.
132 #define test_assert(test) \
135 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \
137 logln("PASS: asserted " #test); \
142 test_assert_print( Test (should be TRUE), printable )
145 test_assert(i==3, toString(i));
147 the macro is ugly but makes the tests pretty.
150 #define test_assert_print(test,print) \
153 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \
155 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \
159 #define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); }
161 LocaleTest::LocaleTest()
167 LocaleTest::~LocaleTest()
169 if (dataTable
!= 0) {
170 for (int32_t i
= 0; i
< 33; i
++) {
171 delete []dataTable
[i
];
178 void LocaleTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
181 TESTCASE(0, TestBasicGetters
);
182 TESTCASE(1, TestSimpleResourceInfo
);
183 TESTCASE(2, TestDisplayNames
);
184 TESTCASE(3, TestSimpleObjectStuff
);
185 TESTCASE(4, TestPOSIXParsing
);
186 TESTCASE(5, TestGetAvailableLocales
);
187 TESTCASE(6, TestDataDirectory
);
188 TESTCASE(7, TestISO3Fallback
);
189 TESTCASE(8, TestGetLangsAndCountries
);
190 TESTCASE(9, TestSimpleDisplayNames
);
191 TESTCASE(10, TestUninstalledISO3Names
);
192 TESTCASE(11, TestAtypicalLocales
);
193 #if !UCONFIG_NO_FORMATTING
194 TESTCASE(12, TestThaiCurrencyFormat
);
195 TESTCASE(13, TestEuroSupport
);
197 TESTCASE(14, TestToString
);
198 #if !UCONFIG_NO_FORMATTING
199 TESTCASE(15, Test4139940
);
200 TESTCASE(16, Test4143951
);
202 TESTCASE(17, Test4147315
);
203 TESTCASE(18, Test4147317
);
204 TESTCASE(19, Test4147552
);
205 TESTCASE(20, TestVariantParsing
);
206 #if !UCONFIG_NO_FORMATTING
207 TESTCASE(21, Test4105828
);
209 TESTCASE(22, TestSetIsBogus
);
210 TESTCASE(23, TestParallelAPIValues
);
211 TESTCASE(24, TestKeywordVariants
);
212 TESTCASE(25, TestKeywordVariantParsing
);
213 TESTCASE(26, TestGetBaseName
);
214 TESTCASE(27, TestGetLocale
);
215 TESTCASE(28, TestVariantWithOutCountry
);
216 TESTCASE(29, TestCanonicalization
);
218 // keep the last index in sync with the condition in default:
221 if (index
<= 28) { // keep this in sync with the last index!
222 name
= "(test omitted by !UCONFIG_NO_FORMATTING)";
226 break; //needed to end loop
230 void LocaleTest::TestBasicGetters() {
234 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
235 Locale
testLocale("");
236 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
237 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
240 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
242 logln("Testing " + (UnicodeString
)testLocale
.getName() + "...");
244 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
245 errln(" Language code mismatch: " + temp
+ " versus "
246 + dataTable
[LANG
][i
]);
247 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
248 errln(" Script code mismatch: " + temp
+ " versus "
249 + dataTable
[SCRIPT
][i
]);
250 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
251 errln(" Country code mismatch: " + temp
+ " versus "
252 + dataTable
[CTRY
][i
]);
253 if ( (temp
=testLocale
.getVariant()) != (dataTable
[VAR
][i
]))
254 errln(" Variant code mismatch: " + temp
+ " versus "
255 + dataTable
[VAR
][i
]);
256 if ( (temp
=testLocale
.getName()) != (dataTable
[NAME
][i
]))
257 errln(" Locale name mismatch: " + temp
+ " versus "
258 + dataTable
[NAME
][i
]);
261 logln("Same thing without variant codes...");
262 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
263 Locale
testLocale("");
264 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
265 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
]);
268 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
]);
270 logln("Testing " + (temp
=testLocale
.getName()) + "...");
272 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
273 errln("Language code mismatch: " + temp
+ " versus "
274 + dataTable
[LANG
][i
]);
275 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
276 errln("Script code mismatch: " + temp
+ " versus "
277 + dataTable
[SCRIPT
][i
]);
278 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
279 errln("Country code mismatch: " + temp
+ " versus "
280 + dataTable
[CTRY
][i
]);
281 if (testLocale
.getVariant()[0] != 0)
282 errln("Variant code mismatch: something versus \"\"");
285 logln("Testing long language names and getters");
286 Locale test8
= Locale::createFromName("x-klingon-latn-zx.utf32be@special");
288 temp
= test8
.getLanguage();
289 if (temp
!= UnicodeString("x-klingon") )
290 errln("Language code mismatch: " + temp
+ " versus \"x-klingon\"");
292 temp
= test8
.getScript();
293 if (temp
!= UnicodeString("Latn") )
294 errln("Script code mismatch: " + temp
+ " versus \"Latn\"");
296 temp
= test8
.getCountry();
297 if (temp
!= UnicodeString("ZX") )
298 errln("Country code mismatch: " + temp
+ " versus \"ZX\"");
300 temp
= test8
.getVariant();
301 //if (temp != UnicodeString("SPECIAL") )
302 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\"");
303 // As of 3.0, the "@special" will *not* be parsed by uloc_getName()
304 if (temp
!= UnicodeString("") )
305 errln("Variant code mismatch: " + temp
+ " versus \"\"");
307 if (Locale::getDefault() != Locale::createFromName(NULL
))
308 errln("Locale::getDefault() == Locale::createFromName(NULL)");
311 // NOTE: There used to be a special test for locale names that had language or
312 // country codes that were longer than two letters. The new version of Locale
313 // doesn't support anything that isn't an officially recognized language or
314 // country code, so we no longer support this feature.
316 Locale
bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code too long
317 if(!bogusLang
.isBogus()) {
318 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE");
321 bogusLang
=Locale("eo");
322 if( bogusLang
.isBogus() ||
323 strcmp(bogusLang
.getLanguage(), "eo")!=0 ||
324 *bogusLang
.getCountry()!=0 ||
325 *bogusLang
.getVariant()!=0 ||
326 strcmp(bogusLang
.getName(), "eo")!=0
328 errln("assignment to bogus Locale does not unbogus it or sets bad data");
331 Locale
a("eo_DE@currency=DEM");
332 Locale
*pb
=a
.clone();
333 if(pb
==&a
|| *pb
!=a
) {
334 errln("Locale.clone() failed");
339 void LocaleTest::TestParallelAPIValues() {
340 logln("Test synchronization between C and C++ API");
341 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE
) != 0) {
342 errln("Differences for ULOC_CHINESE Locale");
344 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH
) != 0) {
345 errln("Differences for ULOC_ENGLISH Locale");
347 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH
) != 0) {
348 errln("Differences for ULOC_FRENCH Locale");
350 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN
) != 0) {
351 errln("Differences for ULOC_GERMAN Locale");
353 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN
) != 0) {
354 errln("Differences for ULOC_ITALIAN Locale");
356 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE
) != 0) {
357 errln("Differences for ULOC_JAPANESE Locale");
359 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN
) != 0) {
360 errln("Differences for ULOC_KOREAN Locale");
362 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE
) != 0) {
363 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale");
365 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINESE
) != 0) {
366 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale");
370 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA
) != 0) {
371 errln("Differences for ULOC_CANADA Locale");
373 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH
) != 0) {
374 errln("Differences for ULOC_CANADA_FRENCH Locale");
376 if (strcmp(Locale::getChina().getName(), ULOC_CHINA
) != 0) {
377 errln("Differences for ULOC_CHINA Locale");
379 if (strcmp(Locale::getPRC().getName(), ULOC_PRC
) != 0) {
380 errln("Differences for ULOC_PRC Locale");
382 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE
) != 0) {
383 errln("Differences for ULOC_FRANCE Locale");
385 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY
) != 0) {
386 errln("Differences for ULOC_GERMANY Locale");
388 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY
) != 0) {
389 errln("Differences for ULOC_ITALY Locale");
391 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN
) != 0) {
392 errln("Differences for ULOC_JAPAN Locale");
394 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA
) != 0) {
395 errln("Differences for ULOC_KOREA Locale");
397 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN
) != 0) {
398 errln("Differences for ULOC_TAIWAN Locale");
400 if (strcmp(Locale::getUK().getName(), ULOC_UK
) != 0) {
401 errln("Differences for ULOC_UK Locale");
403 if (strcmp(Locale::getUS().getName(), ULOC_US
) != 0) {
404 errln("Differences for ULOC_US Locale");
409 void LocaleTest::TestSimpleResourceInfo() {
412 UErrorCode err
= U_ZERO_ERROR
;
415 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
416 Locale
testLocale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
417 logln("Testing " + (temp
=testLocale
.getName()) + "...");
419 if ( (temp
=testLocale
.getISO3Language()) != (dataTable
[LANG3
][i
]))
420 errln(" ISO-3 language code mismatch: " + temp
421 + " versus " + dataTable
[LANG3
][i
]);
422 if ( (temp
=testLocale
.getISO3Country()) != (dataTable
[CTRY3
][i
]))
423 errln(" ISO-3 country code mismatch: " + temp
424 + " versus " + dataTable
[CTRY3
][i
]);
426 sprintf(temp2
, "%x", (int)testLocale
.getLCID());
427 if (UnicodeString(temp2
) != dataTable
[LCID
][i
])
428 errln((UnicodeString
)" LCID mismatch: " + temp2
+ " versus "
429 + dataTable
[LCID
][i
]);
433 errln((UnicodeString
)"Some error on number " + i
+ u_errorName(err
));
439 if(strcmp(locale
.getName(), "en") != 0||
440 strcmp(locale
.getLanguage(), "en") != 0) {
441 errln("construction of Locale(en) failed\n");
448 * Jitterbug 2439 -- markus 20030425
450 * The lookup of display names must not fall back through the default
451 * locale because that yields useless results.
454 LocaleTest::TestDisplayNames()
456 Locale
english("en", "US");
457 Locale
french("fr", "FR");
458 Locale
croatian("ca", "ES");
459 Locale
greek("el", "GR");
461 logln(" In locale = en_US...");
462 doTestDisplayNames(english
, DLANG_EN
);
463 logln(" In locale = fr_FR...");
464 doTestDisplayNames(french
, DLANG_FR
);
465 logln(" In locale = ca_ES...");
466 doTestDisplayNames(croatian
, DLANG_CA
);
467 logln(" In locale = el_GR...");
468 doTestDisplayNames(greek
, DLANG_EL
);
470 /* test that the default locale has a display name for its own language */
472 Locale().getDisplayLanguage(Locale(), s
);
473 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
474 /* check <=3 to reject getting the language code as a display name */
475 errln("unable to get a display string for the language of the default locale\n");
479 * API coverage improvements: call
480 * Locale::getDisplayLanguage(UnicodeString &) and
481 * Locale::getDisplayCountry(UnicodeString &)
484 Locale().getDisplayLanguage(s
);
485 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
486 errln("unable to get a display string for the language of the default locale [2]\n");
489 french
.getDisplayCountry(s
);
491 errln("unable to get any default-locale display string for the country of fr_FR\n");
494 Locale("zh", "Hant").getDisplayScript(s
);
496 errln("unable to get any default-locale display string for the country of zh_Hant\n");
500 void LocaleTest::TestSimpleObjectStuff() {
501 Locale
test1("aa", "AA");
502 Locale
test2("aa", "AA");
504 Locale
test4("zz", "ZZ");
505 Locale
test5("aa", "AA", "");
506 Locale
test6("aa", "AA", "ANTARES");
507 Locale
test7("aa", "AA", "JUPITER");
508 Locale test8
= Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that
510 // now list them all for debugging usage.
511 test_dumpLocale(test1
);
512 test_dumpLocale(test2
);
513 test_dumpLocale(test3
);
514 test_dumpLocale(test4
);
515 test_dumpLocale(test5
);
516 test_dumpLocale(test6
);
517 test_dumpLocale(test7
);
518 test_dumpLocale(test8
);
520 // Make sure things compare to themselves!
521 test_assert(test1
== test1
);
522 test_assert(test2
== test2
);
523 test_assert(test3
== test3
);
524 test_assert(test4
== test4
);
525 test_assert(test5
== test5
);
526 test_assert(test6
== test6
);
527 test_assert(test7
== test7
);
528 test_assert(test8
== test8
);
530 // make sure things are not equal to themselves.
531 test_assert(!(test1
!= test1
));
532 test_assert(!(test2
!= test2
));
533 test_assert(!(test3
!= test3
));
534 test_assert(!(test4
!= test4
));
535 test_assert(!(test5
!= test5
));
536 test_assert(!(test6
!= test6
));
537 test_assert(!(test7
!= test7
));
538 test_assert(!(test8
!= test8
));
540 // make sure things that are equal to each other don't show up as unequal.
541 test_assert(!(test1
!= test2
));
542 test_assert(!(test2
!= test1
));
543 test_assert(!(test1
!= test3
));
544 test_assert(!(test2
!= test3
));
545 test_assert(test5
== test1
);
546 test_assert(test6
!= test2
);
547 test_assert(test6
!= test5
);
549 test_assert(test6
!= test7
);
551 // test for things that shouldn't compare equal.
552 test_assert(!(test1
== test4
));
553 test_assert(!(test2
== test4
));
554 test_assert(!(test3
== test4
));
556 test_assert(test7
== test8
);
558 // test for hash codes to be the same.
559 int32_t hash1
= test1
.hashCode();
560 int32_t hash2
= test2
.hashCode();
561 int32_t hash3
= test3
.hashCode();
563 test_assert(hash1
== hash2
);
564 test_assert(hash1
== hash3
);
565 test_assert(hash2
== hash3
);
567 // test that the assignment operator works.
569 logln("test4=test1;");
570 test_dumpLocale(test4
);
571 test_assert(test4
== test4
);
573 test_assert(!(test1
!= test4
));
574 test_assert(!(test2
!= test4
));
575 test_assert(!(test3
!= test4
));
576 test_assert(test1
== test4
);
577 test_assert(test4
== test1
);
579 // test assignments with a variant
580 logln("test7 = test6");
582 test_dumpLocale(test7
);
583 test_assert(test7
== test7
);
584 test_assert(test7
== test6
);
585 test_assert(test7
!= test5
);
587 logln("test6 = test1");
589 test_dumpLocale(test6
);
590 test_assert(test6
!= test7
);
591 test_assert(test6
== test1
);
592 test_assert(test6
== test6
);
595 // A class which exposes constructors that are implemented in terms of the POSIX parsing code.
596 class POSIXLocale
: public Locale
599 POSIXLocale(const UnicodeString
& l
)
603 ch
= new char[l
.length() + 1];
604 ch
[l
.extract(0, 0x7fffffff, ch
, "")] = 0;
608 POSIXLocale(const char *l
)
615 void LocaleTest::TestPOSIXParsing()
617 POSIXLocale
test1("ab_AB");
618 POSIXLocale
test2(UnicodeString("ab_AB"));
619 Locale
test3("ab","AB");
621 POSIXLocale
test4("ab_AB_Antares");
622 POSIXLocale
test5(UnicodeString("ab_AB_Antares"));
623 Locale
test6("ab", "AB", "Antares");
625 test_dumpLocale(test1
);
626 test_dumpLocale(test2
);
627 test_dumpLocale(test3
);
628 test_dumpLocale(test4
);
629 test_dumpLocale(test5
);
630 test_dumpLocale(test6
);
632 test_assert(test1
== test1
);
634 test_assert(test1
== test2
);
635 test_assert(test2
== test3
);
636 test_assert(test3
== test1
);
638 test_assert(test4
== test5
);
639 test_assert(test5
== test6
);
640 test_assert(test6
== test4
);
642 test_assert(test1
!= test4
);
643 test_assert(test5
!= test3
);
644 test_assert(test5
!= test2
);
646 int32_t hash1
= test1
.hashCode();
647 int32_t hash2
= test2
.hashCode();
648 int32_t hash3
= test3
.hashCode();
650 test_assert(hash1
== hash2
);
651 test_assert(hash2
== hash3
);
652 test_assert(hash3
== hash1
);
655 void LocaleTest::TestGetAvailableLocales()
657 int32_t locCount
= 0;
658 const Locale
* locList
= Locale::getAvailableLocales(locCount
);
661 errln("getAvailableLocales() returned an empty list!");
663 logln(UnicodeString("Number of locales returned = ") + locCount
);
665 for(int32_t i
= 0; i
< locCount
; ++i
)
666 logln(locList
[i
].getName());
668 // I have no idea how to test this function...
671 // This test isn't applicable anymore - getISO3Language is
672 // independent of the data directory
673 void LocaleTest::TestDataDirectory()
676 char oldDirectory[80];
678 UErrorCode err = U_ZERO_ERROR;
679 UnicodeString testValue;
681 temp = Locale::getDataDirectory();
682 strcpy(oldDirectory, temp);
683 logln(UnicodeString("oldDirectory = ") + oldDirectory);
685 Locale test(Locale::US);
686 test.getISO3Language(testValue);
687 logln("first fetch of language retrieved " + testValue);
688 if (testValue != "eng")
689 errln("Initial check of ISO3 language failed: expected \"eng\", got \"" + testValue + "\"");
693 path=IntlTest::getTestDirectory();
694 Locale::setDataDirectory( path );
697 test.getISO3Language(testValue);
698 logln("second fetch of language retrieved " + testValue);
699 if (testValue != "xxx")
700 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue + "\"");
702 Locale::setDataDirectory(oldDirectory);
703 test.getISO3Language(testValue);
704 logln("third fetch of language retrieved " + testValue);
705 if (testValue != "eng")
706 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testValue + "\"");
710 //===========================================================
712 void LocaleTest::doTestDisplayNames(Locale
& displayLocale
, int32_t compareIndex
) {
715 for (int32_t i
= 0; i
<= MAX_LOCALES
; i
++) {
716 Locale
testLocale("");
717 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
718 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
721 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
723 logln(" Testing " + (temp
=testLocale
.getName()) + "...");
725 UnicodeString testLang
;
726 UnicodeString testScript
;
727 UnicodeString testCtry
;
728 UnicodeString testVar
;
729 UnicodeString testName
;
731 testLocale
.getDisplayLanguage(displayLocale
, testLang
);
732 testLocale
.getDisplayScript(displayLocale
, testScript
);
733 testLocale
.getDisplayCountry(displayLocale
, testCtry
);
734 testLocale
.getDisplayVariant(displayLocale
, testVar
);
735 testLocale
.getDisplayName(displayLocale
, testName
);
737 UnicodeString expectedLang
;
738 UnicodeString expectedScript
;
739 UnicodeString expectedCtry
;
740 UnicodeString expectedVar
;
741 UnicodeString expectedName
;
743 expectedLang
= dataTable
[compareIndex
][i
];
744 if (expectedLang
.length() == 0)
745 expectedLang
= dataTable
[DLANG_EN
][i
];
747 expectedScript
= dataTable
[compareIndex
+ 1][i
];
748 if (expectedScript
.length() == 0)
749 expectedScript
= dataTable
[DSCRIPT_EN
][i
];
751 expectedCtry
= dataTable
[compareIndex
+ 2][i
];
752 if (expectedCtry
.length() == 0)
753 expectedCtry
= dataTable
[DCTRY_EN
][i
];
755 expectedVar
= dataTable
[compareIndex
+ 3][i
];
756 if (expectedVar
.length() == 0)
757 expectedVar
= dataTable
[DVAR_EN
][i
];
759 expectedName
= dataTable
[compareIndex
+ 4][i
];
760 if (expectedName
.length() == 0)
761 expectedName
= dataTable
[DNAME_EN
][i
];
763 if (testLang
!= expectedLang
)
764 errln("Display language (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testLang
+ " expected " + expectedLang
);
765 if (testScript
!= expectedScript
)
766 errln("Display script (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testScript
+ " expected " + expectedScript
);
767 if (testCtry
!= expectedCtry
)
768 errln("Display country (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testCtry
+ " expected " + expectedCtry
);
769 if (testVar
!= expectedVar
)
770 errln("Display variant (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testVar
+ " expected " + expectedVar
);
771 if (testName
!= expectedName
)
772 errln("Display name (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testName
+ " expected " + expectedName
);
776 //---------------------------------------------------
777 // table of valid data
778 //---------------------------------------------------
782 void LocaleTest::setUpDataTable()
784 if (dataTable
== 0) {
785 dataTable
= new UnicodeString
*[33];
787 for (int32_t i
= 0; i
< 33; i
++) {
788 dataTable
[i
] = new UnicodeString
[8];
789 for (int32_t j
= 0; j
< 8; j
++) {
790 dataTable
[i
][j
] = CharsToUnicodeString(rawData
[i
][j
]);
796 // ====================
800 * @bug 4011756 4011380
803 LocaleTest::TestISO3Fallback()
805 Locale
test("xx", "YY");
809 result
= test
.getISO3Language();
811 // Conform to C API usage
813 if (!result
|| (result
[0] != 0))
814 errln("getISO3Language() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
816 result
= test
.getISO3Country();
818 if (!result
|| (result
[0] != 0))
819 errln("getISO3Country() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
823 * @bug 4106155 4118587
826 LocaleTest::TestGetLangsAndCountries()
828 // It didn't seem right to just do an exhaustive test of everything here, so I check
829 // for the following things:
830 // 1) Does each list have the right total number of entries?
831 // 2) Does each list contain certain language and country codes we think are important
832 // (the G7 countries, plus a couple others)?
833 // 3) Does each list have every entry formatted correctly? (i.e., two characters,
834 // all lower case for the language codes, all upper case for the country codes)
835 // 4) Is each list in sorted order?
836 int32_t testCount
= 0;
837 const char * const * test
= Locale::getISOLanguages();
838 const char spotCheck1
[ ][4] = { "en", "es", "fr", "de", "it",
839 "ja", "ko", "zh", "th", "he",
840 "id", "iu", "ug", "yi", "za" };
844 for(testCount
= 0;test
[testCount
];testCount
++)
847 /* TODO: Change this test to be more like the cloctst version? */
848 if (testCount
!= 485)
849 errln("Expected getISOLanguages() to return 481 languages; it returned %d", testCount
);
851 for (i
= 0; i
< 15; i
++) {
853 for (j
= 0; j
< testCount
; j
++)
854 if (uprv_strcmp(test
[j
],spotCheck1
[i
])== 0)
856 if (j
== testCount
|| (uprv_strcmp(test
[j
],spotCheck1
[i
])!=0))
857 errln("Couldn't find " + (UnicodeString
)spotCheck1
[i
] + " in language list.");
860 for (i
= 0; i
< testCount
; i
++) {
861 UnicodeString
testee(test
[i
],"");
862 UnicodeString
lc(test
[i
],"");
863 if (testee
!= lc
.toLower())
864 errln(lc
+ " is not all lower case.");
865 if ( (testee
.length() != 2) && (testee
.length() != 3))
866 errln(testee
+ " is not two or three characters long.");
867 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
868 errln(testee
+ " appears in an out-of-order position in the list.");
871 test
= Locale::getISOCountries();
872 UnicodeString spotCheck2
[] = { "US", "CA", "GB", "FR", "DE",
873 "IT", "JP", "KR", "CN", "TW",
875 int32_t spot2Len
= 11;
876 for(testCount
=0;test
[testCount
];testCount
++)
879 if (testCount
!= 244){
880 errln("Expected getISOCountries to return 240 countries; it returned %d", testCount
);
882 for (i
= 0; i
< spot2Len
; i
++) {
884 for (j
= 0; j
< testCount
; j
++)
886 UnicodeString
testee(test
[j
],"");
888 if (testee
== spotCheck2
[i
])
891 UnicodeString
testee(test
[j
],"");
892 if (j
== testCount
|| testee
!= spotCheck2
[i
])
893 errln("Couldn't find " + spotCheck2
[i
] + " in country list.");
896 for (i
= 0; i
< testCount
; i
++) {
897 UnicodeString
testee(test
[i
],"");
898 UnicodeString
uc(test
[i
],"");
899 if (testee
!= uc
.toUpper())
900 errln(testee
+ " is not all upper case.");
901 if (testee
.length() != 2)
902 errln(testee
+ " is not two characters long.");
903 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
904 errln(testee
+ " appears in an out-of-order position in the list.");
912 LocaleTest::TestSimpleDisplayNames()
914 // This test is different from TestDisplayNames because TestDisplayNames checks
915 // fallback behavior, combination of language and country names to form locale
916 // names, and other stuff like that. This test just checks specific language
917 // and country codes to make sure we have the correct names for them.
918 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
919 UnicodeString languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish",
922 for (int32_t i
= 0; i
< 6; i
++) {
924 Locale
l(languageCodes
[i
], "", "");
925 l
.getDisplayLanguage(Locale::getUS(), test
);
926 if (test
!= languageNames
[i
])
927 errln("Got wrong display name for " + UnicodeString(languageCodes
[i
]) + ": Expected \"" +
928 languageNames
[i
] + "\", got \"" + test
+ "\".");
936 LocaleTest::TestUninstalledISO3Names()
938 // This test checks to make sure getISO3Language and getISO3Country work right
939 // even for locales that are not installed.
940 const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
942 const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
943 "ssw", "twi", "zul" };
947 for (i
= 0; i
< 8; i
++) {
948 UErrorCode err
= U_ZERO_ERROR
;
951 Locale
l(iso2Languages
[i
], "", "");
952 test
= l
.getISO3Language();
953 if((test
!= iso3Languages
[i
]) || U_FAILURE(err
))
954 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages
[i
]) + ": Expected \"" +
955 iso3Languages
[i
] + "\", got \"" + test
+ "\"." + UnicodeString(u_errorName(err
)));
958 char iso2Countries
[][4] = { "AF", "BW", "KZ", "MO", "MN",
960 char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
961 "SLB", "TCA", "ZWE" };
963 for (i
= 0; i
< 8; i
++) {
964 UErrorCode err
= U_ZERO_ERROR
;
965 Locale
l("", iso2Countries
[i
], "");
966 UnicodeString
test(l
.getISO3Country(), "");
967 if (test
!= iso3Countries
[i
])
968 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries
[i
]) + ": Expected \"" +
969 UnicodeString(iso3Countries
[i
]) + "\", got \"" + test
+ "\"." + u_errorName(err
));
975 * I could not reproduce this bug. I'm pretty convinced it was fixed with the
976 * big locale-data reorg of 10/28/97. The lookup logic for language and country
977 * display names was also changed at that time in that check-in. --rtg 3/20/98
980 LocaleTest::TestAtypicalLocales()
982 Locale localesToTest
[] = { Locale("de", "CA"),
992 UnicodeString englishDisplayNames
[] = { "German (Canada)",
993 "Japanese (South Africa)",
999 "Dominican Republic",
1001 UnicodeString frenchDisplayNames
[]= { "allemand (Canada)",
1002 "japonais (Afrique du Sud)",
1005 "espagnol (Allemagne)",
1007 CharsToUnicodeString("Su\\u00E8de"),
1008 CharsToUnicodeString("Dominicaine, r\\u00E9publique"),
1010 UnicodeString spanishDisplayNames
[] = {
1011 CharsToUnicodeString("alem\\u00E1n (Canad\\u00E1)"),
1012 CharsToUnicodeString("japon\\u00E9s (Sud\\u00E1frica)"),
1013 CharsToUnicodeString("ruso (M\\u00E9xico)"),
1014 CharsToUnicodeString("ingl\\u00E9s (Francia)"),
1015 CharsToUnicodeString("espa\\u00F1ol (Alemania)"),
1018 CharsToUnicodeString("Rep\\u00FAblica Dominicana"),
1019 CharsToUnicodeString("B\\u00E9lgica") };
1020 // De-Anglicizing root required the change from
1021 // English display names to ISO Codes - ram 2003/09/26
1022 UnicodeString invDisplayNames
[] = { "German (Canada)",
1023 "Japanese (South Africa)",
1026 "Spanish (Germany)",
1029 "Dominican Republic",
1033 UErrorCode status
= U_ZERO_ERROR
;
1035 Locale::setDefault(Locale::getUS(), status
);
1036 for (i
= 0; i
< 9; ++i
) {
1038 localesToTest
[i
].getDisplayName(Locale::getUS(), name
);
1040 if (name
!= englishDisplayNames
[i
])
1042 errln("Lookup in English failed: expected \"" + englishDisplayNames
[i
]
1043 + "\", got \"" + name
+ "\"");
1044 logln("Locale name was-> " + (name
=localesToTest
[i
].getName()));
1048 for (i
= 0; i
< 9; i
++) {
1050 localesToTest
[i
].getDisplayName(Locale("es", "ES"), name
);
1052 if (name
!= spanishDisplayNames
[i
])
1053 errln("Lookup in Spanish failed: expected \"" + spanishDisplayNames
[i
]
1054 + "\", got \"" + name
+ "\"");
1057 for (i
= 0; i
< 9; i
++) {
1059 localesToTest
[i
].getDisplayName(Locale::getFrance(), name
);
1061 if (name
!= frenchDisplayNames
[i
])
1062 errln("Lookup in French failed: expected \"" + frenchDisplayNames
[i
]
1063 + "\", got \"" + name
+ "\"");
1066 for (i
= 0; i
< 9; i
++) {
1068 localesToTest
[i
].getDisplayName(Locale("inv", "IN"), name
);
1069 logln(name
+ " Locale fallback to be, and data fallback to root");
1070 if (name
!= invDisplayNames
[i
])
1071 errln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1072 + "\", got \"" + prettify(name
) + "\"");
1073 localesToTest
[i
].getDisplayName(Locale("inv", "BD"), name
);
1074 logln(name
+ " Data fallback to root");
1075 if (name
!= invDisplayNames
[i
])
1076 errln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1077 + "\", got \"" + prettify(name
)+ "\"");
1079 Locale::setDefault(saveLocale
, status
);
1082 #if !UCONFIG_NO_FORMATTING
1086 * This would be better tested by the LocaleDataTest. Will move it when I
1087 * get the LocaleDataTest working again.
1090 LocaleTest::TestThaiCurrencyFormat()
1092 UErrorCode status
= U_ZERO_ERROR
;
1093 DecimalFormat
*thaiCurrency
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(
1094 Locale("th", "TH"), status
);
1095 UChar posPrefix
= 0x0e3f;
1098 if(U_FAILURE(status
) || !thaiCurrency
)
1100 errln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status
)));
1103 if (thaiCurrency
->getPositivePrefix(temp
) != UnicodeString(&posPrefix
, 1, 1))
1104 errln("Thai currency prefix wrong: expected 0x0e3f, got \"" +
1105 thaiCurrency
->getPositivePrefix(temp
) + "\"");
1106 if (thaiCurrency
->getPositiveSuffix(temp
) != "")
1107 errln("Thai currency suffix wrong: expected \"\", got \"" +
1108 thaiCurrency
->getPositiveSuffix(temp
) + "\"");
1110 delete thaiCurrency
;
1115 * Confirm that Euro support works. This test is pretty rudimentary; all it does
1116 * is check that any locales with the EURO variant format a number using the
1117 * Euro currency symbol.
1119 * ASSUME: All locales encode the Euro character "\u20AC".
1120 * If this is changed to use the single-character Euro symbol, this
1121 * test must be updated.
1125 LocaleTest::TestEuroSupport()
1127 UChar euro
= 0x20ac;
1128 const UnicodeString
EURO_CURRENCY(&euro
, 1, 1); // Look for this UnicodeString in formatted Euro currency
1129 const char* localeArr
[] = {
1153 const char** locales
= localeArr
;
1155 UErrorCode status
= U_ZERO_ERROR
;
1159 for (;*locales
!=NULL
;locales
++) {
1160 Locale
loc (*locales
);
1162 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(loc
, status
);
1165 if (U_FAILURE(status
)) {
1166 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales
);
1170 nf
->format(271828.182845, pos
);
1172 nf
->format(-271828.182845, neg
);
1173 if (pos
.indexOf(EURO_CURRENCY
) >= 0 &&
1174 neg
.indexOf(EURO_CURRENCY
) >= 0) {
1175 logln("Ok: " + (temp
=loc
.getName()) +
1176 ": " + pos
+ " / " + neg
);
1179 errln("Fail: " + (temp
=loc
.getName()) +
1180 " formats without " + EURO_CURRENCY
+
1181 ": " + pos
+ " / " + neg
+
1182 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***");
1188 UnicodeString
dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar
)0x00a4), resultStr
;
1190 status
= U_ZERO_ERROR
;
1192 ucurr_forLocale("en_US", tmp
, 4, &status
);
1193 resultStr
.setTo(tmp
);
1194 if (dollarStr
!= resultStr
) {
1195 errln("Fail: en_US didn't return USD");
1197 ucurr_forLocale("en_US_EURO", tmp
, 4, &status
);
1198 resultStr
.setTo(tmp
);
1199 if (euroStr
!= resultStr
) {
1200 errln("Fail: en_US_EURO didn't return EUR");
1202 ucurr_forLocale("en_GB_EURO", tmp
, 4, &status
);
1203 resultStr
.setTo(tmp
);
1204 if (euroStr
!= resultStr
) {
1205 errln("Fail: en_GB_EURO didn't return EUR");
1207 ucurr_forLocale("en_US_PREEURO", tmp
, 4, &status
);
1208 resultStr
.setTo(tmp
);
1209 if (dollarStr
!= resultStr
) {
1210 errln("Fail: en_US_PREEURO didn't fallback to en_US");
1212 ucurr_forLocale("en_US_Q", tmp
, 4, &status
);
1213 resultStr
.setTo(tmp
);
1214 if (dollarStr
!= resultStr
) {
1215 errln("Fail: en_US_Q didn't fallback to en_US");
1217 int32_t invalidLen
= ucurr_forLocale("en_QQ", tmp
, 4, &status
);
1218 if (invalidLen
|| U_SUCCESS(status
)) {
1219 errln("Fail: en_QQ didn't return NULL");
1227 * toString() doesn't work with language_VARIANT.
1230 LocaleTest::TestToString() {
1232 Locale("xx", "", ""),
1233 Locale("", "YY", ""),
1234 Locale("", "", "ZZ"),
1235 Locale("xx", "YY", ""),
1236 Locale("xx", "", "ZZ"),
1237 Locale("", "YY", "ZZ"),
1238 Locale("xx", "YY", "ZZ"),
1241 const char DATA_S
[][20] = {
1251 for (int32_t i
=0; i
< 7; ++i
) {
1253 name
= DATA
[i
].getName();
1255 if (strcmp(name
, DATA_S
[i
]) != 0)
1257 errln("Fail: Locale.getName(), got:" + UnicodeString(name
) + ", expected: " + DATA_S
[i
]);
1260 logln("Pass: Locale.getName(), got:" + UnicodeString(name
) );
1264 #if !UCONFIG_NO_FORMATTING
1268 * Couldn't reproduce this bug -- probably was fixed earlier.
1270 * ORIGINAL BUG REPORT:
1271 * -- basically, hungarian for monday shouldn't have an \u00f4
1272 * (o circumflex)in it instead it should be an o with 2 inclined
1273 * (right) lines over it..
1275 * You may wonder -- why do all this -- why not just add a line to
1276 * LocaleData? Well, I could see by inspection that the locale file had the
1277 * right character in it, so I wanted to check the rest of the pipeline -- a
1278 * very remote possibility, but I wanted to be sure. The other possibility
1279 * is that something is wrong with the font mapping subsystem, but we can't
1283 LocaleTest::Test4139940()
1285 Locale
mylocale("hu", "", "");
1286 UDate mydate
= date(98,3,13); // A Monday
1287 UErrorCode status
= U_ZERO_ERROR
;
1288 SimpleDateFormat
df_full("EEEE", mylocale
, status
);
1289 if(U_FAILURE(status
)){
1290 errln(UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: " )+ UnicodeString(u_errorName(status
)));
1294 FieldPosition
pos(FieldPosition::DONT_CARE
);
1295 df_full
.format(mydate
, str
, pos
);
1296 // Make sure that o circumflex (\u00F4) is NOT there, and
1297 // o double acute (\u0151) IS.
1300 if (str
.indexOf(oda
) < 0 || str
.indexOf(ocf
) >= 0) {
1301 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
1302 str
.indexOf(oda
), str
.indexOf(ocf
));
1303 logln(UnicodeString("String is: ") + str
);
1308 LocaleTest::date(int32_t y
, int32_t m
, int32_t d
, int32_t hr
, int32_t min
, int32_t sec
)
1310 UErrorCode status
= U_ZERO_ERROR
;
1311 Calendar
*cal
= Calendar::createInstance(status
);
1315 cal
->set(1900 + y
, m
, d
, hr
, min
, sec
); // Add 1900 to follow java.util.Date protocol
1316 UDate dt
= cal
->getTime(status
);
1317 if (U_FAILURE(status
))
1326 * Russian first day of week should be Monday. Confirmed.
1329 LocaleTest::Test4143951()
1331 UErrorCode status
= U_ZERO_ERROR
;
1332 Calendar
*cal
= Calendar::createInstance(Locale("ru", "", ""), status
);
1333 if(U_SUCCESS(status
)) {
1334 if (cal
->getFirstDayOfWeek(status
) != UCAL_MONDAY
) {
1335 errln("Fail: First day of week in Russia should be Monday");
1345 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes.
1346 * Should throw an exception for unknown locales
1349 LocaleTest::Test4147315()
1352 // Try with codes that are the wrong length but happen to match text
1353 // at a valid offset in the mapping table
1354 Locale
locale("aaa", "CCC");
1356 const char *result
= locale
.getISO3Country();
1358 // Change to conform to C api usage
1359 if((result
==NULL
)||(result
[0] != 0))
1360 errln("ERROR: getISO3Country() returns: " + UnicodeString(result
,"") +
1361 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1366 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
1367 * Should throw an exception for unknown locales
1370 LocaleTest::Test4147317()
1373 // Try with codes that are the wrong length but happen to match text
1374 // at a valid offset in the mapping table
1375 Locale
locale("aaa", "CCC");
1377 const char *result
= locale
.getISO3Language();
1379 // Change to conform to C api usage
1380 if((result
==NULL
)||(result
[0] != 0))
1381 errln("ERROR: getISO3Language() returns: " + UnicodeString(result
,"") +
1382 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1389 LocaleTest::Test4147552()
1391 Locale locales
[] = { Locale("no", "NO"),
1392 Locale("no", "NO", "B"),
1393 Locale("no", "NO", "NY")
1396 UnicodeString
edn("Norwegian (Norway, B)");
1397 UnicodeString englishDisplayNames
[] = {
1398 "Norwegian (Norway)",
1400 // "Norwegian (Norway,B)",
1401 //"Norwegian (Norway,NY)"
1402 "Norwegian (Norway, NY)"
1404 UnicodeString
ndn("norsk (Norge, B");
1405 UnicodeString norwegianDisplayNames
[] = {
1410 //"Norsk (Noreg, Nynorsk)"
1412 UErrorCode status
= U_ZERO_ERROR
;
1415 Locale::setDefault(Locale::getEnglish(), status
);
1416 for (int32_t i
= 0; i
< 3; ++i
) {
1417 Locale loc
= locales
[i
];
1419 if (loc
.getDisplayName(temp
) != englishDisplayNames
[i
])
1420 errln("English display-name mismatch: expected " +
1421 englishDisplayNames
[i
] + ", got " + loc
.getDisplayName(temp
));
1422 if (loc
.getDisplayName(loc
, temp
) != norwegianDisplayNames
[i
])
1423 errln("Norwegian display-name mismatch: expected " +
1424 norwegianDisplayNames
[i
] + ", got " +
1425 loc
.getDisplayName(loc
, temp
));
1427 Locale::setDefault(saveLocale
, status
);
1431 LocaleTest::TestVariantParsing()
1433 Locale
en_US_custom("en", "US", "De Anza_Cupertino_California_United States_Earth");
1435 UnicodeString
dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)");
1436 UnicodeString
dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH");
1440 en_US_custom
.getDisplayVariant(Locale::getUS(), got
);
1441 if(got
!= dispVar
) {
1442 errln("FAIL: getDisplayVariant()");
1443 errln("Wanted: " + dispVar
);
1444 errln("Got : " + got
);
1447 en_US_custom
.getDisplayName(Locale::getUS(), got
);
1448 if(got
!= dispName
) {
1449 errln("FAIL: getDisplayName()");
1450 errln("Wanted: " + dispName
);
1451 errln("Got : " + got
);
1454 Locale
shortVariant("fr", "FR", "foo");
1455 shortVariant
.getDisplayVariant(got
);
1458 errln("FAIL: getDisplayVariant()");
1459 errln("Wanted: foo");
1460 errln("Got : " + got
);
1463 Locale
bogusVariant("fr", "FR", "_foo");
1464 bogusVariant
.getDisplayVariant(got
);
1467 errln("FAIL: getDisplayVariant()");
1468 errln("Wanted: foo");
1469 errln("Got : " + got
);
1472 Locale
bogusVariant2("fr", "FR", "foo_");
1473 bogusVariant2
.getDisplayVariant(got
);
1476 errln("FAIL: getDisplayVariant()");
1477 errln("Wanted: foo");
1478 errln("Got : " + got
);
1481 Locale
bogusVariant3("fr", "FR", "_foo_");
1482 bogusVariant3
.getDisplayVariant(got
);
1485 errln("FAIL: getDisplayVariant()");
1486 errln("Wanted: foo");
1487 errln("Got : " + got
);
1491 #if !UCONFIG_NO_FORMATTING
1495 * Currency symbol in zh is wrong. We will test this at the NumberFormat
1496 * end to test the whole pipe.
1499 LocaleTest::Test4105828()
1501 Locale LOC
[] = { Locale::getChinese(), Locale("zh", "CN", ""),
1502 Locale("zh", "TW", ""), Locale("zh", "HK", "") };
1503 UErrorCode status
= U_ZERO_ERROR
;
1504 for (int32_t i
= 0; i
< 4; ++i
) {
1505 NumberFormat
*fmt
= NumberFormat::createPercentInstance(LOC
[i
], status
);
1506 if(U_FAILURE(status
)) {
1507 errln("Couldn't create NumberFormat");
1510 UnicodeString result
;
1511 FieldPosition
pos(0);
1512 fmt
->format((int32_t)1, result
, pos
);
1514 if(result
!= "100%") {
1515 errln(UnicodeString("Percent for ") + LOC
[i
].getDisplayName(temp
) + " should be 100%, got " + result
);
1523 // Tests setBogus and isBogus APIs for Locale
1526 LocaleTest::TestSetIsBogus() {
1529 if(l
.isBogus() != TRUE
) {
1530 errln("After setting bogus, didn't return TRUE");
1532 l
= "en_US"; // This should reset bogus
1533 if(l
.isBogus() != FALSE
) {
1534 errln("After resetting bogus, didn't return FALSE");
1540 LocaleTest::TestKeywordVariants(void) {
1542 const char *localeID
;
1543 const char *expectedLocaleID
;
1544 //const char *expectedLocaleIDNoKeywords;
1545 //const char *expectedCanonicalID;
1546 const char *expectedKeywords
[10];
1547 int32_t numKeywords
;
1548 UErrorCode expectedStatus
;
1551 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1552 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1554 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1555 {"calendar", "collation", "currency"},
1563 //"de_DE@currency=EUR",
1564 {"","","","","","",""},
1566 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1569 UErrorCode status
= U_ZERO_ERROR
;
1571 int32_t i
= 0, j
= 0;
1572 const char *result
= NULL
;
1573 StringEnumeration
*keywords
;
1574 int32_t keyCount
= 0;
1575 const char *keyword
= NULL
;
1576 const UnicodeString
*keywordString
;
1577 int32_t keywordLen
= 0;
1579 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1580 status
= U_ZERO_ERROR
;
1581 Locale
l(testCases
[i
].localeID
);
1582 keywords
= l
.createKeywords(status
);
1584 if(status
!= testCases
[i
].expectedStatus
) {
1585 err("Expected to get status %s. Got %s instead\n",
1586 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1588 status
= U_ZERO_ERROR
;
1590 if((keyCount
= keywords
->count(status
)) != testCases
[i
].numKeywords
) {
1591 err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1596 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1599 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1600 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1603 if((keywordString
= keywords
->snext(status
)) == NULL
) {
1606 if(*keywordString
!= UnicodeString(testCases
[i
].expectedKeywords
[j
], "")) {
1607 err("Expected to get keyword UnicodeString %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1612 if(j
== keyCount
/ 2) {
1613 // replace keywords with a clone of itself
1614 StringEnumeration
*k2
= keywords
->clone();
1615 if(k2
== NULL
|| keyCount
!= k2
->count(status
)) {
1616 errln("KeywordEnumeration.clone() failed");
1623 keywords
->reset(status
); // Make sure that reset works.
1625 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1628 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1629 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1636 result
= l
.getName();
1637 if(uprv_strcmp(testCases
[i
].expectedLocaleID
, result
) != 0) {
1638 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n",
1639 testCases
[i
].expectedLocaleID
, testCases
[i
].localeID
, result
);
1647 LocaleTest::TestKeywordVariantParsing(void) {
1649 const char *localeID
;
1650 const char *keyword
;
1651 const char *expectedValue
;
1653 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook" },
1654 { "de_DE", "collation", ""},
1655 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" },
1656 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation", "PHONEBOOk" },
1659 UErrorCode status
= U_ZERO_ERROR
;
1662 int32_t resultLen
= 0;
1665 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1667 Locale
l(testCases
[i
].localeID
);
1668 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1669 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1670 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1671 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1677 LocaleTest::TestGetBaseName(void) {
1679 const char *localeID
;
1680 const char *baseName
;
1682 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
1683 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
1684 { "ja@calendar = buddhist", "ja" }
1689 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1690 Locale
loc(testCases
[i
].localeID
);
1691 if(strcmp(testCases
[i
].baseName
, loc
.getBaseName())) {
1692 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
1693 testCases
[i
].localeID
, testCases
[i
].baseName
, loc
.getBaseName());
1700 * Compare two locale IDs. If they are equal, return 0. If `string'
1701 * starts with `prefix' plus an additional element, that is, string ==
1702 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
1704 static UBool
_loccmp(const char* string
, const char* prefix
) {
1705 int32_t slen
= (int32_t)strlen(string
),
1706 plen
= (int32_t)strlen(prefix
);
1707 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
1708 /* 'root' is "less than" everything */
1709 if (uprv_strcmp(prefix
, "root") == 0) {
1710 return (uprv_strcmp(string
, "root") == 0) ? 0 : 1;
1712 if (c
) return -1; /* mismatch */
1713 if (slen
== plen
) return 0;
1714 if (string
[plen
] == '_') return 1;
1715 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
1719 * Check the relationship between requested locales, and report problems.
1720 * The caller specifies the expected relationships between requested
1721 * and valid (expReqValid) and between valid and actual (expValidActual).
1722 * Possible values are:
1723 * "gt" strictly greater than, e.g., en_US > en
1724 * "ge" greater or equal, e.g., en >= en
1725 * "eq" equal, e.g., en == en
1727 void LocaleTest::_checklocs(const char* label
,
1729 const Locale
& validLoc
,
1730 const Locale
& actualLoc
,
1731 const char* expReqValid
,
1732 const char* expValidActual
) {
1733 const char* valid
= validLoc
.getName();
1734 const char* actual
= actualLoc
.getName();
1735 int32_t reqValid
= _loccmp(req
, valid
);
1736 int32_t validActual
= _loccmp(valid
, actual
);
1737 if (((0 == uprv_strcmp(expReqValid
, "gt") && reqValid
> 0) ||
1738 (0 == uprv_strcmp(expReqValid
, "ge") && reqValid
>= 0) ||
1739 (0 == uprv_strcmp(expReqValid
, "eq") && reqValid
== 0)) &&
1740 ((0 == uprv_strcmp(expValidActual
, "gt") && validActual
> 0) ||
1741 (0 == uprv_strcmp(expValidActual
, "ge") && validActual
>= 0) ||
1742 (0 == uprv_strcmp(expValidActual
, "eq") && validActual
== 0))) {
1743 logln("%s; req=%s, valid=%s, actual=%s",
1744 label
, req
, valid
, actual
);
1746 errln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
1747 label
, req
, valid
, actual
,
1748 expReqValid
, expValidActual
);
1752 void LocaleTest::TestGetLocale(void) {
1753 #if !UCONFIG_NO_SERVICE
1754 UErrorCode ec
= U_ZERO_ERROR
;
1756 Locale valid
, actual
, reqLoc
;
1759 #if !UCONFIG_NO_FORMATTING
1760 req
= "en_US_BROOKLYN";
1761 Calendar
* cal
= Calendar::createInstance(Locale::createFromName(req
), ec
);
1762 if (U_FAILURE(ec
)) {
1763 errln("FAIL: Calendar::createInstance failed");
1765 valid
= cal
->getLocale(ULOC_VALID_LOCALE
, ec
);
1766 actual
= cal
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1767 if (U_FAILURE(ec
)) {
1768 errln("FAIL: Calendar::getLocale() failed");
1770 _checklocs("Calendar", req
, valid
, actual
);
1772 /* Make sure that it fails correctly */
1773 ec
= U_FILE_ACCESS_ERROR
;
1774 if (cal
->getLocale(ULOC_VALID_LOCALE
, ec
).getName()[0] != 0) {
1775 errln("FAIL: Calendar::getLocale() failed to fail correctly. It should have returned \"\"");
1782 // DecimalFormat, DecimalFormatSymbols
1783 #if !UCONFIG_NO_FORMATTING
1785 DecimalFormat
* dec
= (DecimalFormat
*)
1786 NumberFormat::createInstance(Locale::createFromName(req
), ec
);
1787 if (U_FAILURE(ec
)) {
1788 errln("FAIL: NumberFormat::createInstance failed");
1790 if (dec
->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
1791 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
1794 valid
= dec
->getLocale(ULOC_VALID_LOCALE
, ec
);
1795 actual
= dec
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1796 if (U_FAILURE(ec
)) {
1797 errln("FAIL: DecimalFormat::getLocale() failed");
1799 _checklocs("DecimalFormat", req
, valid
, actual
);
1802 const DecimalFormatSymbols
* sym
= dec
->getDecimalFormatSymbols();
1804 errln("FAIL: getDecimalFormatSymbols returned NULL");
1807 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1808 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1809 if (U_FAILURE(ec
)) {
1810 errln("FAIL: DecimalFormatSymbols::getLocale() failed");
1812 _checklocs("DecimalFormatSymbols", req
, valid
, actual
);
1818 // DateFormat, DateFormatSymbols
1819 #if !UCONFIG_NO_FORMATTING
1820 req
= "de_CH_LUCERNE";
1821 SimpleDateFormat
* dat
= (SimpleDateFormat
*)
1822 DateFormat::createDateInstance(DateFormat::kDefault
,
1823 Locale::createFromName(req
));
1825 dataerrln("Error calling DateFormat::createDateInstance()");
1827 if (dat
->getDynamicClassID() != SimpleDateFormat::getStaticClassID()) {
1828 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
1831 valid
= dat
->getLocale(ULOC_VALID_LOCALE
, ec
);
1832 actual
= dat
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1833 if (U_FAILURE(ec
)) {
1834 errln("FAIL: SimpleDateFormat::getLocale() failed");
1836 _checklocs("SimpleDateFormat", req
, valid
, actual
);
1839 const DateFormatSymbols
* sym
= dat
->getDateFormatSymbols();
1841 errln("FAIL: getDateFormatSymbols returned NULL");
1844 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1845 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1846 if (U_FAILURE(ec
)) {
1847 errln("FAIL: DateFormatSymbols::getLocale() failed");
1849 _checklocs("DateFormatSymbols", req
, valid
, actual
);
1856 #if !UCONFIG_NO_BREAK_ITERATION
1857 req
= "es_ES_BARCELONA";
1858 reqLoc
= Locale::createFromName(req
);
1859 BreakIterator
* brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1860 if (U_FAILURE(ec
)) {
1861 errln("FAIL: BreakIterator::createWordInstance failed");
1863 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1864 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1865 if (U_FAILURE(ec
)) {
1866 errln("FAIL: BreakIterator::getLocale() failed");
1868 _checklocs("BreakIterator", req
, valid
, actual
);
1871 // After registering something, the behavior should be different
1872 URegistryKey key
= BreakIterator::registerInstance(brk
, reqLoc
, UBRK_WORD
, ec
);
1873 brk
= 0; // registerInstance adopts
1874 if (U_FAILURE(ec
)) {
1875 errln("FAIL: BreakIterator::registerInstance() failed");
1877 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1878 if (U_FAILURE(ec
)) {
1879 errln("FAIL: BreakIterator::createWordInstance failed");
1881 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1882 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1883 if (U_FAILURE(ec
)) {
1884 errln("FAIL: BreakIterator::getLocale() failed");
1886 // N.B.: now expect valid==actual==req
1887 _checklocs("BreakIterator(registered)",
1888 req
, valid
, actual
, "eq", "eq");
1891 // No matter what, unregister
1892 BreakIterator::unregister(key
, ec
);
1893 if (U_FAILURE(ec
)) {
1894 errln("FAIL: BreakIterator::unregister() failed");
1900 // After unregistering, should behave normally again
1901 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1902 if (U_FAILURE(ec
)) {
1903 errln("FAIL: BreakIterator::createWordInstance failed");
1905 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1906 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1907 if (U_FAILURE(ec
)) {
1908 errln("FAIL: BreakIterator::getLocale() failed");
1910 _checklocs("BreakIterator(unregistered)", req
, valid
, actual
);
1918 #if !UCONFIG_NO_COLLATION
1919 req
= "hi_IN_BHOPAL";
1920 reqLoc
= Locale::createFromName(req
);
1921 Collator
* coll
= Collator::createInstance(reqLoc
, ec
);
1922 if (U_FAILURE(ec
)) {
1923 errln("FAIL: Collator::createInstance failed");
1925 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
1926 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1927 if (U_FAILURE(ec
)) {
1928 errln("FAIL: Collator::getLocale() failed");
1930 _checklocs("Collator", req
, valid
, actual
);
1933 // After registering something, the behavior should be different
1934 URegistryKey key
= Collator::registerInstance(coll
, reqLoc
, ec
);
1935 coll
= 0; // registerInstance adopts
1936 if (U_FAILURE(ec
)) {
1937 errln("FAIL: Collator::registerInstance() failed");
1939 coll
= Collator::createInstance(reqLoc
, ec
);
1940 if (U_FAILURE(ec
)) {
1941 errln("FAIL: Collator::createWordInstance failed");
1943 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
1944 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1945 if (U_FAILURE(ec
)) {
1946 errln("FAIL: Collator::getLocale() failed");
1948 // N.B.: now expect valid==actual==req
1949 _checklocs("Collator(registered)",
1950 req
, valid
, actual
, "eq", "eq");
1953 // No matter what, unregister
1954 Collator::unregister(key
, ec
);
1955 if (U_FAILURE(ec
)) {
1956 errln("FAIL: Collator::unregister() failed");
1962 // After unregistering, should behave normally again
1963 coll
= Collator::createInstance(reqLoc
, ec
);
1964 if (U_FAILURE(ec
)) {
1965 errln("FAIL: Collator::createInstance failed");
1967 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
1968 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1969 if (U_FAILURE(ec
)) {
1970 errln("FAIL: Collator::getLocale() failed");
1972 _checklocs("Collator(unregistered)", req
, valid
, actual
);
1981 void LocaleTest::TestVariantWithOutCountry(void) {
1982 Locale
loc("en","","POSIX");
1983 if (0 != strcmp(loc
.getVariant(), "POSIX")) {
1984 errln("FAIL: en__POSIX didn't get parsed correctly");
1986 Locale
loc2("en","","FOUR");
1987 if (0 != strcmp(loc2
.getVariant(), "FOUR")) {
1988 errln("FAIL: en__FOUR didn't get parsed correctly");
1990 Locale
loc3("en","Latn","","FOUR");
1991 if (0 != strcmp(loc3
.getVariant(), "FOUR")) {
1992 errln("FAIL: en_Latn__FOUR didn't get parsed correctly");
1994 Locale
loc4("","Latn","","FOUR");
1995 if (0 != strcmp(loc4
.getVariant(), "FOUR")) {
1996 errln("FAIL: _Latn__FOUR didn't get parsed correctly");
1998 Locale
loc5("","Latn","US","FOUR");
1999 if (0 != strcmp(loc5
.getVariant(), "FOUR")) {
2000 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly");
2004 static Locale
_canonicalize(int32_t selector
, /* 0==createFromName, 1==createCanonical, 2==Locale ct */
2005 const char* localeID
) {
2008 return Locale::createFromName(localeID
);
2010 return Locale::createCanonical(localeID
);
2012 return Locale(localeID
);
2018 void LocaleTest::TestCanonicalization(void)
2021 const char *localeID
; /* input */
2022 const char *getNameID
; /* expected getName() result */
2023 const char *canonicalID
; /* expected canonicalize() result */
2025 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2026 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2027 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2028 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
2029 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
2030 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
2031 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
2032 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
2033 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
2034 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
2035 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
2036 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
2037 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
2038 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
2039 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
2040 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
2041 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
2042 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
2043 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
2044 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
2045 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
2046 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
2047 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
2048 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
2049 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
2050 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
2051 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
2052 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
2053 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
2054 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_Hant_TW@collation=stroke" },
2055 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
2056 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2057 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2058 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2059 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2060 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2061 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2062 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2063 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2064 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
2065 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
2066 // TODO: unify this behavior
2067 { "en-BOONT", "BOGUS", "en__BOONT" }, /* registered name */
2068 { "de-1901", "de_1901", "de__1901" }, /* registered name */
2069 { "de-1906", "de_1906", "de__1906" }, /* registered name */
2070 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_CS" }, /* .NET name */
2071 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_CS" }, /* .NET name */
2072 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_CS" }, /* Linux name */
2073 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
2074 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
2075 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
2076 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */
2078 /* posix behavior that used to be performed by getName */
2079 { "mr.utf8", "mr.utf8", "mr" },
2080 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2081 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2082 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2083 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2084 { "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 */
2086 /* fleshing out canonicalization */
2087 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2088 { "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" },
2089 /* already-canonical ids are not changed */
2090 { "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" },
2091 /* PRE_EURO and EURO conversions don't affect other keywords */
2092 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
2093 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
2094 /* currency keyword overrides PRE_EURO and EURO currency */
2095 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
2096 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
2097 /* norwegian is just too weird, if we handle things in their full generality */
2098 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2100 /* test cases reflecting internal resource bundle usage */
2101 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2102 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2103 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" }
2106 static const char* label
[] = { "createFromName", "createCanonical", "Locale" };
2110 for (i
=0; i
< (int)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
2111 for (j
=0; j
<3; ++j
) {
2112 const char* expected
= (j
==1) ? testCases
[i
].canonicalID
: testCases
[i
].getNameID
;
2113 Locale loc
= _canonicalize(j
, testCases
[i
].localeID
);
2114 const char* getName
= loc
.isBogus() ? "BOGUS" : loc
.getName();
2115 if(uprv_strcmp(expected
, getName
) != 0) {
2116 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"",
2117 label
[j
], testCases
[i
].localeID
, getName
, expected
);
2119 logln("Ok: %s(%s) => \"%s\"",
2120 label
[j
], testCases
[i
].localeID
, getName
);