1 /********************************************************************
3 * Copyright (c) 1997-2004, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
9 #include "unicode/decimfmt.h"
10 #include "unicode/ucurr.h"
11 #include "unicode/smpdtfmt.h"
12 #include "unicode/dtfmtsym.h"
13 #include "unicode/brkiter.h"
14 #include "unicode/coll.h"
18 const char* rawData
[33][8] = {
21 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
23 { "", "", "", "", "", "", "", "Hans" },
25 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" },
27 { "", "", "", "", "NY", "", "", "" },
29 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" },
31 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" },
33 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" },
35 { "409", "40c", "403", "408", "814", "10", "0", "804" },
37 // display langage (English)
38 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" },
39 // display script (English)
40 { "", "", "", "", "", "", "", "Simplified Han" },
41 // display country (English)
42 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China" },
43 // display variant (English)
44 { "", "", "", "", "NY", "", "", ""},
45 // display name (English)
46 // Updated no_NO_NY English display name for new pattern-based algorithm
47 // (part of Euro support).
48 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplified Han, China)" },
50 // display langage (French)
51 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
52 // display script (French)
53 { "", "", "", "", "", "", "", "han simplifi\\u00E9" },
54 // display country (French)
55 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine" },
56 // display variant (French)
57 { "", "", "", "", "NY", "", "", "" },
58 // display name (French)
59 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
60 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois (han simplifi\\u00E9, Chine)" }, // STILL not right
63 /* display language (Catalan) */
64 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E9s" },
65 /* display script (Catalan) */
66 { "", "", "", "", "", "", "", "Hans" },
67 /* display country (Catalan) */
68 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina" },
69 /* display variant (Catalan) */
70 { "", "", "", "", "NY", "", "" },
71 /* display name (Catalan) */
72 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E9s (Hans, Xina)" },
74 // display langage (Greek)[actual values listed below]
75 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
76 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
77 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
78 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
79 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
80 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
82 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
84 // display script (Greek)
85 { "", "", "", "", "", "", "", "Hans" },
86 // display country (Greek)[actual values listed below]
87 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
88 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
89 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
90 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
91 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
94 "\\u039A\\u03AF\\u03BD\\u03B1"
96 // display variant (Greek)
97 { "", "", "", "", "NY", "", "" },
98 // display name (Greek)[actual values listed below]
99 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
100 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
101 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
102 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
103 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
104 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
106 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (Hans, \\u039A\\u03AF\\u03BD\\u03B1)"
109 // display langage (<root>)
110 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" },
111 // display script (<root>)
112 { "", "", "", "", "", "", "", ""},
113 // display country (<root>)
114 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" },
115 // display variant (<root>)
116 { "", "", "", "", "Nynorsk", "", "", ""},
117 // display name (<root>)
118 //{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" },
119 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
125 test_compare( Function to be performed,
126 Test of the function,
127 expected result of the test,
132 test_compare(i=3,i,3, someNumberFormatter(i));
133 test_compare(0,1+1,2,someNumberFormatter(1+1));
135 Note that in the second example the expression is 0, because the fcn produces it's own result.
137 Macro is ugly but makes the tests pretty.
140 #define test_compare(expression,test,expected,printableResult) \
144 if((test) != (expected)) \
145 errln("FAIL: " + UnicodeString(#expression) + "; -> " + printableResult + "\n" + \
146 " (" + UnicodeString(#test) + " != " + UnicodeString(#expected) + ")" ); \
148 logln(UnicodeString(#expression) + " -> " + printableResult + " (" + UnicodeString(#test) + ")"); \
156 test_assert_print( Test (should be TRUE), printable )
159 test_assert(i==3, toString(i));
161 the macro is ugly but makes the tests pretty.
164 #define test_assert_print(test,print) \
167 errln("FAIL: " + UnicodeString(#test) + " was not true." + "-> " + UnicodeString(print) ); \
169 logln("PASS: asserted " + UnicodeString(#test) + "-> " + UnicodeString(print)); \
173 #define test_dumpLocale(l) { UnicodeString s(l.getName(),""); logln(#l + UnicodeString(" = ") + s); }
175 LocaleTest::LocaleTest()
181 LocaleTest::~LocaleTest()
183 if (dataTable
!= 0) {
184 for (int32_t i
= 0; i
< 33; i
++) {
185 delete []dataTable
[i
];
192 void LocaleTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
195 TESTCASE(0, TestBasicGetters
);
196 TESTCASE(1, TestSimpleResourceInfo
);
197 TESTCASE(2, TestDisplayNames
);
198 TESTCASE(3, TestSimpleObjectStuff
);
199 TESTCASE(4, TestPOSIXParsing
);
200 TESTCASE(5, TestGetAvailableLocales
);
201 TESTCASE(6, TestDataDirectory
);
202 TESTCASE(7, TestISO3Fallback
);
203 TESTCASE(8, TestGetLangsAndCountries
);
204 TESTCASE(9, TestSimpleDisplayNames
);
205 TESTCASE(10, TestUninstalledISO3Names
);
206 TESTCASE(11, TestAtypicalLocales
);
207 #if !UCONFIG_NO_FORMATTING
208 TESTCASE(12, TestThaiCurrencyFormat
);
209 TESTCASE(13, TestEuroSupport
);
211 TESTCASE(14, TestToString
);
212 #if !UCONFIG_NO_FORMATTING
213 TESTCASE(15, Test4139940
);
214 TESTCASE(16, Test4143951
);
216 TESTCASE(17, Test4147315
);
217 TESTCASE(18, Test4147317
);
218 TESTCASE(19, Test4147552
);
219 TESTCASE(20, TestVariantParsing
);
220 #if !UCONFIG_NO_FORMATTING
221 TESTCASE(21, Test4105828
);
223 TESTCASE(22, TestSetIsBogus
);
224 TESTCASE(23, TestParallelAPIValues
);
225 TESTCASE(24, TestKeywordVariants
);
226 TESTCASE(25, TestKeywordVariantParsing
);
227 TESTCASE(26, TestGetBaseName
);
228 TESTCASE(27, TestGetLocale
);
229 TESTCASE(28, TestVariantWithOutCountry
);
230 TESTCASE(29, TestCanonicalization
);
232 // keep the last index in sync with the condition in default:
235 if (index
<= 28) { // keep this in sync with the last index!
236 name
= "(test omitted by !UCONFIG_NO_FORMATTING)";
240 break; //needed to end loop
244 void LocaleTest::TestBasicGetters() {
248 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
249 Locale
testLocale("");
250 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
251 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
254 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
256 logln("Testing " + (UnicodeString
)testLocale
.getName() + "...");
258 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
259 errln(" Language code mismatch: " + temp
+ " versus "
260 + dataTable
[LANG
][i
]);
261 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
262 errln(" Script code mismatch: " + temp
+ " versus "
263 + dataTable
[SCRIPT
][i
]);
264 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
265 errln(" Country code mismatch: " + temp
+ " versus "
266 + dataTable
[CTRY
][i
]);
267 if ( (temp
=testLocale
.getVariant()) != (dataTable
[VAR
][i
]))
268 errln(" Variant code mismatch: " + temp
+ " versus "
269 + dataTable
[VAR
][i
]);
270 if ( (temp
=testLocale
.getName()) != (dataTable
[NAME
][i
]))
271 errln(" Locale name mismatch: " + temp
+ " versus "
272 + dataTable
[NAME
][i
]);
275 logln("Same thing without variant codes...");
276 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
277 Locale
testLocale("");
278 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
279 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
]);
282 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
]);
284 logln("Testing " + (temp
=testLocale
.getName()) + "...");
286 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
287 errln("Language code mismatch: " + temp
+ " versus "
288 + dataTable
[LANG
][i
]);
289 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
290 errln("Script code mismatch: " + temp
+ " versus "
291 + dataTable
[SCRIPT
][i
]);
292 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
293 errln("Country code mismatch: " + temp
+ " versus "
294 + dataTable
[CTRY
][i
]);
295 if (testLocale
.getVariant()[0] != 0)
296 errln("Variant code mismatch: something versus \"\"");
299 logln("Testing long language names and getters");
300 Locale test8
= Locale::createFromName("x-klingon-latn-zx.utf32be@special");
302 temp
= test8
.getLanguage();
303 if (temp
!= UnicodeString("x-klingon") )
304 errln("Language code mismatch: " + temp
+ " versus \"x-klingon\"");
306 temp
= test8
.getScript();
307 if (temp
!= UnicodeString("Latn") )
308 errln("Script code mismatch: " + temp
+ " versus \"Latn\"");
310 temp
= test8
.getCountry();
311 if (temp
!= UnicodeString("ZX") )
312 errln("Country code mismatch: " + temp
+ " versus \"ZX\"");
314 temp
= test8
.getVariant();
315 //if (temp != UnicodeString("SPECIAL") )
316 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\"");
317 // As of 3.0, the "@special" will *not* be parsed by uloc_getName()
318 if (temp
!= UnicodeString("") )
319 errln("Variant code mismatch: " + temp
+ " versus \"\"");
321 if (Locale::getDefault() != Locale::createFromName(NULL
))
322 errln("Locale::getDefault() == Locale::createFromName(NULL)");
325 // NOTE: There used to be a special test for locale names that had language or
326 // country codes that were longer than two letters. The new version of Locale
327 // doesn't support anything that isn't an officially recognized language or
328 // country code, so we no longer support this feature.
330 Locale
bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code too long
331 if(!bogusLang
.isBogus()) {
332 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE");
335 bogusLang
=Locale("eo");
336 if( bogusLang
.isBogus() ||
337 strcmp(bogusLang
.getLanguage(), "eo")!=0 ||
338 *bogusLang
.getCountry()!=0 ||
339 *bogusLang
.getVariant()!=0 ||
340 strcmp(bogusLang
.getName(), "eo")!=0
342 errln("assignment to bogus Locale does not unbogus it or sets bad data");
345 Locale
a("eo_DE@currency=DEM");
346 Locale
*pb
=a
.clone();
347 if(pb
==&a
|| *pb
!=a
) {
348 errln("Locale.clone() failed");
353 void LocaleTest::TestParallelAPIValues() {
354 logln("Test synchronization between C and C++ API");
355 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE
) != 0) {
356 errln("Differences for ULOC_CHINESE Locale");
358 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH
) != 0) {
359 errln("Differences for ULOC_ENGLISH Locale");
361 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH
) != 0) {
362 errln("Differences for ULOC_FRENCH Locale");
364 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN
) != 0) {
365 errln("Differences for ULOC_GERMAN Locale");
367 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN
) != 0) {
368 errln("Differences for ULOC_ITALIAN Locale");
370 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE
) != 0) {
371 errln("Differences for ULOC_JAPANESE Locale");
373 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN
) != 0) {
374 errln("Differences for ULOC_KOREAN Locale");
376 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE
) != 0) {
377 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale");
379 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINESE
) != 0) {
380 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale");
384 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA
) != 0) {
385 errln("Differences for ULOC_CANADA Locale");
387 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH
) != 0) {
388 errln("Differences for ULOC_CANADA_FRENCH Locale");
390 if (strcmp(Locale::getChina().getName(), ULOC_CHINA
) != 0) {
391 errln("Differences for ULOC_CHINA Locale");
393 if (strcmp(Locale::getPRC().getName(), ULOC_PRC
) != 0) {
394 errln("Differences for ULOC_PRC Locale");
396 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE
) != 0) {
397 errln("Differences for ULOC_FRANCE Locale");
399 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY
) != 0) {
400 errln("Differences for ULOC_GERMANY Locale");
402 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY
) != 0) {
403 errln("Differences for ULOC_ITALY Locale");
405 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN
) != 0) {
406 errln("Differences for ULOC_JAPAN Locale");
408 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA
) != 0) {
409 errln("Differences for ULOC_KOREA Locale");
411 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN
) != 0) {
412 errln("Differences for ULOC_TAIWAN Locale");
414 if (strcmp(Locale::getUK().getName(), ULOC_UK
) != 0) {
415 errln("Differences for ULOC_UK Locale");
417 if (strcmp(Locale::getUS().getName(), ULOC_US
) != 0) {
418 errln("Differences for ULOC_US Locale");
423 void LocaleTest::TestSimpleResourceInfo() {
426 UErrorCode err
= U_ZERO_ERROR
;
429 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
430 Locale
testLocale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
431 logln("Testing " + (temp
=testLocale
.getName()) + "...");
433 if ( (temp
=testLocale
.getISO3Language()) != (dataTable
[LANG3
][i
]))
434 errln(" ISO-3 language code mismatch: " + temp
435 + " versus " + dataTable
[LANG3
][i
]);
436 if ( (temp
=testLocale
.getISO3Country()) != (dataTable
[CTRY3
][i
]))
437 errln(" ISO-3 country code mismatch: " + temp
438 + " versus " + dataTable
[CTRY3
][i
]);
440 sprintf(temp2
, "%x", (int)testLocale
.getLCID());
441 if (UnicodeString(temp2
) != dataTable
[LCID
][i
])
442 errln((UnicodeString
)" LCID mismatch: " + temp2
+ " versus "
443 + dataTable
[LCID
][i
]);
447 errln((UnicodeString
)"Some error on number " + i
+ u_errorName(err
));
453 if(strcmp(locale
.getName(), "en") != 0||
454 strcmp(locale
.getLanguage(), "en") != 0) {
455 errln("construction of Locale(en) failed\n");
462 * Jitterbug 2439 -- markus 20030425
464 * The lookup of display names must not fall back through the default
465 * locale because that yields useless results.
468 LocaleTest::TestDisplayNames()
470 Locale
english("en", "US");
471 Locale
french("fr", "FR");
472 Locale
croatian("ca", "ES");
473 Locale
greek("el", "GR");
475 logln(" In locale = en_US...");
476 doTestDisplayNames(english
, DLANG_EN
);
477 logln(" In locale = fr_FR...");
478 doTestDisplayNames(french
, DLANG_FR
);
479 logln(" In locale = ca_ES...");
480 doTestDisplayNames(croatian
, DLANG_CA
);
481 logln(" In locale = el_GR...");
482 doTestDisplayNames(greek
, DLANG_EL
);
484 /* test that the default locale has a display name for its own language */
486 Locale().getDisplayLanguage(Locale(), s
);
487 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
488 /* check <=3 to reject getting the language code as a display name */
489 errln("unable to get a display string for the language of the default locale\n");
493 * API coverage improvements: call
494 * Locale::getDisplayLanguage(UnicodeString &) and
495 * Locale::getDisplayCountry(UnicodeString &)
498 Locale().getDisplayLanguage(s
);
499 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
500 errln("unable to get a display string for the language of the default locale [2]\n");
503 french
.getDisplayCountry(s
);
505 errln("unable to get any default-locale display string for the country of fr_FR\n");
511 test_assert( Test (should be TRUE) )
516 the macro is ugly but makes the tests pretty.
519 #define test_assert(test) \
522 errln("FAIL: " + UnicodeString(#test) + " was not true. " + UnicodeString(__FILE__ " line ") + __LINE__ ); \
524 logln("PASS: asserted " + UnicodeString(#test) ); \
527 void LocaleTest::TestSimpleObjectStuff() {
528 Locale
test1("aa", "AA");
529 Locale
test2("aa", "AA");
531 Locale
test4("zz", "ZZ");
532 Locale
test5("aa", "AA", "");
533 Locale
test6("aa", "AA", "ANTARES");
534 Locale
test7("aa", "AA", "JUPITER");
535 Locale test8
= Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that
537 // now list them all for debugging usage.
538 test_dumpLocale(test1
);
539 test_dumpLocale(test2
);
540 test_dumpLocale(test3
);
541 test_dumpLocale(test4
);
542 test_dumpLocale(test5
);
543 test_dumpLocale(test6
);
544 test_dumpLocale(test7
);
545 test_dumpLocale(test8
);
547 // Make sure things compare 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 are not equal to themselves.
558 test_assert(!(test1
!= test1
));
559 test_assert(!(test2
!= test2
));
560 test_assert(!(test3
!= test3
));
561 test_assert(!(test4
!= test4
));
562 test_assert(!(test5
!= test5
));
563 test_assert(!(test6
!= test6
));
564 test_assert(!(test7
!= test7
));
565 test_assert(!(test8
!= test8
));
567 // make sure things that are equal to each other don't show up as unequal.
568 test_assert(!(test1
!= test2
));
569 test_assert(!(test2
!= test1
));
570 test_assert(!(test1
!= test3
));
571 test_assert(!(test2
!= test3
));
572 test_assert(test5
== test1
);
573 test_assert(test6
!= test2
);
574 test_assert(test6
!= test5
);
576 test_assert(test6
!= test7
);
578 // test for things that shouldn't compare equal.
579 test_assert(!(test1
== test4
));
580 test_assert(!(test2
== test4
));
581 test_assert(!(test3
== test4
));
583 test_assert(test7
== test8
);
585 // test for hash codes to be the same.
586 int32_t hash1
= test1
.hashCode();
587 int32_t hash2
= test2
.hashCode();
588 int32_t hash3
= test3
.hashCode();
590 test_assert(hash1
== hash2
);
591 test_assert(hash1
== hash3
);
592 test_assert(hash2
== hash3
);
594 // test that the assignment operator works.
596 logln("test4=test1;");
597 test_dumpLocale(test4
);
598 test_assert(test4
== test4
);
600 test_assert(!(test1
!= test4
));
601 test_assert(!(test2
!= test4
));
602 test_assert(!(test3
!= test4
));
603 test_assert(test1
== test4
);
604 test_assert(test4
== test1
);
606 // test assignments with a variant
607 logln("test7 = test6");
609 test_dumpLocale(test7
);
610 test_assert(test7
== test7
);
611 test_assert(test7
== test6
);
612 test_assert(test7
!= test5
);
614 logln("test6 = test1");
616 test_dumpLocale(test6
);
617 test_assert(test6
!= test7
);
618 test_assert(test6
== test1
);
619 test_assert(test6
== test6
);
622 // A class which exposes constructors that are implemented in terms of the POSIX parsing code.
623 class POSIXLocale
: public Locale
626 POSIXLocale(const UnicodeString
& l
)
630 ch
= new char[l
.length() + 1];
631 ch
[l
.extract(0, 0x7fffffff, ch
, "")] = 0;
635 POSIXLocale(const char *l
)
642 void LocaleTest::TestPOSIXParsing()
644 POSIXLocale
test1("ab_AB");
645 POSIXLocale
test2(UnicodeString("ab_AB"));
646 Locale
test3("ab","AB");
648 POSIXLocale
test4("ab_AB_Antares");
649 POSIXLocale
test5(UnicodeString("ab_AB_Antares"));
650 Locale
test6("ab", "AB", "Antares");
652 test_dumpLocale(test1
);
653 test_dumpLocale(test2
);
654 test_dumpLocale(test3
);
655 test_dumpLocale(test4
);
656 test_dumpLocale(test5
);
657 test_dumpLocale(test6
);
659 test_assert(test1
== test1
);
661 test_assert(test1
== test2
);
662 test_assert(test2
== test3
);
663 test_assert(test3
== test1
);
665 test_assert(test4
== test5
);
666 test_assert(test5
== test6
);
667 test_assert(test6
== test4
);
669 test_assert(test1
!= test4
);
670 test_assert(test5
!= test3
);
671 test_assert(test5
!= test2
);
673 int32_t hash1
= test1
.hashCode();
674 int32_t hash2
= test2
.hashCode();
675 int32_t hash3
= test3
.hashCode();
677 test_assert(hash1
== hash2
);
678 test_assert(hash2
== hash3
);
679 test_assert(hash3
== hash1
);
682 void LocaleTest::TestGetAvailableLocales()
684 int32_t locCount
= 0;
685 const Locale
* locList
= Locale::getAvailableLocales(locCount
);
688 errln("getAvailableLocales() returned an empty list!");
690 logln(UnicodeString("Number of locales returned = ") + locCount
);
692 for(int32_t i
= 0; i
< locCount
; ++i
)
693 logln(locList
[i
].getName());
695 // I have no idea how to test this function...
698 // This test isn't applicable anymore - getISO3Language is
699 // independent of the data directory
700 void LocaleTest::TestDataDirectory()
703 char oldDirectory[80];
705 UErrorCode err = U_ZERO_ERROR;
706 UnicodeString testValue;
708 temp = Locale::getDataDirectory();
709 strcpy(oldDirectory, temp);
710 logln(UnicodeString("oldDirectory = ") + oldDirectory);
712 Locale test(Locale::US);
713 test.getISO3Language(testValue);
714 logln("first fetch of language retrieved " + testValue);
715 if (testValue != "eng")
716 errln("Initial check of ISO3 language failed: expected \"eng\", got \"" + testValue + "\"");
720 path=IntlTest::getTestDirectory();
721 Locale::setDataDirectory( path );
724 test.getISO3Language(testValue);
725 logln("second fetch of language retrieved " + testValue);
726 if (testValue != "xxx")
727 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue + "\"");
729 Locale::setDataDirectory(oldDirectory);
730 test.getISO3Language(testValue);
731 logln("third fetch of language retrieved " + testValue);
732 if (testValue != "eng")
733 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testValue + "\"");
737 //===========================================================
739 void LocaleTest::doTestDisplayNames(Locale
& displayLocale
, int32_t compareIndex
) {
742 for (int32_t i
= 0; i
<= MAX_LOCALES
; i
++) {
743 Locale
testLocale("");
744 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
745 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
748 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
750 logln(" Testing " + (temp
=testLocale
.getName()) + "...");
752 UnicodeString testLang
;
753 UnicodeString testScript
;
754 UnicodeString testCtry
;
755 UnicodeString testVar
;
756 UnicodeString testName
;
758 testLocale
.getDisplayLanguage(displayLocale
, testLang
);
759 testLocale
.getDisplayScript(displayLocale
, testScript
);
760 testLocale
.getDisplayCountry(displayLocale
, testCtry
);
761 testLocale
.getDisplayVariant(displayLocale
, testVar
);
762 testLocale
.getDisplayName(displayLocale
, testName
);
764 UnicodeString expectedLang
;
765 UnicodeString expectedScript
;
766 UnicodeString expectedCtry
;
767 UnicodeString expectedVar
;
768 UnicodeString expectedName
;
770 expectedLang
= dataTable
[compareIndex
][i
];
771 if (expectedLang
.length() == 0)
772 expectedLang
= dataTable
[DLANG_EN
][i
];
774 expectedScript
= dataTable
[compareIndex
+ 1][i
];
775 if (expectedScript
.length() == 0)
776 expectedScript
= dataTable
[DSCRIPT_EN
][i
];
778 expectedCtry
= dataTable
[compareIndex
+ 2][i
];
779 if (expectedCtry
.length() == 0)
780 expectedCtry
= dataTable
[DCTRY_EN
][i
];
782 expectedVar
= dataTable
[compareIndex
+ 3][i
];
783 if (expectedVar
.length() == 0)
784 expectedVar
= dataTable
[DVAR_EN
][i
];
786 expectedName
= dataTable
[compareIndex
+ 4][i
];
787 if (expectedName
.length() == 0)
788 expectedName
= dataTable
[DNAME_EN
][i
];
790 if (testLang
!= expectedLang
)
791 errln("Display language (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testLang
+ " expected " + expectedLang
);
792 if (testScript
!= expectedScript
)
793 errln("Display script (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testScript
+ " expected " + expectedScript
);
794 if (testCtry
!= expectedCtry
)
795 errln("Display country (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testCtry
+ " expected " + expectedCtry
);
796 if (testVar
!= expectedVar
)
797 errln("Display variant (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testVar
+ " expected " + expectedVar
);
798 if (testName
!= expectedName
)
799 errln("Display name (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testName
+ " expected " + expectedName
);
803 //---------------------------------------------------
804 // table of valid data
805 //---------------------------------------------------
809 void LocaleTest::setUpDataTable()
811 if (dataTable
== 0) {
812 dataTable
= new UnicodeString
*[33];
814 for (int32_t i
= 0; i
< 33; i
++) {
815 dataTable
[i
] = new UnicodeString
[8];
816 for (int32_t j
= 0; j
< 8; j
++) {
817 dataTable
[i
][j
] = CharsToUnicodeString(rawData
[i
][j
]);
823 // ====================
827 * @bug 4011756 4011380
830 LocaleTest::TestISO3Fallback()
832 Locale
test("xx", "YY");
836 result
= test
.getISO3Language();
838 // Conform to C API usage
840 if (!result
|| (result
[0] != 0))
841 errln("getISO3Language() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
843 result
= test
.getISO3Country();
845 if (!result
|| (result
[0] != 0))
846 errln("getISO3Country() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
850 * @bug 4106155 4118587
853 LocaleTest::TestGetLangsAndCountries()
855 // It didn't seem right to just do an exhaustive test of everything here, so I check
856 // for the following things:
857 // 1) Does each list have the right total number of entries?
858 // 2) Does each list contain certain language and country codes we think are important
859 // (the G7 countries, plus a couple others)?
860 // 3) Does each list have every entry formatted correctly? (i.e., two characters,
861 // all lower case for the language codes, all upper case for the country codes)
862 // 4) Is each list in sorted order?
863 int32_t testCount
= 0;
864 const char * const * test
= Locale::getISOLanguages();
865 const char spotCheck1
[ ][4] = { "en", "es", "fr", "de", "it",
866 "ja", "ko", "zh", "th", "he",
867 "id", "iu", "ug", "yi", "za" };
871 for(testCount
= 0;test
[testCount
];testCount
++)
874 /* TODO: Change this test to be more like the cloctst version? */
875 if (testCount
!= 468)
876 errln("Expected getISOLanguages() to return 468 languages; it returned %d", testCount
);
878 for (i
= 0; i
< 15; i
++) {
880 for (j
= 0; j
< testCount
; j
++)
881 if (uprv_strcmp(test
[j
],spotCheck1
[i
])== 0)
883 if (j
== testCount
|| (uprv_strcmp(test
[j
],spotCheck1
[i
])!=0))
884 errln("Couldn't find " + (UnicodeString
)spotCheck1
[i
] + " in language list.");
887 for (i
= 0; i
< testCount
; i
++) {
888 UnicodeString
testee(test
[i
],"");
889 UnicodeString
lc(test
[i
],"");
890 if (testee
!= lc
.toLower())
891 errln(lc
+ " is not all lower case.");
892 if ( (testee
.length() != 2) && (testee
.length() != 3))
893 errln(testee
+ " is not two or three characters long.");
894 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
895 errln(testee
+ " appears in an out-of-order position in the list.");
898 test
= Locale::getISOCountries();
899 UnicodeString spotCheck2
[] = { "US", "CA", "GB", "FR", "DE",
900 "IT", "JP", "KR", "CN", "TW",
902 int32_t spot2Len
= 11;
903 for(testCount
=0;test
[testCount
];testCount
++)
906 if (testCount
!= 239)
907 errln("Expected getISOLanguages to return 238 languages; it returned" + testCount
);
909 for (i
= 0; i
< spot2Len
; i
++) {
911 for (j
= 0; j
< testCount
; j
++)
913 UnicodeString
testee(test
[j
],"");
915 if (testee
== spotCheck2
[i
])
918 UnicodeString
testee(test
[j
],"");
919 if (j
== testCount
|| testee
!= spotCheck2
[i
])
920 errln("Couldn't find " + spotCheck2
[i
] + " in country list.");
923 for (i
= 0; i
< testCount
; i
++) {
924 UnicodeString
testee(test
[i
],"");
925 UnicodeString
uc(test
[i
],"");
926 if (testee
!= uc
.toUpper())
927 errln(testee
+ " is not all upper case.");
928 if (testee
.length() != 2)
929 errln(testee
+ " is not two characters long.");
930 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
931 errln(testee
+ " appears in an out-of-order position in the list.");
939 LocaleTest::TestSimpleDisplayNames()
941 // This test is different from TestDisplayNames because TestDisplayNames checks
942 // fallback behavior, combination of language and country names to form locale
943 // names, and other stuff like that. This test just checks specific language
944 // and country codes to make sure we have the correct names for them.
945 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
946 UnicodeString languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish",
949 for (int32_t i
= 0; i
< 6; i
++) {
951 Locale
l(languageCodes
[i
], "", "");
952 l
.getDisplayLanguage(Locale::getUS(), test
);
953 if (test
!= languageNames
[i
])
954 errln("Got wrong display name for " + UnicodeString(languageCodes
[i
]) + ": Expected \"" +
955 languageNames
[i
] + "\", got \"" + test
+ "\".");
963 LocaleTest::TestUninstalledISO3Names()
965 // This test checks to make sure getISO3Language and getISO3Country work right
966 // even for locales that are not installed.
967 const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
969 const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
970 "ssw", "twi", "zul" };
974 for (i
= 0; i
< 8; i
++) {
975 UErrorCode err
= U_ZERO_ERROR
;
978 Locale
l(iso2Languages
[i
], "", "");
979 test
= l
.getISO3Language();
980 if((test
!= iso3Languages
[i
]) || U_FAILURE(err
))
981 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages
[i
]) + ": Expected \"" +
982 iso3Languages
[i
] + "\", got \"" + test
+ "\"." + UnicodeString(u_errorName(err
)));
985 char iso2Countries
[][4] = { "AF", "BW", "KZ", "MO", "MN",
987 char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
988 "SLB", "TCA", "ZWE" };
990 for (i
= 0; i
< 8; i
++) {
991 UErrorCode err
= U_ZERO_ERROR
;
992 Locale
l("", iso2Countries
[i
], "");
993 UnicodeString
test(l
.getISO3Country(), "");
994 if (test
!= iso3Countries
[i
])
995 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries
[i
]) + ": Expected \"" +
996 UnicodeString(iso3Countries
[i
]) + "\", got \"" + test
+ "\"." + u_errorName(err
));
1002 * I could not reproduce this bug. I'm pretty convinced it was fixed with the
1003 * big locale-data reorg of 10/28/97. The lookup logic for language and country
1004 * display names was also changed at that time in that check-in. --rtg 3/20/98
1007 LocaleTest::TestAtypicalLocales()
1009 Locale localesToTest
[] = { Locale("de", "CA"),
1019 UnicodeString englishDisplayNames
[] = { "German (Canada)",
1020 "Japanese (South Africa)",
1023 "Spanish (Germany)",
1026 "Dominican Republic",
1028 UnicodeString frenchDisplayNames
[]= { "allemand (Canada)",
1029 "japonais (Afrique du Sud)",
1032 "espagnol (Allemagne)",
1034 CharsToUnicodeString("Su\\u00E8de"),
1035 CharsToUnicodeString("R\\u00E9publique dominicaine"),
1037 UnicodeString spanishDisplayNames
[] = {
1038 CharsToUnicodeString("alem\\u00E1n (Canad\\u00E1)"),
1039 CharsToUnicodeString("japon\\u00E9s (Sud\\u00E1frica)"),
1040 CharsToUnicodeString("ruso (M\\u00E9xico)"),
1041 CharsToUnicodeString("ingl\\u00E9s (Francia)"),
1042 CharsToUnicodeString("espa\\u00F1ol (Alemania)"),
1045 CharsToUnicodeString("Rep\\u00FAblica Dominicana"),
1046 CharsToUnicodeString("B\\u00E9lgica") };
1047 // De-Anglicizing root required the change from
1048 // English display names to ISO Codes - ram 2003/09/26
1049 UnicodeString bengaliDisplayNames
[] = { "de (CA)",
1060 UErrorCode status
= U_ZERO_ERROR
;
1061 Locale::setDefault(Locale::getUS(), status
);
1062 for (i
= 0; i
< 9; ++i
) {
1064 localesToTest
[i
].getDisplayName(Locale::getUS(), name
);
1066 if (name
!= englishDisplayNames
[i
])
1068 errln("Lookup in English failed: expected \"" + englishDisplayNames
[i
]
1069 + "\", got \"" + name
+ "\"");
1070 logln("Locale name was-> " + (name
=localesToTest
[i
].getName()));
1074 for (i
= 0; i
< 9; i
++) {
1076 localesToTest
[i
].getDisplayName(Locale("es", "ES"), name
);
1078 if (name
!= spanishDisplayNames
[i
])
1079 errln("Lookup in Spanish failed: expected \"" + spanishDisplayNames
[i
]
1080 + "\", got \"" + name
+ "\"");
1083 for (i
= 0; i
< 9; i
++) {
1085 localesToTest
[i
].getDisplayName(Locale::getFrance(), name
);
1087 if (name
!= frenchDisplayNames
[i
])
1088 errln("Lookup in French failed: expected \"" + frenchDisplayNames
[i
]
1089 + "\", got \"" + name
+ "\"");
1092 for (i
= 0; i
< 9; i
++) {
1094 localesToTest
[i
].getDisplayName(Locale("be", "ES"), name
);
1095 logln(name
+ " Locale fallback to be, and data fallback to root");
1096 if (name
!= bengaliDisplayNames
[i
])
1097 errln("Lookup in Bengali failed: expected \"" + bengaliDisplayNames
[i
]
1098 + "\", got \"" + name
+ "\"");
1099 localesToTest
[i
].getDisplayName(Locale("be", "EG"), name
);
1100 logln(name
+ " Data fallback to root");
1101 if (name
!= bengaliDisplayNames
[i
])
1102 errln("Lookup in Bengali failed: expected \"" + bengaliDisplayNames
[i
]
1103 + "\", got \"" + name
+ "\"");
1107 #if !UCONFIG_NO_FORMATTING
1111 * This would be better tested by the LocaleDataTest. Will move it when I
1112 * get the LocaleDataTest working again.
1115 LocaleTest::TestThaiCurrencyFormat()
1117 UErrorCode status
= U_ZERO_ERROR
;
1118 DecimalFormat
*thaiCurrency
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(
1119 Locale("th", "TH"), status
);
1120 UChar posPrefix
= 0x0e3f;
1123 if(U_FAILURE(status
) || !thaiCurrency
)
1125 errln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status
)));
1128 if (thaiCurrency
->getPositivePrefix(temp
) != UnicodeString(&posPrefix
, 1, 1))
1129 errln("Thai currency prefix wrong: expected 0x0e3f, got \"" +
1130 thaiCurrency
->getPositivePrefix(temp
) + "\"");
1131 if (thaiCurrency
->getPositiveSuffix(temp
) != "")
1132 errln("Thai currency suffix wrong: expected \"\", got \"" +
1133 thaiCurrency
->getPositiveSuffix(temp
) + "\"");
1135 delete thaiCurrency
;
1140 * Confirm that Euro support works. This test is pretty rudimentary; all it does
1141 * is check that any locales with the EURO variant format a number using the
1142 * Euro currency symbol.
1144 * ASSUME: All locales encode the Euro character "\u20AC".
1145 * If this is changed to use the single-character Euro symbol, this
1146 * test must be updated.
1150 LocaleTest::TestEuroSupport()
1152 UChar euro
= 0x20ac;
1153 const UnicodeString
EURO_CURRENCY(&euro
, 1, 1); // Look for this UnicodeString in formatted Euro currency
1154 const char* localeArr
[] = {
1178 const char** locales
= localeArr
;
1180 UErrorCode status
= U_ZERO_ERROR
;
1184 for (;*locales
!=NULL
;locales
++) {
1185 Locale
loc (*locales
);
1187 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(loc
, status
);
1189 nf
->format(271828.182845, pos
);
1191 nf
->format(-271828.182845, neg
);
1192 if (pos
.indexOf(EURO_CURRENCY
) >= 0 &&
1193 neg
.indexOf(EURO_CURRENCY
) >= 0) {
1194 logln("Ok: " + (temp
=loc
.getName()) +
1195 ": " + pos
+ " / " + neg
);
1198 errln("Fail: " + (temp
=loc
.getName()) +
1199 " formats without " + EURO_CURRENCY
+
1200 ": " + pos
+ " / " + neg
+
1201 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***");
1207 UnicodeString
dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar
)0x00a4), resultStr
;
1209 status
= U_ZERO_ERROR
;
1211 ucurr_forLocale("en_US", tmp
, 4, &status
);
1212 resultStr
.setTo(tmp
);
1213 if (dollarStr
!= resultStr
) {
1214 errln("Fail: en_US didn't return USD");
1216 ucurr_forLocale("en_US_EURO", tmp
, 4, &status
);
1217 resultStr
.setTo(tmp
);
1218 if (euroStr
!= resultStr
) {
1219 errln("Fail: en_US_EURO didn't return EUR");
1221 ucurr_forLocale("en_GB_EURO", tmp
, 4, &status
);
1222 resultStr
.setTo(tmp
);
1223 if (euroStr
!= resultStr
) {
1224 errln("Fail: en_GB_EURO didn't return EUR");
1226 ucurr_forLocale("en_US_PREEURO", tmp
, 4, &status
);
1227 resultStr
.setTo(tmp
);
1228 if (dollarStr
!= resultStr
) {
1229 errln("Fail: en_US_PREEURO didn't fallback to en_US");
1231 ucurr_forLocale("en_US_Q", tmp
, 4, &status
);
1232 resultStr
.setTo(tmp
);
1233 if (dollarStr
!= resultStr
) {
1234 errln("Fail: en_US_Q didn't fallback to en_US");
1236 int32_t invalidLen
= ucurr_forLocale("en_QQ", tmp
, 4, &status
);
1237 if (invalidLen
|| U_SUCCESS(status
)) {
1238 errln("Fail: en_QQ didn't return NULL");
1246 * toString() doesn't work with language_VARIANT.
1249 LocaleTest::TestToString() {
1251 Locale("xx", "", ""),
1252 Locale("", "YY", ""),
1253 Locale("", "", "ZZ"),
1254 Locale("xx", "YY", ""),
1255 Locale("xx", "", "ZZ"),
1256 Locale("", "YY", "ZZ"),
1257 Locale("xx", "YY", "ZZ"),
1260 const char DATA_S
[][20] = {
1270 for (int32_t i
=0; i
< 7; ++i
) {
1272 name
= DATA
[i
].getName();
1274 if (strcmp(name
, DATA_S
[i
]) != 0)
1276 errln("Fail: Locale.getName(), got:" + UnicodeString(name
) + ", expected: " + DATA_S
[i
]);
1279 logln("Pass: Locale.getName(), got:" + UnicodeString(name
) );
1283 #if !UCONFIG_NO_FORMATTING
1287 * Couldn't reproduce this bug -- probably was fixed earlier.
1289 * ORIGINAL BUG REPORT:
1290 * -- basically, hungarian for monday shouldn't have an \u00f4
1291 * (o circumflex)in it instead it should be an o with 2 inclined
1292 * (right) lines over it..
1294 * You may wonder -- why do all this -- why not just add a line to
1295 * LocaleData? Well, I could see by inspection that the locale file had the
1296 * right character in it, so I wanted to check the rest of the pipeline -- a
1297 * very remote possibility, but I wanted to be sure. The other possibility
1298 * is that something is wrong with the font mapping subsystem, but we can't
1302 LocaleTest::Test4139940()
1304 Locale
mylocale("hu", "", "");
1305 UDate mydate
= date(98,3,13); // A Monday
1306 UErrorCode status
= U_ZERO_ERROR
;
1307 SimpleDateFormat
df_full("EEEE", mylocale
, status
);
1309 FieldPosition
pos(FieldPosition::DONT_CARE
);
1310 df_full
.format(mydate
, str
, pos
);
1311 // Make sure that o circumflex (\u00F4) is NOT there, and
1312 // o double acute (\u0151) IS.
1315 if (str
.indexOf(oda
) < 0 || str
.indexOf(ocf
) >= 0) {
1316 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
1317 str
.indexOf(oda
), str
.indexOf(ocf
));
1318 logln(UnicodeString("String is: ") + str
);
1323 LocaleTest::date(int32_t y
, int32_t m
, int32_t d
, int32_t hr
, int32_t min
, int32_t sec
)
1325 UErrorCode status
= U_ZERO_ERROR
;
1326 Calendar
*cal
= Calendar::createInstance(status
);
1330 cal
->set(1900 + y
, m
, d
, hr
, min
, sec
); // Add 1900 to follow java.util.Date protocol
1331 UDate dt
= cal
->getTime(status
);
1332 if (U_FAILURE(status
))
1341 * Russian first day of week should be Monday. Confirmed.
1344 LocaleTest::Test4143951()
1346 UErrorCode status
= U_ZERO_ERROR
;
1347 Calendar
*cal
= Calendar::createInstance(Locale("ru", "", ""), status
);
1348 if(U_SUCCESS(status
)) {
1349 if (cal
->getFirstDayOfWeek(status
) != UCAL_MONDAY
) {
1350 errln("Fail: First day of week in Russia should be Monday");
1360 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes.
1361 * Should throw an exception for unknown locales
1364 LocaleTest::Test4147315()
1367 // Try with codes that are the wrong length but happen to match text
1368 // at a valid offset in the mapping table
1369 Locale
locale("aaa", "CCC");
1371 const char *result
= locale
.getISO3Country();
1373 // Change to conform to C api usage
1374 if((result
==NULL
)||(result
[0] != 0))
1375 errln("ERROR: getISO3Country() returns: " + UnicodeString(result
,"") +
1376 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1381 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
1382 * Should throw an exception for unknown locales
1385 LocaleTest::Test4147317()
1388 // Try with codes that are the wrong length but happen to match text
1389 // at a valid offset in the mapping table
1390 Locale
locale("aaa", "CCC");
1392 const char *result
= locale
.getISO3Language();
1394 // Change to conform to C api usage
1395 if((result
==NULL
)||(result
[0] != 0))
1396 errln("ERROR: getISO3Language() returns: " + UnicodeString(result
,"") +
1397 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1404 LocaleTest::Test4147552()
1406 Locale locales
[] = { Locale("no", "NO"),
1407 Locale("no", "NO", "B"),
1408 Locale("no", "NO", "NY")
1411 UnicodeString
edn("Norwegian (Norway, B)");
1412 UnicodeString englishDisplayNames
[] = {
1413 "Norwegian (Norway)",
1415 // "Norwegian (Norway,B)",
1416 //"Norwegian (Norway,NY)"
1417 "Norwegian (Norway, NY)"
1419 UnicodeString
ndn("norsk (Norge, B");
1420 UnicodeString norwegianDisplayNames
[] = {
1425 //"Norsk (Noreg, Nynorsk)"
1428 for (int32_t i
= 0; i
< 3; ++i
) {
1429 Locale loc
= locales
[i
];
1431 if (loc
.getDisplayName(temp
) != englishDisplayNames
[i
])
1432 errln("English display-name mismatch: expected " +
1433 englishDisplayNames
[i
] + ", got " + loc
.getDisplayName(temp
));
1434 if (loc
.getDisplayName(loc
, temp
) != norwegianDisplayNames
[i
])
1435 errln("Norwegian display-name mismatch: expected " +
1436 norwegianDisplayNames
[i
] + ", got " +
1437 loc
.getDisplayName(loc
, temp
));
1442 LocaleTest::TestVariantParsing()
1444 Locale
en_US_custom("en", "US", "De Anza_Cupertino_California_United States_Earth");
1446 UnicodeString
dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)");
1447 UnicodeString
dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH");
1451 en_US_custom
.getDisplayVariant(Locale::getUS(), got
);
1452 if(got
!= dispVar
) {
1453 errln("FAIL: getDisplayVariant()");
1454 errln("Wanted: " + dispVar
);
1455 errln("Got : " + got
);
1458 en_US_custom
.getDisplayName(Locale::getUS(), got
);
1459 if(got
!= dispName
) {
1460 errln("FAIL: getDisplayName()");
1461 errln("Wanted: " + dispName
);
1462 errln("Got : " + got
);
1465 Locale
shortVariant("fr", "FR", "foo");
1466 shortVariant
.getDisplayVariant(got
);
1469 errln("FAIL: getDisplayVariant()");
1470 errln("Wanted: foo");
1471 errln("Got : " + got
);
1474 Locale
bogusVariant("fr", "FR", "_foo");
1475 bogusVariant
.getDisplayVariant(got
);
1478 errln("FAIL: getDisplayVariant()");
1479 errln("Wanted: foo");
1480 errln("Got : " + got
);
1483 Locale
bogusVariant2("fr", "FR", "foo_");
1484 bogusVariant2
.getDisplayVariant(got
);
1487 errln("FAIL: getDisplayVariant()");
1488 errln("Wanted: foo");
1489 errln("Got : " + got
);
1492 Locale
bogusVariant3("fr", "FR", "_foo_");
1493 bogusVariant3
.getDisplayVariant(got
);
1496 errln("FAIL: getDisplayVariant()");
1497 errln("Wanted: foo");
1498 errln("Got : " + got
);
1502 #if !UCONFIG_NO_FORMATTING
1506 * Currency symbol in zh is wrong. We will test this at the NumberFormat
1507 * end to test the whole pipe.
1510 LocaleTest::Test4105828()
1512 Locale LOC
[] = { Locale::getChinese(), Locale("zh", "CN", ""),
1513 Locale("zh", "TW", ""), Locale("zh", "HK", "") };
1514 UErrorCode status
= U_ZERO_ERROR
;
1515 for (int32_t i
= 0; i
< 4; ++i
) {
1516 NumberFormat
*fmt
= NumberFormat::createPercentInstance(LOC
[i
], status
);
1517 if(U_FAILURE(status
)) {
1518 errln("Couldn't create NumberFormat");
1521 UnicodeString result
;
1522 FieldPosition
pos(0);
1523 fmt
->format((int32_t)1, result
, pos
);
1525 if(result
!= "100%") {
1526 errln(UnicodeString("Percent for ") + LOC
[i
].getDisplayName(temp
) + " should be 100%, got " + result
);
1534 // Tests setBogus and isBogus APIs for Locale
1537 LocaleTest::TestSetIsBogus() {
1540 if(l
.isBogus() != TRUE
) {
1541 errln("After setting bogus, didn't return TRUE");
1543 l
= "en_US"; // This should reset bogus
1544 if(l
.isBogus() != FALSE
) {
1545 errln("After resetting bogus, didn't return FALSE");
1551 LocaleTest::TestKeywordVariants(void) {
1553 const char *localeID
;
1554 const char *expectedLocaleID
;
1555 //const char *expectedLocaleIDNoKeywords;
1556 //const char *expectedCanonicalID;
1557 const char *expectedKeywords
[10];
1558 int32_t numKeywords
;
1559 UErrorCode expectedStatus
;
1562 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1563 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1565 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1566 {"calendar", "collation", "currency"},
1574 //"de_DE@currency=EUR",
1575 {"","","","","","",""},
1577 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1580 UErrorCode status
= U_ZERO_ERROR
;
1582 int32_t i
= 0, j
= 0;
1583 const char *result
= NULL
;
1584 StringEnumeration
*keywords
;
1585 int32_t keyCount
= 0;
1586 const char *keyword
= NULL
;
1587 const UnicodeString
*keywordString
;
1588 int32_t keywordLen
= 0;
1590 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1591 status
= U_ZERO_ERROR
;
1592 Locale
l(testCases
[i
].localeID
);
1593 keywords
= l
.createKeywords(status
);
1595 if(status
!= testCases
[i
].expectedStatus
) {
1596 err("Expected to get status %s. Got %s instead\n",
1597 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1599 status
= U_ZERO_ERROR
;
1601 if((keyCount
= keywords
->count(status
)) != testCases
[i
].numKeywords
) {
1602 err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1607 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1610 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1611 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1614 if((keywordString
= keywords
->snext(status
)) == NULL
) {
1617 if(*keywordString
!= UnicodeString(testCases
[i
].expectedKeywords
[j
], "")) {
1618 err("Expected to get keyword UnicodeString %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1623 if(j
== keyCount
/ 2) {
1624 // replace keywords with a clone of itself
1625 StringEnumeration
*k2
= keywords
->clone();
1626 if(k2
== NULL
|| keyCount
!= k2
->count(status
)) {
1627 errln("KeywordEnumeration.clone() failed");
1637 result
= l
.getName();
1638 if(uprv_strcmp(testCases
[i
].expectedLocaleID
, result
) != 0) {
1639 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n",
1640 testCases
[i
].expectedLocaleID
, testCases
[i
].localeID
, result
);
1648 LocaleTest::TestKeywordVariantParsing(void) {
1650 const char *localeID
;
1651 const char *keyword
;
1652 const char *expectedValue
;
1654 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook" },
1655 { "de_DE", "collation", ""},
1656 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" },
1657 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation", "PHONEBOOk" },
1660 UErrorCode status
= U_ZERO_ERROR
;
1663 int32_t resultLen
= 0;
1666 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1668 Locale
l(testCases
[i
].localeID
);
1669 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1670 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1671 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1672 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1678 LocaleTest::TestGetBaseName(void) {
1680 const char *localeID
;
1681 const char *baseName
;
1683 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
1684 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
1685 { "ja@calendar = buddhist", "ja" }
1690 for(i
= 0; i
< (int32_t)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
1691 Locale
loc(testCases
[i
].localeID
);
1692 if(strcmp(testCases
[i
].baseName
, loc
.getBaseName())) {
1693 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
1694 testCases
[i
].localeID
, testCases
[i
].baseName
, loc
.getBaseName());
1701 * Compare two locale IDs. If they are equal, return 0. If `string'
1702 * starts with `prefix' plus an additional element, that is, string ==
1703 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
1705 static UBool
_loccmp(const char* string
, const char* prefix
) {
1706 int32_t slen
= (int32_t)strlen(string
),
1707 plen
= (int32_t)strlen(prefix
);
1708 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
1709 /* 'root' is "less than" everything */
1710 if (uprv_strcmp(prefix
, "root") == 0) {
1711 return (uprv_strcmp(string
, "root") == 0) ? 0 : 1;
1713 if (c
) return -1; /* mismatch */
1714 if (slen
== plen
) return 0;
1715 if (string
[plen
] == '_') return 1;
1716 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
1720 * Check the relationship between requested locales, and report problems.
1721 * The caller specifies the expected relationships between requested
1722 * and valid (expReqValid) and between valid and actual (expValidActual).
1723 * Possible values are:
1724 * "gt" strictly greater than, e.g., en_US > en
1725 * "ge" greater or equal, e.g., en >= en
1726 * "eq" equal, e.g., en == en
1728 void LocaleTest::_checklocs(const char* label
,
1730 const Locale
& validLoc
,
1731 const Locale
& actualLoc
,
1732 const char* expReqValid
,
1733 const char* expValidActual
) {
1734 const char* valid
= validLoc
.getName();
1735 const char* actual
= actualLoc
.getName();
1736 int32_t reqValid
= _loccmp(req
, valid
);
1737 int32_t validActual
= _loccmp(valid
, actual
);
1738 if (((0 == uprv_strcmp(expReqValid
, "gt") && reqValid
> 0) ||
1739 (0 == uprv_strcmp(expReqValid
, "ge") && reqValid
>= 0) ||
1740 (0 == uprv_strcmp(expReqValid
, "eq") && reqValid
== 0)) &&
1741 ((0 == uprv_strcmp(expValidActual
, "gt") && validActual
> 0) ||
1742 (0 == uprv_strcmp(expValidActual
, "ge") && validActual
>= 0) ||
1743 (0 == uprv_strcmp(expValidActual
, "eq") && validActual
== 0))) {
1744 logln("%s; req=%s, valid=%s, actual=%s",
1745 label
, req
, valid
, actual
);
1747 errln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
1748 label
, req
, valid
, actual
,
1749 expReqValid
, expValidActual
);
1753 void LocaleTest::TestGetLocale(void) {
1754 #if !UCONFIG_NO_SERVICE
1755 UErrorCode ec
= U_ZERO_ERROR
;
1757 Locale valid
, actual
, reqLoc
;
1760 #if !UCONFIG_NO_FORMATTING
1761 req
= "en_US_BROOKLYN";
1762 Calendar
* cal
= Calendar::createInstance(Locale::createFromName(req
), ec
);
1763 if (U_FAILURE(ec
)) {
1764 errln("FAIL: Calendar::createInstance failed");
1766 valid
= cal
->getLocale(ULOC_VALID_LOCALE
, ec
);
1767 actual
= cal
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1768 if (U_FAILURE(ec
)) {
1769 errln("FAIL: Calendar::getLocale() failed");
1771 _checklocs("Calendar", req
, valid
, actual
);
1777 // DecimalFormat, DecimalFormatSymbols
1778 #if !UCONFIG_NO_FORMATTING
1780 DecimalFormat
* dec
= (DecimalFormat
*)
1781 NumberFormat::createInstance(Locale::createFromName(req
), ec
);
1782 U_ASSERT(dec
->getDynamicClassID() == DecimalFormat::getStaticClassID());
1783 if (U_FAILURE(ec
)) {
1784 errln("FAIL: NumberFormat::createInstance failed");
1786 valid
= dec
->getLocale(ULOC_VALID_LOCALE
, ec
);
1787 actual
= dec
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1788 if (U_FAILURE(ec
)) {
1789 errln("FAIL: DecimalFormat::getLocale() failed");
1791 _checklocs("DecimalFormat", req
, valid
, actual
);
1794 const DecimalFormatSymbols
* sym
= dec
->getDecimalFormatSymbols();
1796 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1797 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1798 if (U_FAILURE(ec
)) {
1799 errln("FAIL: DecimalFormatSymbols::getLocale() failed");
1801 _checklocs("DecimalFormatSymbols", req
, valid
, actual
);
1807 // DateFormat, DateFormatSymbols
1808 #if !UCONFIG_NO_FORMATTING
1809 req
= "de_CH_LUCERNE";
1810 SimpleDateFormat
* dat
= (SimpleDateFormat
*)
1811 DateFormat::createDateInstance(DateFormat::kDefault
,
1812 Locale::createFromName(req
));
1814 U_ASSERT(dat
->getDynamicClassID() == SimpleDateFormat::getStaticClassID());
1815 valid
= dat
->getLocale(ULOC_VALID_LOCALE
, ec
);
1816 actual
= dat
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1817 if (U_FAILURE(ec
)) {
1818 errln("FAIL: SimpleDateFormat::getLocale() failed");
1820 _checklocs("SimpleDateFormat", req
, valid
, actual
);
1823 const DateFormatSymbols
* sym
= dat
->getDateFormatSymbols();
1825 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
1826 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1827 if (U_FAILURE(ec
)) {
1828 errln("FAIL: DateFormatSymbols::getLocale() failed");
1830 _checklocs("DateFormatSymbols", req
, valid
, actual
);
1836 #if !UCONFIG_NO_BREAK_ITERATION
1837 req
= "es_ES_BARCELONA";
1838 reqLoc
= Locale::createFromName(req
);
1839 BreakIterator
* brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1840 if (U_FAILURE(ec
)) {
1841 errln("FAIL: BreakIterator::createWordInstance failed");
1843 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1844 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1845 if (U_FAILURE(ec
)) {
1846 errln("FAIL: BreakIterator::getLocale() failed");
1848 _checklocs("BreakIterator", req
, valid
, actual
);
1851 // After registering something, the behavior should be different
1852 URegistryKey key
= BreakIterator::registerInstance(brk
, reqLoc
, UBRK_WORD
, ec
);
1853 brk
= 0; // registerInstance adopts
1854 if (U_FAILURE(ec
)) {
1855 errln("FAIL: BreakIterator::registerInstance() failed");
1857 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1858 if (U_FAILURE(ec
)) {
1859 errln("FAIL: BreakIterator::createWordInstance failed");
1861 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1862 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1863 if (U_FAILURE(ec
)) {
1864 errln("FAIL: BreakIterator::getLocale() failed");
1866 // N.B.: now expect valid==actual==req
1867 _checklocs("BreakIterator(registered)",
1868 req
, valid
, actual
, "eq", "eq");
1871 // No matter what, unregister
1872 BreakIterator::unregister(key
, ec
);
1873 if (U_FAILURE(ec
)) {
1874 errln("FAIL: BreakIterator::unregister() failed");
1880 // After unregistering, should behave normally again
1881 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
1882 if (U_FAILURE(ec
)) {
1883 errln("FAIL: BreakIterator::createWordInstance failed");
1885 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
1886 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1887 if (U_FAILURE(ec
)) {
1888 errln("FAIL: BreakIterator::getLocale() failed");
1890 _checklocs("BreakIterator(unregistered)", req
, valid
, actual
);
1898 #if !UCONFIG_NO_COLLATION
1899 req
= "hi_IN_BHOPAL";
1900 reqLoc
= Locale::createFromName(req
);
1901 Collator
* coll
= Collator::createInstance(reqLoc
, ec
);
1902 if (U_FAILURE(ec
)) {
1903 errln("FAIL: Collator::createInstance failed");
1905 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
1906 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1907 if (U_FAILURE(ec
)) {
1908 errln("FAIL: Collator::getLocale() failed");
1910 _checklocs("Collator", req
, valid
, actual
);
1913 // After registering something, the behavior should be different
1914 URegistryKey key
= Collator::registerInstance(coll
, reqLoc
, ec
);
1915 coll
= 0; // registerInstance adopts
1916 if (U_FAILURE(ec
)) {
1917 errln("FAIL: Collator::registerInstance() failed");
1919 coll
= Collator::createInstance(reqLoc
, ec
);
1920 if (U_FAILURE(ec
)) {
1921 errln("FAIL: Collator::createWordInstance failed");
1923 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
1924 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1925 if (U_FAILURE(ec
)) {
1926 errln("FAIL: Collator::getLocale() failed");
1928 // N.B.: now expect valid==actual==req
1929 _checklocs("Collator(registered)",
1930 req
, valid
, actual
, "eq", "eq");
1933 // No matter what, unregister
1934 Collator::unregister(key
, ec
);
1935 if (U_FAILURE(ec
)) {
1936 errln("FAIL: Collator::unregister() failed");
1942 // After unregistering, should behave normally again
1943 coll
= Collator::createInstance(reqLoc
, ec
);
1944 if (U_FAILURE(ec
)) {
1945 errln("FAIL: Collator::createInstance failed");
1947 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
1948 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
1949 if (U_FAILURE(ec
)) {
1950 errln("FAIL: Collator::getLocale() failed");
1952 _checklocs("Collator(unregistered)", req
, valid
, actual
);
1961 void LocaleTest::TestVariantWithOutCountry(void) {
1962 Locale
loc("en","","POSIX");
1963 if (0 != strcmp(loc
.getVariant(), "POSIX")) {
1964 errln("FAIL: en__POSIX didn't get parsed correctly");
1966 Locale
loc2("en","","FOUR");
1967 if (0 != strcmp(loc2
.getVariant(), "FOUR")) {
1968 errln("FAIL: en__FOUR didn't get parsed correctly");
1970 Locale
loc3("en","Latn","","FOUR");
1971 if (0 != strcmp(loc3
.getVariant(), "FOUR")) {
1972 errln("FAIL: en_Latn__FOUR didn't get parsed correctly");
1974 Locale
loc4("","Latn","","FOUR");
1975 if (0 != strcmp(loc4
.getVariant(), "FOUR")) {
1976 errln("FAIL: _Latn__FOUR didn't get parsed correctly");
1978 Locale
loc5("","Latn","US","FOUR");
1979 if (0 != strcmp(loc5
.getVariant(), "FOUR")) {
1980 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly");
1984 static Locale
_canonicalize(int32_t selector
, /* 0==createFromName, 1==createCanonical, 2==Locale ct */
1985 const char* localeID
) {
1988 return Locale::createFromName(localeID
);
1990 return Locale::createCanonical(localeID
);
1992 return Locale(localeID
);
1998 void LocaleTest::TestCanonicalization(void)
2001 const char *localeID
; /* input */
2002 const char *getNameID
; /* expected getName() result */
2003 const char *canonicalID
; /* expected canonicalize() result */
2005 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2006 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2007 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2008 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" },
2009 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" },
2010 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" },
2011 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" },
2012 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" },
2013 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" },
2014 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" },
2015 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" },
2016 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" },
2017 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" },
2018 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" },
2019 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" },
2020 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" },
2021 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" },
2022 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" },
2023 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" },
2024 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" },
2025 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" },
2026 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" },
2027 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" },
2028 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" },
2029 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */
2030 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" },
2031 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" },
2032 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" },
2033 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" },
2034 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" },
2035 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" },
2036 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2037 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2038 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2039 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2040 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2041 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2042 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2043 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2044 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses private use iso codes */
2045 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
2046 // TODO: unify this behavior
2047 { "en-BOONT", "BOGUS", "en__BOONT" }, /* registered name */
2048 { "de-1901", "de_1901", "de__1901" }, /* registered name */
2049 { "de-1906", "de_1906", "de__1906" }, /* registered name */
2050 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_SP" }, /* .NET name */
2051 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_SP" }, /* .NET name */
2052 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */
2053 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */
2054 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */
2055 { "zh-CHT", "zh_CHT", "zh_TW" }, /* .NET name This may change back to zh_Hant */
2057 /* posix behavior that used to be performed by getName */
2058 { "mr.utf8", "mr.utf8", "mr" },
2059 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2060 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2061 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2062 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2063 { "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 */
2065 /* fleshing out canonicalization */
2066 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2067 { "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" },
2068 /* already-canonical ids are not changed */
2069 { "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" },
2070 /* PRE_EURO and EURO conversions don't affect other keywords */
2071 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES@calendar=Japanese;currency=ESP" },
2072 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES@currency=EUR;shout=zipeedeedoodah" },
2073 /* currency keyword overrides PRE_EURO and EURO currency */
2074 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@currency=EUR" },
2075 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=ESP" },
2076 /* norwegian is just too weird, if we handle things in their full generality */
2077 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2079 /* test cases reflecting internal resource bundle usage */
2080 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2081 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2082 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" }
2085 static const char* label
[] = { "createFromName", "createCanonical", "Locale" };
2089 for (i
=0; i
< (int)(sizeof(testCases
)/sizeof(testCases
[0])); i
++) {
2090 for (j
=0; j
<3; ++j
) {
2091 const char* expected
= (j
==1) ? testCases
[i
].canonicalID
: testCases
[i
].getNameID
;
2092 Locale loc
= _canonicalize(j
, testCases
[i
].localeID
);
2093 const char* getName
= loc
.isBogus() ? "BOGUS" : loc
.getName();
2094 if(uprv_strcmp(expected
, getName
) != 0) {
2095 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"",
2096 label
[j
], testCases
[i
].localeID
, getName
, expected
);
2098 logln("Ok: %s(%s) => \"%s\"",
2099 label
[j
], testCases
[i
].localeID
, getName
);