1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
14 #include "unicode/localebuilder.h"
15 #include "unicode/localpointer.h"
16 #include "unicode/decimfmt.h"
17 #include "unicode/ucurr.h"
18 #include "unicode/smpdtfmt.h"
19 #include "unicode/strenum.h"
20 #include "unicode/dtfmtsym.h"
21 #include "unicode/brkiter.h"
22 #include "unicode/coll.h"
23 #include "unicode/ustring.h"
24 #include "unicode/std_string.h"
34 static const char* const rawData
[33][8] = {
37 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
39 { "", "", "", "", "", "", "", "Hans" },
41 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" },
43 { "", "", "", "", "NY", "", "", "" },
45 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" },
47 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" },
49 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" },
51 { "409", "40c", "403", "408", "814", "10", "0", "804" },
53 // display language (English)
54 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" },
55 // display script (English)
56 { "", "", "", "", "", "", "", "Simplified Han" },
57 // display country (English)
58 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China mainland" },
59 // display variant (English)
60 { "", "", "", "", "NY", "", "", ""},
61 // display name (English)
62 // Updated no_NO_NY English display name for new pattern-based algorithm
63 // (part of Euro support).
64 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese, Simplified (China mainland)" },
66 // display language (French)
67 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
68 // display script (French)
69 { "", "", "", "", "", "", "", "sinogrammes simplifi\\u00E9s" },
70 // display country (French)
71 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine continentale" },
72 // display variant (French)
73 { "", "", "", "", "NY", "", "", "" },
74 // display name (French)
75 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
76 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois simplifi\\u00E9 (Chine continentale)" },
79 /* display language (Catalan) */
80 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E8s" },
81 /* display script (Catalan) */
82 { "", "", "", "", "", "", "", "han simplificat" },
83 /* display country (Catalan) */
84 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina continental" },
85 /* display variant (Catalan) */
86 { "", "", "", "", "NY", "", "" },
87 /* display name (Catalan) */
88 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E8s simplificat (Xina continental)" },
90 // display language (Greek)[actual values listed below]
91 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
92 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
93 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
94 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
95 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
96 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
98 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
100 // display script (Greek)
101 { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd" },
102 // display country (Greek)[actual values listed below]
103 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
104 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
105 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
106 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
107 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
110 "\\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE"
112 // display variant (Greek)
113 { "", "", "", "", "NY", "", "" },
114 // display name (Greek)[actual values listed below]
115 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
116 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
117 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
118 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
119 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
120 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
122 "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1 \\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE)"
125 // display language (<root>)
126 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" },
127 // display script (<root>)
128 { "", "", "", "", "", "", "", ""},
129 // display country (<root>)
130 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" },
131 // display variant (<root>)
132 { "", "", "", "", "Nynorsk", "", "", ""},
133 // display name (<root>)
134 //{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" },
135 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
141 test_assert( Test (should be TRUE) )
146 the macro is ugly but makes the tests pretty.
149 #define test_assert(test) \
152 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \
154 logln("PASS: asserted " #test); \
159 test_assert_print( Test (should be TRUE), printable )
162 test_assert(i==3, toString(i));
164 the macro is ugly but makes the tests pretty.
167 #define test_assert_print(test,print) \
170 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \
172 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \
176 #define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); }
178 LocaleTest::LocaleTest()
184 LocaleTest::~LocaleTest()
186 if (dataTable
!= 0) {
187 for (int32_t i
= 0; i
< 33; i
++) {
188 delete []dataTable
[i
];
195 void LocaleTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
198 TESTCASE_AUTO(TestBug11421
); // Must run early in list to trigger failure.
199 TESTCASE_AUTO(TestBasicGetters
);
200 TESTCASE_AUTO(TestSimpleResourceInfo
);
201 TESTCASE_AUTO(TestDisplayNames
);
202 TESTCASE_AUTO(TestSimpleObjectStuff
);
203 TESTCASE_AUTO(TestPOSIXParsing
);
204 TESTCASE_AUTO(TestGetAvailableLocales
);
205 TESTCASE_AUTO(TestDataDirectory
);
206 TESTCASE_AUTO(TestISO3Fallback
);
207 TESTCASE_AUTO(TestGetLangsAndCountries
);
208 TESTCASE_AUTO(TestSimpleDisplayNames
);
209 TESTCASE_AUTO(TestUninstalledISO3Names
);
210 TESTCASE_AUTO(TestAtypicalLocales
);
211 #if !UCONFIG_NO_FORMATTING
212 TESTCASE_AUTO(TestThaiCurrencyFormat
);
213 TESTCASE_AUTO(TestEuroSupport
);
215 TESTCASE_AUTO(TestToString
);
216 #if !UCONFIG_NO_FORMATTING
217 TESTCASE_AUTO(Test4139940
);
218 TESTCASE_AUTO(Test4143951
);
220 TESTCASE_AUTO(Test4147315
);
221 TESTCASE_AUTO(Test4147317
);
222 TESTCASE_AUTO(Test4147552
);
223 TESTCASE_AUTO(TestVariantParsing
);
224 #if !UCONFIG_NO_FORMATTING
225 TESTCASE_AUTO(Test4105828
);
227 TESTCASE_AUTO(TestSetIsBogus
);
228 TESTCASE_AUTO(TestParallelAPIValues
);
229 TESTCASE_AUTO(TestAddLikelySubtags
);
230 TESTCASE_AUTO(TestMinimizeSubtags
);
231 TESTCASE_AUTO(TestAddLikelyAndMinimizeSubtags
);
232 TESTCASE_AUTO(TestKeywordVariants
);
233 TESTCASE_AUTO(TestCreateUnicodeKeywords
);
234 TESTCASE_AUTO(TestKeywordVariantParsing
);
235 TESTCASE_AUTO(TestCreateKeywordSet
);
236 TESTCASE_AUTO(TestCreateUnicodeKeywordSet
);
237 TESTCASE_AUTO(TestGetKeywordValueStdString
);
238 TESTCASE_AUTO(TestGetUnicodeKeywordValueStdString
);
239 TESTCASE_AUTO(TestSetKeywordValue
);
240 TESTCASE_AUTO(TestSetKeywordValueStringPiece
);
241 TESTCASE_AUTO(TestSetUnicodeKeywordValueStringPiece
);
242 TESTCASE_AUTO(TestGetBaseName
);
243 #if !UCONFIG_NO_FILE_IO
244 TESTCASE_AUTO(TestGetLocale
);
246 TESTCASE_AUTO(TestVariantWithOutCountry
);
247 TESTCASE_AUTO(TestCanonicalization
);
248 TESTCASE_AUTO(TestCurrencyByDate
);
249 TESTCASE_AUTO(TestGetVariantWithKeywords
);
250 TESTCASE_AUTO(TestIsRightToLeft
);
251 TESTCASE_AUTO(TestBug13277
);
252 TESTCASE_AUTO(TestBug13554
);
253 TESTCASE_AUTO(TestBug20410
);
254 TESTCASE_AUTO(TestForLanguageTag
);
255 TESTCASE_AUTO(TestToLanguageTag
);
256 TESTCASE_AUTO(TestMoveAssign
);
257 TESTCASE_AUTO(TestMoveCtor
);
258 TESTCASE_AUTO(TestBug20407iVariantPreferredValue
);
259 TESTCASE_AUTO(TestBug13417VeryLongLanguageTag
);
260 TESTCASE_AUTO(TestBug11053UnderlineTimeZone
);
261 TESTCASE_AUTO(TestUnd
);
262 TESTCASE_AUTO(TestUndScript
);
263 TESTCASE_AUTO(TestUndRegion
);
264 TESTCASE_AUTO(TestUndCAPI
);
268 void LocaleTest::TestBasicGetters() {
272 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
273 Locale
testLocale("");
274 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
275 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
278 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
280 logln("Testing " + (UnicodeString
)testLocale
.getName() + "...");
282 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
283 errln(" Language code mismatch: " + temp
+ " versus "
284 + dataTable
[LANG
][i
]);
285 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
286 errln(" Script code mismatch: " + temp
+ " versus "
287 + dataTable
[SCRIPT
][i
]);
288 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
289 errln(" Country code mismatch: " + temp
+ " versus "
290 + dataTable
[CTRY
][i
]);
291 if ( (temp
=testLocale
.getVariant()) != (dataTable
[VAR
][i
]))
292 errln(" Variant code mismatch: " + temp
+ " versus "
293 + dataTable
[VAR
][i
]);
294 if ( (temp
=testLocale
.getName()) != (dataTable
[NAME
][i
]))
295 errln(" Locale name mismatch: " + temp
+ " versus "
296 + dataTable
[NAME
][i
]);
299 logln("Same thing without variant codes...");
300 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
301 Locale
testLocale("");
302 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
303 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
]);
306 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
]);
308 logln("Testing " + (temp
=testLocale
.getName()) + "...");
310 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
311 errln("Language code mismatch: " + temp
+ " versus "
312 + dataTable
[LANG
][i
]);
313 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
314 errln("Script code mismatch: " + temp
+ " versus "
315 + dataTable
[SCRIPT
][i
]);
316 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
317 errln("Country code mismatch: " + temp
+ " versus "
318 + dataTable
[CTRY
][i
]);
319 if (testLocale
.getVariant()[0] != 0)
320 errln("Variant code mismatch: something versus \"\"");
323 logln("Testing long language names and getters");
324 Locale test8
= Locale::createFromName("x-klingon-latn-zx.utf32be@special");
326 temp
= test8
.getLanguage();
327 if (temp
!= UnicodeString("x-klingon") )
328 errln("Language code mismatch: " + temp
+ " versus \"x-klingon\"");
330 temp
= test8
.getScript();
331 if (temp
!= UnicodeString("Latn") )
332 errln("Script code mismatch: " + temp
+ " versus \"Latn\"");
334 temp
= test8
.getCountry();
335 if (temp
!= UnicodeString("ZX") )
336 errln("Country code mismatch: " + temp
+ " versus \"ZX\"");
338 temp
= test8
.getVariant();
339 //if (temp != UnicodeString("SPECIAL") )
340 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\"");
341 // As of 3.0, the "@special" will *not* be parsed by uloc_getName()
342 if (temp
!= UnicodeString("") )
343 errln("Variant code mismatch: " + temp
+ " versus \"\"");
345 if (Locale::getDefault() != Locale::createFromName(NULL
))
346 errln("Locale::getDefault() == Locale::createFromName(NULL)");
349 // NOTE: There used to be a special test for locale names that had language or
350 // country codes that were longer than two letters. The new version of Locale
351 // doesn't support anything that isn't an officially recognized language or
352 // country code, so we no longer support this feature.
354 Locale
bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code too long
355 if(!bogusLang
.isBogus()) {
356 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE");
359 bogusLang
=Locale("eo");
360 if( bogusLang
.isBogus() ||
361 strcmp(bogusLang
.getLanguage(), "eo")!=0 ||
362 *bogusLang
.getCountry()!=0 ||
363 *bogusLang
.getVariant()!=0 ||
364 strcmp(bogusLang
.getName(), "eo")!=0
366 errln("assignment to bogus Locale does not unbogus it or sets bad data");
369 Locale
a("eo_DE@currency=DEM");
370 Locale
*pb
=a
.clone();
371 if(pb
==&a
|| *pb
!=a
) {
372 errln("Locale.clone() failed");
377 void LocaleTest::TestParallelAPIValues() {
378 logln("Test synchronization between C and C++ API");
379 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE
) != 0) {
380 errln("Differences for ULOC_CHINESE Locale");
382 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH
) != 0) {
383 errln("Differences for ULOC_ENGLISH Locale");
385 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH
) != 0) {
386 errln("Differences for ULOC_FRENCH Locale");
388 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN
) != 0) {
389 errln("Differences for ULOC_GERMAN Locale");
391 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN
) != 0) {
392 errln("Differences for ULOC_ITALIAN Locale");
394 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE
) != 0) {
395 errln("Differences for ULOC_JAPANESE Locale");
397 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN
) != 0) {
398 errln("Differences for ULOC_KOREAN Locale");
400 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE
) != 0) {
401 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale");
403 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINESE
) != 0) {
404 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale");
408 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA
) != 0) {
409 errln("Differences for ULOC_CANADA Locale");
411 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH
) != 0) {
412 errln("Differences for ULOC_CANADA_FRENCH Locale");
414 if (strcmp(Locale::getChina().getName(), ULOC_CHINA
) != 0) {
415 errln("Differences for ULOC_CHINA Locale");
417 if (strcmp(Locale::getPRC().getName(), ULOC_PRC
) != 0) {
418 errln("Differences for ULOC_PRC Locale");
420 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE
) != 0) {
421 errln("Differences for ULOC_FRANCE Locale");
423 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY
) != 0) {
424 errln("Differences for ULOC_GERMANY Locale");
426 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY
) != 0) {
427 errln("Differences for ULOC_ITALY Locale");
429 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN
) != 0) {
430 errln("Differences for ULOC_JAPAN Locale");
432 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA
) != 0) {
433 errln("Differences for ULOC_KOREA Locale");
435 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN
) != 0) {
436 errln("Differences for ULOC_TAIWAN Locale");
438 if (strcmp(Locale::getUK().getName(), ULOC_UK
) != 0) {
439 errln("Differences for ULOC_UK Locale");
441 if (strcmp(Locale::getUS().getName(), ULOC_US
) != 0) {
442 errln("Differences for ULOC_US Locale");
447 void LocaleTest::TestSimpleResourceInfo() {
450 UErrorCode err
= U_ZERO_ERROR
;
453 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
454 Locale
testLocale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
455 logln("Testing " + (temp
=testLocale
.getName()) + "...");
457 if ( (temp
=testLocale
.getISO3Language()) != (dataTable
[LANG3
][i
]))
458 errln(" ISO-3 language code mismatch: " + temp
459 + " versus " + dataTable
[LANG3
][i
]);
460 if ( (temp
=testLocale
.getISO3Country()) != (dataTable
[CTRY3
][i
]))
461 errln(" ISO-3 country code mismatch: " + temp
462 + " versus " + dataTable
[CTRY3
][i
]);
464 sprintf(temp2
, "%x", (int)testLocale
.getLCID());
465 if (UnicodeString(temp2
) != dataTable
[LCID
][i
])
466 errln((UnicodeString
)" LCID mismatch: " + temp2
+ " versus "
467 + dataTable
[LCID
][i
]);
471 errln((UnicodeString
)"Some error on number " + i
+ u_errorName(err
));
477 if(strcmp(locale
.getName(), "en") != 0||
478 strcmp(locale
.getLanguage(), "en") != 0) {
479 errln("construction of Locale(en) failed\n");
486 * Jitterbug 2439 -- markus 20030425
488 * The lookup of display names must not fall back through the default
489 * locale because that yields useless results.
492 LocaleTest::TestDisplayNames()
494 Locale
english("en", "US");
495 Locale
french("fr", "FR");
496 Locale
croatian("ca", "ES");
497 Locale
greek("el", "GR");
499 logln(" In locale = en_US...");
500 doTestDisplayNames(english
, DLANG_EN
);
501 logln(" In locale = fr_FR...");
502 doTestDisplayNames(french
, DLANG_FR
);
503 logln(" In locale = ca_ES...");
504 doTestDisplayNames(croatian
, DLANG_CA
);
505 logln(" In locale = el_GR...");
506 doTestDisplayNames(greek
, DLANG_EL
);
509 UErrorCode status
= U_ZERO_ERROR
;
511 #if !UCONFIG_NO_FORMATTING
512 DecimalFormatSymbols
symb(status
);
513 /* Check to see if ICU supports this locale */
514 if (symb
.getLocale(ULOC_VALID_LOCALE
, status
) != Locale("root")) {
515 /* test that the default locale has a display name for its own language */
516 /* Currently, there is no language information in the "tl" data file so this test will fail if default locale is "tl" */
517 if (uprv_strcmp(Locale().getLanguage(), "tl") != 0) {
518 Locale().getDisplayLanguage(Locale(), s
);
519 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
520 /* check <=3 to reject getting the language code as a display name */
521 dataerrln("unable to get a display string for the language of the default locale: " + s
);
525 * API coverage improvements: call
526 * Locale::getDisplayLanguage(UnicodeString &) and
527 * Locale::getDisplayCountry(UnicodeString &)
530 Locale().getDisplayLanguage(s
);
531 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
532 dataerrln("unable to get a display string for the language of the default locale [2]: " + s
);
537 logln("Default locale %s is unsupported by ICU\n", Locale().getName());
542 french
.getDisplayCountry(s
);
544 errln("unable to get any default-locale display string for the country of fr_FR\n");
547 Locale("zh", "Hant").getDisplayScript(s
);
549 errln("unable to get any default-locale display string for the country of zh_Hant\n");
553 void LocaleTest::TestSimpleObjectStuff() {
554 Locale
test1("aa", "AA");
555 Locale
test2("aa", "AA");
557 Locale
test4("zz", "ZZ");
558 Locale
test5("aa", "AA", "");
559 Locale
test6("aa", "AA", "ANTARES");
560 Locale
test7("aa", "AA", "JUPITER");
561 Locale test8
= Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that
563 // now list them all for debugging usage.
564 test_dumpLocale(test1
);
565 test_dumpLocale(test2
);
566 test_dumpLocale(test3
);
567 test_dumpLocale(test4
);
568 test_dumpLocale(test5
);
569 test_dumpLocale(test6
);
570 test_dumpLocale(test7
);
571 test_dumpLocale(test8
);
573 // Make sure things compare to themselves!
574 test_assert(test1
== test1
);
575 test_assert(test2
== test2
);
576 test_assert(test3
== test3
);
577 test_assert(test4
== test4
);
578 test_assert(test5
== test5
);
579 test_assert(test6
== test6
);
580 test_assert(test7
== test7
);
581 test_assert(test8
== test8
);
583 // make sure things are not equal to themselves.
584 test_assert(!(test1
!= test1
));
585 test_assert(!(test2
!= test2
));
586 test_assert(!(test3
!= test3
));
587 test_assert(!(test4
!= test4
));
588 test_assert(!(test5
!= test5
));
589 test_assert(!(test6
!= test6
));
590 test_assert(!(test7
!= test7
));
591 test_assert(!(test8
!= test8
));
593 // make sure things that are equal to each other don't show up as unequal.
594 test_assert(!(test1
!= test2
));
595 test_assert(!(test2
!= test1
));
596 test_assert(!(test1
!= test3
));
597 test_assert(!(test2
!= test3
));
598 test_assert(test5
== test1
);
599 test_assert(test6
!= test2
);
600 test_assert(test6
!= test5
);
602 test_assert(test6
!= test7
);
604 // test for things that shouldn't compare equal.
605 test_assert(!(test1
== test4
));
606 test_assert(!(test2
== test4
));
607 test_assert(!(test3
== test4
));
609 test_assert(test7
== test8
);
611 // test for hash codes to be the same.
612 int32_t hash1
= test1
.hashCode();
613 int32_t hash2
= test2
.hashCode();
614 int32_t hash3
= test3
.hashCode();
616 test_assert(hash1
== hash2
);
617 test_assert(hash1
== hash3
);
618 test_assert(hash2
== hash3
);
620 // test that the assignment operator works.
622 logln("test4=test1;");
623 test_dumpLocale(test4
);
624 test_assert(test4
== test4
);
626 test_assert(!(test1
!= test4
));
627 test_assert(!(test2
!= test4
));
628 test_assert(!(test3
!= test4
));
629 test_assert(test1
== test4
);
630 test_assert(test4
== test1
);
632 // test assignments with a variant
633 logln("test7 = test6");
635 test_dumpLocale(test7
);
636 test_assert(test7
== test7
);
637 test_assert(test7
== test6
);
638 test_assert(test7
!= test5
);
640 logln("test6 = test1");
642 test_dumpLocale(test6
);
643 test_assert(test6
!= test7
);
644 test_assert(test6
== test1
);
645 test_assert(test6
== test6
);
648 // A class which exposes constructors that are implemented in terms of the POSIX parsing code.
649 class POSIXLocale
: public Locale
652 POSIXLocale(const UnicodeString
& l
)
656 ch
= new char[l
.length() + 1];
657 ch
[l
.extract(0, 0x7fffffff, ch
, "")] = 0;
661 POSIXLocale(const char *l
)
668 void LocaleTest::TestPOSIXParsing()
670 POSIXLocale
test1("ab_AB");
671 POSIXLocale
test2(UnicodeString("ab_AB"));
672 Locale
test3("ab","AB");
674 POSIXLocale
test4("ab_AB_Antares");
675 POSIXLocale
test5(UnicodeString("ab_AB_Antares"));
676 Locale
test6("ab", "AB", "Antares");
678 test_dumpLocale(test1
);
679 test_dumpLocale(test2
);
680 test_dumpLocale(test3
);
681 test_dumpLocale(test4
);
682 test_dumpLocale(test5
);
683 test_dumpLocale(test6
);
685 test_assert(test1
== test1
);
687 test_assert(test1
== test2
);
688 test_assert(test2
== test3
);
689 test_assert(test3
== test1
);
691 test_assert(test4
== test5
);
692 test_assert(test5
== test6
);
693 test_assert(test6
== test4
);
695 test_assert(test1
!= test4
);
696 test_assert(test5
!= test3
);
697 test_assert(test5
!= test2
);
699 int32_t hash1
= test1
.hashCode();
700 int32_t hash2
= test2
.hashCode();
701 int32_t hash3
= test3
.hashCode();
703 test_assert(hash1
== hash2
);
704 test_assert(hash2
== hash3
);
705 test_assert(hash3
== hash1
);
708 void LocaleTest::TestGetAvailableLocales()
710 int32_t locCount
= 0;
711 const Locale
* locList
= Locale::getAvailableLocales(locCount
);
714 dataerrln("getAvailableLocales() returned an empty list!");
716 logln(UnicodeString("Number of locales returned = ") + locCount
);
718 for(int32_t i
= 0; i
< locCount
; ++i
)
719 logln(locList
[i
].getName());
721 // I have no idea how to test this function...
724 // This test isn't applicable anymore - getISO3Language is
725 // independent of the data directory
726 void LocaleTest::TestDataDirectory()
729 char oldDirectory[80];
731 UErrorCode err = U_ZERO_ERROR;
732 UnicodeString testValue;
734 temp = Locale::getDataDirectory();
735 strcpy(oldDirectory, temp);
736 logln(UnicodeString("oldDirectory = ") + oldDirectory);
738 Locale test(Locale::US);
739 test.getISO3Language(testValue);
740 logln("first fetch of language retrieved " + testValue);
741 if (testValue != "eng")
742 errln("Initial check of ISO3 language failed: expected \"eng\", got \"" + testValue + "\"");
746 path=IntlTest::getTestDirectory();
747 Locale::setDataDirectory( path );
750 test.getISO3Language(testValue);
751 logln("second fetch of language retrieved " + testValue);
752 if (testValue != "xxx")
753 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue + "\"");
755 Locale::setDataDirectory(oldDirectory);
756 test.getISO3Language(testValue);
757 logln("third fetch of language retrieved " + testValue);
758 if (testValue != "eng")
759 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testValue + "\"");
763 //===========================================================
765 void LocaleTest::doTestDisplayNames(Locale
& displayLocale
, int32_t compareIndex
) {
768 for (int32_t i
= 0; i
<= MAX_LOCALES
; i
++) {
769 Locale
testLocale("");
770 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
771 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
774 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
776 logln(" Testing " + (temp
=testLocale
.getName()) + "...");
778 UnicodeString testLang
;
779 UnicodeString testScript
;
780 UnicodeString testCtry
;
781 UnicodeString testVar
;
782 UnicodeString testName
;
784 testLocale
.getDisplayLanguage(displayLocale
, testLang
);
785 testLocale
.getDisplayScript(displayLocale
, testScript
);
786 testLocale
.getDisplayCountry(displayLocale
, testCtry
);
787 testLocale
.getDisplayVariant(displayLocale
, testVar
);
788 testLocale
.getDisplayName(displayLocale
, testName
);
790 UnicodeString expectedLang
;
791 UnicodeString expectedScript
;
792 UnicodeString expectedCtry
;
793 UnicodeString expectedVar
;
794 UnicodeString expectedName
;
796 expectedLang
= dataTable
[compareIndex
][i
];
797 if (expectedLang
.length() == 0)
798 expectedLang
= dataTable
[DLANG_EN
][i
];
800 expectedScript
= dataTable
[compareIndex
+ 1][i
];
801 if (expectedScript
.length() == 0)
802 expectedScript
= dataTable
[DSCRIPT_EN
][i
];
804 expectedCtry
= dataTable
[compareIndex
+ 2][i
];
805 if (expectedCtry
.length() == 0)
806 expectedCtry
= dataTable
[DCTRY_EN
][i
];
808 expectedVar
= dataTable
[compareIndex
+ 3][i
];
809 if (expectedVar
.length() == 0)
810 expectedVar
= dataTable
[DVAR_EN
][i
];
812 expectedName
= dataTable
[compareIndex
+ 4][i
];
813 if (expectedName
.length() == 0)
814 expectedName
= dataTable
[DNAME_EN
][i
];
816 if (testLang
!= expectedLang
)
817 dataerrln("Display language (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testLang
+ " expected " + expectedLang
);
818 if (testScript
!= expectedScript
)
819 dataerrln("Display script (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testScript
+ " expected " + expectedScript
);
820 if (testCtry
!= expectedCtry
)
821 dataerrln("Display country (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testCtry
+ " expected " + expectedCtry
);
822 if (testVar
!= expectedVar
)
823 dataerrln("Display variant (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testVar
+ " expected " + expectedVar
);
824 if (testName
!= expectedName
)
825 dataerrln("Display name (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testName
+ " expected " + expectedName
);
829 //---------------------------------------------------
830 // table of valid data
831 //---------------------------------------------------
835 void LocaleTest::setUpDataTable()
837 if (dataTable
== 0) {
838 dataTable
= new UnicodeString
*[33];
840 for (int32_t i
= 0; i
< 33; i
++) {
841 dataTable
[i
] = new UnicodeString
[8];
842 for (int32_t j
= 0; j
< 8; j
++) {
843 dataTable
[i
][j
] = CharsToUnicodeString(rawData
[i
][j
]);
849 // ====================
853 * @bug 4011756 4011380
856 LocaleTest::TestISO3Fallback()
858 Locale
test("xx", "YY");
862 result
= test
.getISO3Language();
864 // Conform to C API usage
866 if (!result
|| (result
[0] != 0))
867 errln("getISO3Language() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
869 result
= test
.getISO3Country();
871 if (!result
|| (result
[0] != 0))
872 errln("getISO3Country() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
876 * @bug 4106155 4118587
879 LocaleTest::TestGetLangsAndCountries()
881 // It didn't seem right to just do an exhaustive test of everything here, so I check
882 // for the following things:
883 // 1) Does each list have the right total number of entries?
884 // 2) Does each list contain certain language and country codes we think are important
885 // (the G7 countries, plus a couple others)?
886 // 3) Does each list have every entry formatted correctly? (i.e., two characters,
887 // all lower case for the language codes, all upper case for the country codes)
888 // 4) Is each list in sorted order?
889 int32_t testCount
= 0;
890 const char * const * test
= Locale::getISOLanguages();
891 const char spotCheck1
[ ][4] = { "en", "es", "fr", "de", "it",
892 "ja", "ko", "zh", "th", "he",
893 "id", "iu", "ug", "yi", "za" };
897 for(testCount
= 0;test
[testCount
];testCount
++)
900 /* TODO: Change this test to be more like the cloctst version? */
901 if (testCount
!= 595)
902 errln("Expected getISOLanguages() to return 595 languages; it returned %d", testCount
);
904 for (i
= 0; i
< 15; i
++) {
906 for (j
= 0; j
< testCount
; j
++)
907 if (uprv_strcmp(test
[j
],spotCheck1
[i
])== 0)
909 if (j
== testCount
|| (uprv_strcmp(test
[j
],spotCheck1
[i
])!=0))
910 errln("Couldn't find " + (UnicodeString
)spotCheck1
[i
] + " in language list.");
913 for (i
= 0; i
< testCount
; i
++) {
914 UnicodeString
testee(test
[i
],"");
915 UnicodeString
lc(test
[i
],"");
916 if (testee
!= lc
.toLower())
917 errln(lc
+ " is not all lower case.");
918 if ( (testee
.length() != 2) && (testee
.length() != 3))
919 errln(testee
+ " is not two or three characters long.");
920 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
921 errln(testee
+ " appears in an out-of-order position in the list.");
924 test
= Locale::getISOCountries();
925 UnicodeString spotCheck2
[] = { "US", "CA", "GB", "FR", "DE",
926 "IT", "JP", "KR", "CN", "TW",
928 int32_t spot2Len
= 11;
929 for(testCount
=0;test
[testCount
];testCount
++)
932 if (testCount
!= 256){
933 errln("Expected getISOCountries to return 256 countries; it returned %d", testCount
);
935 for (i
= 0; i
< spot2Len
; i
++) {
937 for (j
= 0; j
< testCount
; j
++)
939 UnicodeString
testee(test
[j
],"");
941 if (testee
== spotCheck2
[i
])
944 UnicodeString
testee(test
[j
],"");
945 if (j
== testCount
|| testee
!= spotCheck2
[i
])
946 errln("Couldn't find " + spotCheck2
[i
] + " in country list.");
949 for (i
= 0; i
< testCount
; i
++) {
950 UnicodeString
testee(test
[i
],"");
951 UnicodeString
uc(test
[i
],"");
952 if (testee
!= uc
.toUpper())
953 errln(testee
+ " is not all upper case.");
954 if (testee
.length() != 2)
955 errln(testee
+ " is not two characters long.");
956 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
957 errln(testee
+ " appears in an out-of-order position in the list.");
960 // This getAvailableLocales and getISO3Language
962 int32_t numOfLocales
;
964 const Locale
*pLocales
= Locale::getAvailableLocales(numOfLocales
);
966 for (int i
= 0; i
< numOfLocales
; i
++) {
967 const Locale
&loc(pLocales
[i
]);
971 loc
.getDisplayName (enLoc
, name
);
972 name
.extract (0, 200, szName
, sizeof(szName
));
974 if (strlen(loc
.getISO3Language()) == 0) {
975 errln("getISO3Language() returned an empty string for: " + name
);
985 LocaleTest::TestSimpleDisplayNames()
987 // This test is different from TestDisplayNames because TestDisplayNames checks
988 // fallback behavior, combination of language and country names to form locale
989 // names, and other stuff like that. This test just checks specific language
990 // and country codes to make sure we have the correct names for them.
991 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
992 UnicodeString languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
995 for (int32_t i
= 0; i
< 6; i
++) {
997 Locale
l(languageCodes
[i
], "", "");
998 l
.getDisplayLanguage(Locale::getUS(), test
);
999 if (test
!= languageNames
[i
])
1000 dataerrln("Got wrong display name for " + UnicodeString(languageCodes
[i
]) + ": Expected \"" +
1001 languageNames
[i
] + "\", got \"" + test
+ "\".");
1009 LocaleTest::TestUninstalledISO3Names()
1011 // This test checks to make sure getISO3Language and getISO3Country work right
1012 // even for locales that are not installed.
1013 const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
1015 const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
1016 "ssw", "twi", "zul" };
1020 for (i
= 0; i
< 8; i
++) {
1021 UErrorCode err
= U_ZERO_ERROR
;
1024 Locale
l(iso2Languages
[i
], "", "");
1025 test
= l
.getISO3Language();
1026 if((test
!= iso3Languages
[i
]) || U_FAILURE(err
))
1027 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages
[i
]) + ": Expected \"" +
1028 iso3Languages
[i
] + "\", got \"" + test
+ "\"." + UnicodeString(u_errorName(err
)));
1031 char iso2Countries
[][4] = { "AF", "BW", "KZ", "MO", "MN",
1033 char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
1034 "SLB", "TCA", "ZWE" };
1036 for (i
= 0; i
< 8; i
++) {
1037 UErrorCode err
= U_ZERO_ERROR
;
1038 Locale
l("", iso2Countries
[i
], "");
1039 UnicodeString
test(l
.getISO3Country(), "");
1040 if (test
!= iso3Countries
[i
])
1041 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries
[i
]) + ": Expected \"" +
1042 UnicodeString(iso3Countries
[i
]) + "\", got \"" + test
+ "\"." + u_errorName(err
));
1048 * I could not reproduce this bug. I'm pretty convinced it was fixed with the
1049 * big locale-data reorg of 10/28/97. The lookup logic for language and country
1050 * display names was also changed at that time in that check-in. --rtg 3/20/98
1053 LocaleTest::TestAtypicalLocales()
1055 Locale localesToTest
[] = { Locale("de", "CA"),
1065 UnicodeString englishDisplayNames
[] = { "German (Canada)",
1066 "Japanese (South Africa)",
1069 "Spanish (Germany)",
1072 "Dominican Republic",
1074 UnicodeString frenchDisplayNames
[]= { "allemand (Canada)",
1075 "japonais (Afrique du Sud)",
1078 "espagnol (Allemagne)",
1081 u
"République dominicaine",
1083 UnicodeString spanishDisplayNames
[] = {
1085 u
"japonés (Sudáfrica)",
1087 u
"inglés (Francia)",
1088 u
"español (Alemania)",
1091 u
"República Dominicana",
1093 // De-Anglicizing root required the change from
1094 // English display names to ISO Codes - ram 2003/09/26
1095 UnicodeString invDisplayNames
[] = { "German (Canada)",
1096 "Japanese (South Africa)",
1099 "Spanish (Germany)",
1102 "Dominican Republic",
1106 UErrorCode status
= U_ZERO_ERROR
;
1108 Locale::setDefault(Locale::getUS(), status
);
1109 for (i
= 0; i
< 9; ++i
) {
1111 localesToTest
[i
].getDisplayName(Locale::getUS(), name
);
1113 if (name
!= englishDisplayNames
[i
])
1115 dataerrln("Lookup in English failed: expected \"" + englishDisplayNames
[i
]
1116 + "\", got \"" + name
+ "\"");
1117 logln("Locale name was-> " + (name
=localesToTest
[i
].getName()));
1121 for (i
= 0; i
< 9; i
++) {
1123 localesToTest
[i
].getDisplayName(Locale("es", "ES"), name
);
1125 if (name
!= spanishDisplayNames
[i
])
1126 dataerrln("Lookup in Spanish failed: expected \"" + spanishDisplayNames
[i
]
1127 + "\", got \"" + name
+ "\"");
1130 for (i
= 0; i
< 9; i
++) {
1132 localesToTest
[i
].getDisplayName(Locale::getFrance(), name
);
1134 if (name
!= frenchDisplayNames
[i
])
1135 dataerrln("Lookup in French failed: expected \"" + frenchDisplayNames
[i
]
1136 + "\", got \"" + name
+ "\"");
1139 for (i
= 0; i
< 9; i
++) {
1141 localesToTest
[i
].getDisplayName(Locale("inv", "IN"), name
);
1142 logln(name
+ " Locale fallback to be, and data fallback to root");
1143 if (name
!= invDisplayNames
[i
])
1144 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1145 + "\", got \"" + prettify(name
) + "\"");
1146 localesToTest
[i
].getDisplayName(Locale("inv", "BD"), name
);
1147 logln(name
+ " Data fallback to root");
1148 if (name
!= invDisplayNames
[i
])
1149 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1150 + "\", got \"" + prettify(name
)+ "\"");
1152 Locale::setDefault(saveLocale
, status
);
1155 #if !UCONFIG_NO_FORMATTING
1159 * This would be better tested by the LocaleDataTest. Will move it when I
1160 * get the LocaleDataTest working again.
1163 LocaleTest::TestThaiCurrencyFormat()
1165 UErrorCode status
= U_ZERO_ERROR
;
1166 DecimalFormat
*thaiCurrency
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(
1167 Locale("th", "TH"), status
);
1168 UnicodeString
posPrefix(u
"\u0E3F");
1171 if(U_FAILURE(status
) || !thaiCurrency
)
1173 dataerrln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status
)));
1176 if (thaiCurrency
->getPositivePrefix(temp
) != posPrefix
)
1177 errln("Thai currency prefix wrong: expected Baht sign, got \"" +
1178 thaiCurrency
->getPositivePrefix(temp
) + "\"");
1179 if (thaiCurrency
->getPositiveSuffix(temp
) != "")
1180 errln("Thai currency suffix wrong: expected \"\", got \"" +
1181 thaiCurrency
->getPositiveSuffix(temp
) + "\"");
1183 delete thaiCurrency
;
1188 * Confirm that Euro support works. This test is pretty rudimentary; all it does
1189 * is check that any locales with the EURO variant format a number using the
1190 * Euro currency symbol.
1192 * ASSUME: All locales encode the Euro character "\u20AC".
1193 * If this is changed to use the single-character Euro symbol, this
1194 * test must be updated.
1198 LocaleTest::TestEuroSupport()
1200 UChar euro
= 0x20ac;
1201 const UnicodeString
EURO_CURRENCY(&euro
, 1, 1); // Look for this UnicodeString in formatted Euro currency
1202 const char* localeArr
[] = {
1210 "en_GB@currency=EUR",
1211 "en_US@currency=EUR",
1226 const char** locales
= localeArr
;
1228 UErrorCode status
= U_ZERO_ERROR
;
1232 for (;*locales
!=NULL
;locales
++) {
1233 Locale
loc (*locales
);
1235 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(loc
, status
);
1238 if (U_FAILURE(status
)) {
1239 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales
);
1243 nf
->format(271828.182845, pos
);
1245 nf
->format(-271828.182845, neg
);
1246 if (pos
.indexOf(EURO_CURRENCY
) >= 0 &&
1247 neg
.indexOf(EURO_CURRENCY
) >= 0) {
1248 logln("Ok: " + (temp
=loc
.getName()) +
1249 ": " + pos
+ " / " + neg
);
1252 errln("Fail: " + (temp
=loc
.getName()) +
1253 " formats without " + EURO_CURRENCY
+
1254 ": " + pos
+ " / " + neg
+
1255 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***");
1261 UnicodeString
dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar
)0x00a4), resultStr
;
1263 status
= U_ZERO_ERROR
;
1265 ucurr_forLocale("en_US", tmp
, 4, &status
);
1266 resultStr
.setTo(tmp
);
1267 if (dollarStr
!= resultStr
) {
1268 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
1270 ucurr_forLocale("en_US@currency=EUR", tmp
, 4, &status
);
1271 resultStr
.setTo(tmp
);
1272 if (euroStr
!= resultStr
) {
1273 errcheckln(status
, "Fail: en_US@currency=EUR didn't return EUR - %s", u_errorName(status
));
1275 ucurr_forLocale("en_GB@currency=EUR", tmp
, 4, &status
);
1276 resultStr
.setTo(tmp
);
1277 if (euroStr
!= resultStr
) {
1278 errcheckln(status
, "Fail: en_GB@currency=EUR didn't return EUR - %s", u_errorName(status
));
1280 ucurr_forLocale("en_US_Q", tmp
, 4, &status
);
1281 resultStr
.setTo(tmp
);
1282 if (dollarStr
!= resultStr
) {
1283 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
1285 int32_t invalidLen
= ucurr_forLocale("en_QQ", tmp
, 4, &status
);
1286 if (invalidLen
|| U_SUCCESS(status
)) {
1287 errln("Fail: en_QQ didn't return NULL");
1290 // The currency keyword value is as long as the destination buffer.
1291 // It should detect the overflow internally, and default to the locale's currency.
1293 status
= U_ZERO_ERROR
;
1294 int32_t length
= ucurr_forLocale("en_US@currency=euro", tmp
, 4, &status
);
1295 if (U_FAILURE(status
) || dollarStr
!= UnicodeString(tmp
, length
)) {
1296 if (U_SUCCESS(status
) && tmp
[0] == u
'¤') {
1297 errln("Fail: ucurr_forLocale(en_US@currency=euro) succeeded without writing output");
1299 errln("Fail: ucurr_forLocale(en_US@currency=euro) != USD - %s", u_errorName(status
));
1308 * toString() doesn't work with language_VARIANT.
1311 LocaleTest::TestToString() {
1313 Locale("xx", "", ""),
1314 Locale("", "YY", ""),
1315 Locale("", "", "ZZ"),
1316 Locale("xx", "YY", ""),
1317 Locale("xx", "", "ZZ"),
1318 Locale("", "YY", "ZZ"),
1319 Locale("xx", "YY", "ZZ"),
1322 const char DATA_S
[][20] = {
1332 for (int32_t i
=0; i
< 7; ++i
) {
1334 name
= DATA
[i
].getName();
1336 if (strcmp(name
, DATA_S
[i
]) != 0)
1338 errln("Fail: Locale.getName(), got:" + UnicodeString(name
) + ", expected: " + DATA_S
[i
]);
1341 logln("Pass: Locale.getName(), got:" + UnicodeString(name
) );
1345 #if !UCONFIG_NO_FORMATTING
1349 * Couldn't reproduce this bug -- probably was fixed earlier.
1351 * ORIGINAL BUG REPORT:
1352 * -- basically, hungarian for monday shouldn't have an \u00f4
1353 * (o circumflex)in it instead it should be an o with 2 inclined
1354 * (right) lines over it..
1356 * You may wonder -- why do all this -- why not just add a line to
1357 * LocaleData? Well, I could see by inspection that the locale file had the
1358 * right character in it, so I wanted to check the rest of the pipeline -- a
1359 * very remote possibility, but I wanted to be sure. The other possibility
1360 * is that something is wrong with the font mapping subsystem, but we can't
1364 LocaleTest::Test4139940()
1366 Locale
mylocale("hu", "", "");
1367 UDate mydate
= date(98,3,13); // A Monday
1368 UErrorCode status
= U_ZERO_ERROR
;
1369 SimpleDateFormat
df_full("EEEE", mylocale
, status
);
1370 if(U_FAILURE(status
)){
1371 dataerrln(UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: ") + UnicodeString(u_errorName(status
)));
1375 FieldPosition
pos(FieldPosition::DONT_CARE
);
1376 df_full
.format(mydate
, str
, pos
);
1377 // Make sure that o circumflex (\u00F4) is NOT there, and
1378 // o double acute (\u0151) IS.
1381 if (str
.indexOf(oda
) < 0 || str
.indexOf(ocf
) >= 0) {
1382 /* If the default locale is "th" this test will fail because of the buddhist calendar. */
1383 if (strcmp(Locale::getDefault().getLanguage(), "th") != 0) {
1384 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
1385 str
.indexOf(oda
), str
.indexOf(ocf
));
1387 logln(UnicodeString("An error is produce in buddhist calendar."));
1389 logln(UnicodeString("String is: ") + str
);
1394 LocaleTest::date(int32_t y
, int32_t m
, int32_t d
, int32_t hr
, int32_t min
, int32_t sec
)
1396 UErrorCode status
= U_ZERO_ERROR
;
1397 Calendar
*cal
= Calendar::createInstance(status
);
1401 cal
->set(1900 + y
, m
, d
, hr
, min
, sec
); // Add 1900 to follow java.util.Date protocol
1402 UDate dt
= cal
->getTime(status
);
1403 if (U_FAILURE(status
))
1412 * Russian first day of week should be Monday. Confirmed.
1415 LocaleTest::Test4143951()
1417 UErrorCode status
= U_ZERO_ERROR
;
1418 Calendar
*cal
= Calendar::createInstance(Locale("ru", "", ""), status
);
1419 if(U_SUCCESS(status
)) {
1420 if (cal
->getFirstDayOfWeek(status
) != UCAL_MONDAY
) {
1421 dataerrln("Fail: First day of week in Russia should be Monday");
1431 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes.
1432 * Should throw an exception for unknown locales
1435 LocaleTest::Test4147315()
1438 // Try with codes that are the wrong length but happen to match text
1439 // at a valid offset in the mapping table
1440 Locale
locale("xxx", "CCC");
1442 const char *result
= locale
.getISO3Country();
1444 // Change to conform to C api usage
1445 if((result
==NULL
)||(result
[0] != 0))
1446 errln("ERROR: getISO3Country() returns: " + UnicodeString(result
,"") +
1447 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1452 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
1453 * Should throw an exception for unknown locales
1456 LocaleTest::Test4147317()
1459 // Try with codes that are the wrong length but happen to match text
1460 // at a valid offset in the mapping table
1461 Locale
locale("xxx", "CCC");
1463 const char *result
= locale
.getISO3Language();
1465 // Change to conform to C api usage
1466 if((result
==NULL
)||(result
[0] != 0))
1467 errln("ERROR: getISO3Language() returns: " + UnicodeString(result
,"") +
1468 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1475 LocaleTest::Test4147552()
1477 Locale locales
[] = { Locale("no", "NO"),
1478 Locale("no", "NO", "B"),
1479 Locale("no", "NO", "NY")
1482 UnicodeString
edn("Norwegian (Norway, B)");
1483 UnicodeString englishDisplayNames
[] = {
1484 "Norwegian (Norway)",
1486 // "Norwegian (Norway,B)",
1487 //"Norwegian (Norway,NY)"
1488 "Norwegian (Norway, NY)"
1490 UnicodeString
ndn("norsk (Norge, B");
1491 UnicodeString norwegianDisplayNames
[] = {
1496 //"Norsk (Noreg, Nynorsk)"
1498 UErrorCode status
= U_ZERO_ERROR
;
1501 Locale::setDefault(Locale::getEnglish(), status
);
1502 for (int32_t i
= 0; i
< 3; ++i
) {
1503 Locale loc
= locales
[i
];
1505 if (loc
.getDisplayName(temp
) != englishDisplayNames
[i
])
1506 dataerrln("English display-name mismatch: expected " +
1507 englishDisplayNames
[i
] + ", got " + loc
.getDisplayName(temp
));
1508 if (loc
.getDisplayName(loc
, temp
) != norwegianDisplayNames
[i
])
1509 dataerrln("Norwegian display-name mismatch: expected " +
1510 norwegianDisplayNames
[i
] + ", got " +
1511 loc
.getDisplayName(loc
, temp
));
1513 Locale::setDefault(saveLocale
, status
);
1517 LocaleTest::TestVariantParsing()
1519 Locale
en_US_custom("en", "US", "De Anza_Cupertino_California_United States_Earth");
1521 UnicodeString
dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)");
1522 UnicodeString
dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH");
1526 en_US_custom
.getDisplayVariant(Locale::getUS(), got
);
1527 if(got
!= dispVar
) {
1528 errln("FAIL: getDisplayVariant()");
1529 errln("Wanted: " + dispVar
);
1530 errln("Got : " + got
);
1533 en_US_custom
.getDisplayName(Locale::getUS(), got
);
1534 if(got
!= dispName
) {
1535 dataerrln("FAIL: getDisplayName()");
1536 dataerrln("Wanted: " + dispName
);
1537 dataerrln("Got : " + got
);
1540 Locale
shortVariant("fr", "FR", "foo");
1541 shortVariant
.getDisplayVariant(got
);
1544 errln("FAIL: getDisplayVariant()");
1545 errln("Wanted: foo");
1546 errln("Got : " + got
);
1549 Locale
bogusVariant("fr", "FR", "_foo");
1550 bogusVariant
.getDisplayVariant(got
);
1553 errln("FAIL: getDisplayVariant()");
1554 errln("Wanted: foo");
1555 errln("Got : " + got
);
1558 Locale
bogusVariant2("fr", "FR", "foo_");
1559 bogusVariant2
.getDisplayVariant(got
);
1562 errln("FAIL: getDisplayVariant()");
1563 errln("Wanted: foo");
1564 errln("Got : " + got
);
1567 Locale
bogusVariant3("fr", "FR", "_foo_");
1568 bogusVariant3
.getDisplayVariant(got
);
1571 errln("FAIL: getDisplayVariant()");
1572 errln("Wanted: foo");
1573 errln("Got : " + got
);
1577 #if !UCONFIG_NO_FORMATTING
1581 * Currency symbol in zh is wrong. We will test this at the NumberFormat
1582 * end to test the whole pipe.
1585 LocaleTest::Test4105828()
1587 Locale LOC
[] = { Locale::getChinese(), Locale("zh", "CN", ""),
1588 Locale("zh", "TW", ""), Locale("zh", "HK", "") };
1589 UErrorCode status
= U_ZERO_ERROR
;
1590 for (int32_t i
= 0; i
< 4; ++i
) {
1591 NumberFormat
*fmt
= NumberFormat::createPercentInstance(LOC
[i
], status
);
1592 if(U_FAILURE(status
)) {
1593 dataerrln("Couldn't create NumberFormat - %s", u_errorName(status
));
1596 UnicodeString result
;
1597 FieldPosition
pos(FieldPosition::DONT_CARE
);
1598 fmt
->format((int32_t)1, result
, pos
);
1600 if(result
!= "100%") {
1601 errln(UnicodeString("Percent for ") + LOC
[i
].getDisplayName(temp
) + " should be 100%, got " + result
);
1609 // Tests setBogus and isBogus APIs for Locale
1612 LocaleTest::TestSetIsBogus() {
1615 if(l
.isBogus() != TRUE
) {
1616 errln("After setting bogus, didn't return TRUE");
1618 l
= "en_US"; // This should reset bogus
1619 if(l
.isBogus() != FALSE
) {
1620 errln("After resetting bogus, didn't return FALSE");
1626 LocaleTest::TestAddLikelySubtags() {
1627 IcuTestErrorCode
status(*this, "TestAddLikelySubtags()");
1629 static const Locale
min("sv");
1630 static const Locale
max("sv_Latn_SE");
1633 result
.addLikelySubtags(status
);
1634 status
.errIfFailureAndReset("\"%s\"", min
.getName());
1635 assertEquals("addLikelySubtags", max
.getName(), result
.getName());
1640 LocaleTest::TestMinimizeSubtags() {
1641 IcuTestErrorCode
status(*this, "TestMinimizeSubtags()");
1643 static const Locale
max("zh_Hant_TW");
1644 static const Locale
min("zh_TW");
1647 result
.minimizeSubtags(status
);
1648 status
.errIfFailureAndReset("\"%s\"", max
.getName());
1649 assertEquals("minimizeSubtags", min
.getName(), result
.getName());
1654 LocaleTest::TestAddLikelyAndMinimizeSubtags() {
1655 IcuTestErrorCode
status(*this, "TestAddLikelyAndMinimizeSubtags()");
1657 static const struct {
1658 const char* const from
;
1659 const char* const add
;
1660 const char* const remove
;
1681 for (const auto& item
: full_data
) {
1682 const char* const org
= item
.from
;
1683 const char* const exp
= item
.add
;
1685 res
.addLikelySubtags(status
);
1686 status
.errIfFailureAndReset("\"%s\"", org
);
1687 assertEquals("addLikelySubtags", exp
, res
.getName());
1690 for (const auto& item
: full_data
) {
1691 const char* const org
= item
.from
;
1692 const char* const exp
= item
.remove
;
1694 res
.minimizeSubtags(status
);
1695 status
.errIfFailureAndReset("\"%s\"", org
);
1696 assertEquals("minimizeSubtags", exp
, res
.getName());
1702 LocaleTest::TestKeywordVariants(void) {
1703 static const struct {
1704 const char *localeID
;
1705 const char *expectedLocaleID
;
1706 //const char *expectedLocaleIDNoKeywords;
1707 //const char *expectedCanonicalID;
1708 const char *expectedKeywords
[10];
1709 int32_t numKeywords
;
1710 UErrorCode expectedStatus
;
1713 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1714 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1716 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1717 {"calendar", "collation", "currency"},
1725 //"de_DE@currency=EUR",
1726 {"","","","","","",""},
1728 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1731 UErrorCode status
= U_ZERO_ERROR
;
1733 int32_t i
= 0, j
= 0;
1734 const char *result
= NULL
;
1735 StringEnumeration
*keywords
;
1736 int32_t keyCount
= 0;
1737 const char *keyword
= NULL
;
1738 const UnicodeString
*keywordString
;
1739 int32_t keywordLen
= 0;
1741 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1742 status
= U_ZERO_ERROR
;
1743 Locale
l(testCases
[i
].localeID
);
1744 keywords
= l
.createKeywords(status
);
1746 if(status
!= testCases
[i
].expectedStatus
) {
1747 err("Expected to get status %s. Got %s instead\n",
1748 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1750 status
= U_ZERO_ERROR
;
1752 if((keyCount
= keywords
->count(status
)) != testCases
[i
].numKeywords
) {
1753 err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1758 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1761 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1762 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1765 if((keywordString
= keywords
->snext(status
)) == NULL
) {
1768 if(*keywordString
!= UnicodeString(testCases
[i
].expectedKeywords
[j
], "")) {
1769 err("Expected to get keyword UnicodeString %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1774 if(j
== keyCount
/ 2) {
1775 // replace keywords with a clone of itself
1776 StringEnumeration
*k2
= keywords
->clone();
1777 if(k2
== NULL
|| keyCount
!= k2
->count(status
)) {
1778 errln("KeywordEnumeration.clone() failed");
1785 keywords
->reset(status
); // Make sure that reset works.
1787 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1790 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1791 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1798 result
= l
.getName();
1799 if(uprv_strcmp(testCases
[i
].expectedLocaleID
, result
) != 0) {
1800 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n",
1801 testCases
[i
].expectedLocaleID
, testCases
[i
].localeID
, result
);
1810 LocaleTest::TestCreateUnicodeKeywords(void) {
1811 IcuTestErrorCode
status(*this, "TestCreateUnicodeKeywords()");
1813 static const Locale
l("de@calendar=buddhist;collation=phonebook");
1815 LocalPointer
<StringEnumeration
> keys(l
.createUnicodeKeywords(status
));
1816 status
.errIfFailureAndReset("\"%s\"", l
.getName());
1819 int32_t resultLength
;
1821 key
= keys
->next(&resultLength
, status
);
1822 status
.errIfFailureAndReset("key #1");
1823 assertEquals("resultLength", 2, resultLength
);
1824 assertTrue("key != nullptr", key
!= nullptr);
1825 if (key
!= nullptr) {
1826 assertEquals("calendar", "ca", key
);
1829 key
= keys
->next(&resultLength
, status
);
1830 status
.errIfFailureAndReset("key #2");
1831 assertEquals("resultLength", 2, resultLength
);
1832 assertTrue("key != nullptr", key
!= nullptr);
1833 if (key
!= nullptr) {
1834 assertEquals("collation", "co", key
);
1837 key
= keys
->next(&resultLength
, status
);
1838 status
.errIfFailureAndReset("end of keys");
1839 assertEquals("resultLength", 0, resultLength
);
1840 assertTrue("key == nullptr", key
== nullptr);
1842 const UnicodeString
* skey
;
1843 keys
->reset(status
); // KeywordEnumeration::reset() never touches status.
1845 skey
= keys
->snext(status
);
1846 status
.errIfFailureAndReset("skey #1");
1847 assertTrue("skey != nullptr", skey
!= nullptr);
1848 if (skey
!= nullptr) {
1849 assertEquals("calendar", "ca", *skey
);
1852 skey
= keys
->snext(status
);
1853 status
.errIfFailureAndReset("skey #2");
1854 assertTrue("skey != nullptr", skey
!= nullptr);
1855 if (skey
!= nullptr) {
1856 assertEquals("collation", "co", *skey
);
1859 skey
= keys
->snext(status
);
1860 status
.errIfFailureAndReset("end of keys");
1861 assertTrue("skey == nullptr", skey
== nullptr);
1866 LocaleTest::TestKeywordVariantParsing(void) {
1867 static const struct {
1868 const char *localeID
;
1869 const char *keyword
;
1870 const char *expectedValue
;
1872 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook" },
1873 { "de_DE", "collation", ""},
1874 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" },
1875 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation", "PHONEBOOk" },
1878 UErrorCode status
= U_ZERO_ERROR
;
1881 int32_t resultLen
= 0;
1884 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1886 Locale
l(testCases
[i
].localeID
);
1887 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1888 (void)resultLen
; // Suppress unused variable warning.
1889 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1890 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1891 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1897 LocaleTest::TestCreateKeywordSet(void) {
1898 IcuTestErrorCode
status(*this, "TestCreateKeywordSet()");
1900 static const Locale
l("de@calendar=buddhist;collation=phonebook");
1902 std::set
<std::string
> result
;
1903 l
.getKeywords
<std::string
>(
1904 std::insert_iterator
<decltype(result
)>(result
, result
.begin()),
1906 status
.errIfFailureAndReset("\"%s\"", l
.getName());
1908 assertEquals("set::size()", 2, static_cast<int32_t>(result
.size()));
1909 assertTrue("set::find(\"calendar\")",
1910 result
.find("calendar") != result
.end());
1911 assertTrue("set::find(\"collation\")",
1912 result
.find("collation") != result
.end());
1916 LocaleTest::TestCreateUnicodeKeywordSet(void) {
1917 IcuTestErrorCode
status(*this, "TestCreateUnicodeKeywordSet()");
1919 static const Locale
l("de@calendar=buddhist;collation=phonebook");
1921 std::set
<std::string
> result
;
1922 l
.getUnicodeKeywords
<std::string
>(
1923 std::insert_iterator
<decltype(result
)>(result
, result
.begin()),
1925 status
.errIfFailureAndReset("\"%s\"", l
.getName());
1927 assertEquals("set::size()", 2, static_cast<int32_t>(result
.size()));
1928 assertTrue("set::find(\"ca\")",
1929 result
.find("ca") != result
.end());
1930 assertTrue("set::find(\"co\")",
1931 result
.find("co") != result
.end());
1935 LocaleTest::TestGetKeywordValueStdString(void) {
1936 IcuTestErrorCode
status(*this, "TestGetKeywordValueStdString()");
1938 static const char tag
[] = "fa-u-nu-latn";
1939 static const char keyword
[] = "numbers";
1940 static const char expected
[] = "latn";
1942 Locale l
= Locale::forLanguageTag(tag
, status
);
1943 status
.errIfFailureAndReset("\"%s\"", tag
);
1945 std::string result
= l
.getKeywordValue
<std::string
>(keyword
, status
);
1946 status
.errIfFailureAndReset("\"%s\"", keyword
);
1947 assertEquals(keyword
, expected
, result
.c_str());
1951 LocaleTest::TestGetUnicodeKeywordValueStdString(void) {
1952 IcuTestErrorCode
status(*this, "TestGetUnicodeKeywordValueStdString()");
1954 static const char keyword
[] = "co";
1955 static const char expected
[] = "phonebk";
1957 static const Locale
l("de@calendar=buddhist;collation=phonebook");
1959 std::string result
= l
.getUnicodeKeywordValue
<std::string
>(keyword
, status
);
1960 status
.errIfFailureAndReset("\"%s\"", keyword
);
1961 assertEquals(keyword
, expected
, result
.c_str());
1965 LocaleTest::TestSetKeywordValue(void) {
1966 static const struct {
1967 const char *keyword
;
1970 { "collation", "phonebook" },
1971 { "currency", "euro" },
1972 { "calendar", "buddhist" }
1975 UErrorCode status
= U_ZERO_ERROR
;
1978 int32_t resultLen
= 0;
1981 Locale
l(Locale::getGerman());
1983 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1984 l
.setKeywordValue(testCases
[i
].keyword
, testCases
[i
].value
, status
);
1985 if(U_FAILURE(status
)) {
1986 err("FAIL: Locale::setKeywordValue failed - %s\n", u_errorName(status
));
1990 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1991 (void)resultLen
; // Suppress unused variable warning.
1992 if(uprv_strcmp(testCases
[i
].value
, buffer
) != 0) {
1993 err("Expected to extract \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1994 testCases
[i
].value
, testCases
[i
].keyword
, buffer
);
2000 LocaleTest::TestSetKeywordValueStringPiece(void) {
2001 IcuTestErrorCode
status(*this, "TestSetKeywordValueStringPiece()");
2002 Locale
l(Locale::getGerman());
2004 l
.setKeywordValue(StringPiece("collation"), StringPiece("phonebook"), status
);
2005 l
.setKeywordValue(StringPiece("calendarxxx", 8), StringPiece("buddhistxxx", 8), status
);
2007 static const char expected
[] = "de@calendar=buddhist;collation=phonebook";
2008 assertEquals("", expected
, l
.getName());
2012 LocaleTest::TestSetUnicodeKeywordValueStringPiece(void) {
2013 IcuTestErrorCode
status(*this, "TestSetUnicodeKeywordValueStringPiece()");
2014 Locale
l(Locale::getGerman());
2016 l
.setUnicodeKeywordValue(StringPiece("co"), StringPiece("phonebk"), status
);
2017 status
.errIfFailureAndReset();
2019 l
.setUnicodeKeywordValue(StringPiece("caxxx", 2), StringPiece("buddhistxxx", 8), status
);
2020 status
.errIfFailureAndReset();
2022 static const char expected
[] = "de@calendar=buddhist;collation=phonebook";
2023 assertEquals("", expected
, l
.getName());
2025 l
.setUnicodeKeywordValue("cu", nullptr, status
);
2026 status
.errIfFailureAndReset();
2027 assertEquals("", expected
, l
.getName());
2029 l
.setUnicodeKeywordValue("!!", nullptr, status
);
2030 assertEquals("status", U_ILLEGAL_ARGUMENT_ERROR
, status
.reset());
2031 assertEquals("", expected
, l
.getName());
2033 l
.setUnicodeKeywordValue("co", "!!", status
);
2034 assertEquals("status", U_ILLEGAL_ARGUMENT_ERROR
, status
.reset());
2035 assertEquals("", expected
, l
.getName());
2037 l
.setUnicodeKeywordValue("co", nullptr, status
);
2038 status
.errIfFailureAndReset();
2040 l
.setUnicodeKeywordValue("ca", "", status
);
2041 status
.errIfFailureAndReset();
2043 assertEquals("", Locale::getGerman().getName(), l
.getName());
2047 LocaleTest::TestGetBaseName(void) {
2048 static const struct {
2049 const char *localeID
;
2050 const char *baseName
;
2052 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2053 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2054 { "ja@calendar = buddhist", "ja" },
2055 { "de-u-co-phonebk", "de"}
2060 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2061 Locale
loc(testCases
[i
].localeID
);
2062 if(strcmp(testCases
[i
].baseName
, loc
.getBaseName())) {
2063 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
2064 testCases
[i
].localeID
, testCases
[i
].baseName
, loc
.getBaseName());
2069 // Verify that adding a keyword to an existing Locale doesn't change the base name.
2070 UErrorCode status
= U_ZERO_ERROR
;
2071 Locale
loc2("en-US");
2072 if (strcmp("en_US", loc2
.getBaseName())) {
2073 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
2075 loc2
.setKeywordValue("key", "value", status
);
2076 if (strcmp("en_US@key=value", loc2
.getName())) {
2077 errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getName());
2079 if (strcmp("en_US", loc2
.getBaseName())) {
2080 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
2085 * Compare two locale IDs. If they are equal, return 0. If `string'
2086 * starts with `prefix' plus an additional element, that is, string ==
2087 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2089 static UBool
_loccmp(const char* string
, const char* prefix
) {
2090 int32_t slen
= (int32_t)strlen(string
),
2091 plen
= (int32_t)strlen(prefix
);
2092 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
2093 /* 'root' is "less than" everything */
2094 if (prefix
[0] == '\0') {
2095 return string
[0] != '\0';
2097 if (c
) return -1; /* mismatch */
2098 if (slen
== plen
) return 0;
2099 if (string
[plen
] == '_') return 1;
2100 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2104 * Check the relationship between requested locales, and report problems.
2105 * The caller specifies the expected relationships between requested
2106 * and valid (expReqValid) and between valid and actual (expValidActual).
2107 * Possible values are:
2108 * "gt" strictly greater than, e.g., en_US > en
2109 * "ge" greater or equal, e.g., en >= en
2110 * "eq" equal, e.g., en == en
2112 void LocaleTest::_checklocs(const char* label
,
2114 const Locale
& validLoc
,
2115 const Locale
& actualLoc
,
2116 const char* expReqValid
,
2117 const char* expValidActual
) {
2118 const char* valid
= validLoc
.getName();
2119 const char* actual
= actualLoc
.getName();
2120 int32_t reqValid
= _loccmp(req
, valid
);
2121 int32_t validActual
= _loccmp(valid
, actual
);
2122 if (((0 == uprv_strcmp(expReqValid
, "gt") && reqValid
> 0) ||
2123 (0 == uprv_strcmp(expReqValid
, "ge") && reqValid
>= 0) ||
2124 (0 == uprv_strcmp(expReqValid
, "eq") && reqValid
== 0)) &&
2125 ((0 == uprv_strcmp(expValidActual
, "gt") && validActual
> 0) ||
2126 (0 == uprv_strcmp(expValidActual
, "ge") && validActual
>= 0) ||
2127 (0 == uprv_strcmp(expValidActual
, "eq") && validActual
== 0))) {
2128 logln("%s; req=%s, valid=%s, actual=%s",
2129 label
, req
, valid
, actual
);
2131 dataerrln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
2132 label
, req
, valid
, actual
,
2133 expReqValid
, expValidActual
);
2137 void LocaleTest::TestGetLocale(void) {
2138 #if !UCONFIG_NO_SERVICE
2140 Locale valid
, actual
, reqLoc
;
2143 #if !UCONFIG_NO_FORMATTING
2145 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2146 req
= "en_US_BROOKLYN";
2147 Calendar
* cal
= Calendar::createInstance(Locale::createFromName(req
), ec
);
2148 if (U_FAILURE(ec
)) {
2149 dataerrln("FAIL: Calendar::createInstance failed - %s", u_errorName(ec
));
2151 valid
= cal
->getLocale(ULOC_VALID_LOCALE
, ec
);
2152 actual
= cal
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2153 if (U_FAILURE(ec
)) {
2154 errln("FAIL: Calendar::getLocale() failed");
2156 _checklocs("Calendar", req
, valid
, actual
);
2158 /* Make sure that it fails correctly */
2159 ec
= U_FILE_ACCESS_ERROR
;
2160 if (cal
->getLocale(ULOC_VALID_LOCALE
, ec
).getName()[0] != 0) {
2161 errln("FAIL: Calendar::getLocale() failed to fail correctly. It should have returned \"\"");
2169 // DecimalFormat, DecimalFormatSymbols
2170 #if !UCONFIG_NO_FORMATTING
2172 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2174 NumberFormat
* nf
= NumberFormat::createInstance(Locale::createFromName(req
), ec
);
2175 if (U_FAILURE(ec
)) {
2176 dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec
));
2178 DecimalFormat
* dec
= dynamic_cast<DecimalFormat
*>(nf
);
2180 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
2183 valid
= dec
->getLocale(ULOC_VALID_LOCALE
, ec
);
2184 actual
= dec
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2185 if (U_FAILURE(ec
)) {
2186 errln("FAIL: DecimalFormat::getLocale() failed");
2188 _checklocs("DecimalFormat", req
, valid
, actual
);
2191 const DecimalFormatSymbols
* sym
= dec
->getDecimalFormatSymbols();
2193 errln("FAIL: getDecimalFormatSymbols returned NULL");
2196 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
2197 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2198 if (U_FAILURE(ec
)) {
2199 errln("FAIL: DecimalFormatSymbols::getLocale() failed");
2201 _checklocs("DecimalFormatSymbols", req
, valid
, actual
);
2208 // DateFormat, DateFormatSymbols
2209 #if !UCONFIG_NO_FORMATTING
2211 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2212 req
= "de_CH_LUCERNE";
2214 DateFormat::createDateInstance(DateFormat::kDefault
,
2215 Locale::createFromName(req
));
2217 dataerrln("Error calling DateFormat::createDateInstance()");
2219 SimpleDateFormat
* dat
= dynamic_cast<SimpleDateFormat
*>(df
);
2221 errln("FAIL: DateFormat::createInstance does not return a SimpleDateFormat");
2224 valid
= dat
->getLocale(ULOC_VALID_LOCALE
, ec
);
2225 actual
= dat
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2226 if (U_FAILURE(ec
)) {
2227 errln("FAIL: SimpleDateFormat::getLocale() failed");
2229 _checklocs("SimpleDateFormat", req
, valid
, actual
);
2232 const DateFormatSymbols
* sym
= dat
->getDateFormatSymbols();
2234 errln("FAIL: getDateFormatSymbols returned NULL");
2237 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
2238 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2239 if (U_FAILURE(ec
)) {
2240 errln("FAIL: DateFormatSymbols::getLocale() failed");
2242 _checklocs("DateFormatSymbols", req
, valid
, actual
);
2250 #if !UCONFIG_NO_BREAK_ITERATION
2252 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2253 req
= "es_ES_BARCELONA";
2254 reqLoc
= Locale::createFromName(req
);
2255 BreakIterator
* brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2256 if (U_FAILURE(ec
)) {
2257 dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_errorName(ec
));
2259 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2260 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2261 if (U_FAILURE(ec
)) {
2262 errln("FAIL: BreakIterator::getLocale() failed");
2264 _checklocs("BreakIterator", req
, valid
, actual
);
2267 // After registering something, the behavior should be different
2268 URegistryKey key
= BreakIterator::registerInstance(brk
, reqLoc
, UBRK_WORD
, ec
);
2269 brk
= 0; // registerInstance adopts
2270 if (U_FAILURE(ec
)) {
2271 errln("FAIL: BreakIterator::registerInstance() failed");
2273 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2274 if (U_FAILURE(ec
)) {
2275 errln("FAIL: BreakIterator::createWordInstance failed");
2277 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2278 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2279 if (U_FAILURE(ec
)) {
2280 errln("FAIL: BreakIterator::getLocale() failed");
2282 // N.B.: now expect valid==actual==req
2283 _checklocs("BreakIterator(registered)",
2284 req
, valid
, actual
, "eq", "eq");
2287 // No matter what, unregister
2288 BreakIterator::unregister(key
, ec
);
2289 if (U_FAILURE(ec
)) {
2290 errln("FAIL: BreakIterator::unregister() failed");
2296 // After unregistering, should behave normally again
2297 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2298 if (U_FAILURE(ec
)) {
2299 errln("FAIL: BreakIterator::createWordInstance failed");
2301 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2302 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2303 if (U_FAILURE(ec
)) {
2304 errln("FAIL: BreakIterator::getLocale() failed");
2306 _checklocs("BreakIterator(unregistered)", req
, valid
, actual
);
2315 #if !UCONFIG_NO_COLLATION
2317 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2319 checkRegisteredCollators(NULL
); // Don't expect any extras
2321 req
= "hi_IN_BHOPAL";
2322 reqLoc
= Locale::createFromName(req
);
2323 Collator
* coll
= Collator::createInstance(reqLoc
, ec
);
2324 if (U_FAILURE(ec
)) {
2325 dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(ec
));
2327 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2328 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2329 if (U_FAILURE(ec
)) {
2330 errln("FAIL: Collator::getLocale() failed");
2332 _checklocs("Collator", req
, valid
, actual
);
2335 // After registering something, the behavior should be different
2336 URegistryKey key
= Collator::registerInstance(coll
, reqLoc
, ec
);
2337 coll
= 0; // registerInstance adopts
2338 if (U_FAILURE(ec
)) {
2339 errln("FAIL: Collator::registerInstance() failed");
2341 coll
= Collator::createInstance(reqLoc
, ec
);
2342 if (U_FAILURE(ec
)) {
2343 errln("FAIL: Collator::createWordInstance failed");
2345 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2346 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2347 if (U_FAILURE(ec
)) {
2348 errln("FAIL: Collator::getLocale() failed");
2350 // N.B.: now expect valid==actual==req
2351 _checklocs("Collator(registered)",
2352 req
, valid
, actual
, "eq", "eq");
2355 checkRegisteredCollators(req
); // include hi_IN_BHOPAL
2357 // No matter what, unregister
2358 Collator::unregister(key
, ec
);
2359 if (U_FAILURE(ec
)) {
2360 errln("FAIL: Collator::unregister() failed");
2366 // After unregistering, should behave normally again
2367 coll
= Collator::createInstance(reqLoc
, ec
);
2368 if (U_FAILURE(ec
)) {
2369 errln("FAIL: Collator::createInstance failed");
2371 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2372 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2373 if (U_FAILURE(ec
)) {
2374 errln("FAIL: Collator::getLocale() failed");
2376 _checklocs("Collator(unregistered)", req
, valid
, actual
);
2382 checkRegisteredCollators(NULL
); // extra should be gone again
2388 #if !UCONFIG_NO_COLLATION
2390 * Compare Collator::getAvailableLocales(int) [ "old", returning an array ]
2391 * with Collator::getAvailableLocales() [ "new", returning a StringEnumeration ]
2392 * These should be identical (check their API docs) EXCEPT that
2393 * if expectExtra is non-NULL, it will be in the "new" array but not "old".
2394 * Does not return any status but calls errln on error.
2395 * @param expectExtra an extra locale, will be in "new" but not "old". Or NULL.
2397 void LocaleTest::checkRegisteredCollators(const char *expectExtra
) {
2398 UErrorCode status
= U_ZERO_ERROR
;
2399 int32_t count1
=0,count2
=0;
2400 Hashtable
oldHash(status
);
2401 Hashtable
newHash(status
);
2402 assertSuccess(WHERE
, status
);
2404 UnicodeString
expectStr(expectExtra
?expectExtra
:"n/a", "");
2406 // the 'old' list (non enumeration)
2407 const Locale
* oldList
= Collator::getAvailableLocales(count1
);
2408 if(oldList
== NULL
) {
2409 dataerrln("Error: Collator::getAvailableLocales(count) returned NULL");
2413 // the 'new' list (enumeration)
2414 LocalPointer
<StringEnumeration
> newEnum(Collator::getAvailableLocales());
2415 if(newEnum
.isNull()) {
2416 errln("Error: collator::getAvailableLocales() returned NULL");
2420 // OK. Let's add all of the OLD
2421 // then check for any in the NEW not in OLD
2422 // then check for any in OLD not in NEW.
2424 // 1. add all of OLD
2425 for(int32_t i
=0;i
<count1
;i
++) {
2426 const UnicodeString
key(oldList
[i
].getName(), "");
2427 int32_t oldI
= oldHash
.puti(key
, 1, status
);
2429 errln("Error: duplicate key %s in Collator::getAvailableLocales(count) list.\n",
2430 oldList
[i
].getName());
2433 if(expectExtra
!= NULL
&& !strcmp(expectExtra
, oldList
[i
].getName())) {
2434 errln("Inexplicably, Collator::getAvailableCollators(count) had registered collator %s. This shouldn't happen, so I am going to consider it an error.\n", expectExtra
);
2438 // 2. add all of NEW
2439 const UnicodeString
*locStr
;
2440 UBool foundExpected
= FALSE
;
2441 while((locStr
= newEnum
->snext(status
)) && U_SUCCESS(status
)) {
2444 if(expectExtra
!= NULL
&& expectStr
== *locStr
) {
2445 foundExpected
= TRUE
;
2446 logln(UnicodeString("Found expected registered collator: ","") + expectStr
);
2448 (void)foundExpected
; // Hush unused variable compiler warning.
2450 if( oldHash
.geti(*locStr
) == 0 ) {
2451 if(expectExtra
!= NULL
&& expectStr
==*locStr
) {
2452 logln(UnicodeString("As expected, Collator::getAvailableLocales(count) is missing registered collator ") + expectStr
);
2454 errln(UnicodeString("Error: Collator::getAvailableLocales(count) is missing: ","")
2458 newHash
.puti(*locStr
, 1, status
);
2461 // 3. check all of OLD again
2462 for(int32_t i
=0;i
<count1
;i
++) {
2463 const UnicodeString
key(oldList
[i
].getName(), "");
2464 int32_t newI
= newHash
.geti(key
);
2466 errln(UnicodeString("Error: Collator::getAvailableLocales() is missing: ","")
2471 int32_t expectCount2
= count1
;
2472 if(expectExtra
!= NULL
) {
2473 expectCount2
++; // if an extra item registered, bump the expect count
2476 assertEquals("Collator::getAvail() count", expectCount2
, count2
);
2482 void LocaleTest::TestVariantWithOutCountry(void) {
2483 Locale
loc("en","","POSIX");
2484 if (0 != strcmp(loc
.getVariant(), "POSIX")) {
2485 errln("FAIL: en__POSIX didn't get parsed correctly - name is %s - expected %s got %s", loc
.getName(), "POSIX", loc
.getVariant());
2487 Locale
loc2("en","","FOUR");
2488 if (0 != strcmp(loc2
.getVariant(), "FOUR")) {
2489 errln("FAIL: en__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc2
.getName(), "FOUR", loc2
.getVariant());
2491 Locale
loc3("en","Latn","","FOUR");
2492 if (0 != strcmp(loc3
.getVariant(), "FOUR")) {
2493 errln("FAIL: en_Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc3
.getName(), "FOUR", loc3
.getVariant());
2495 Locale
loc4("","Latn","","FOUR");
2496 if (0 != strcmp(loc4
.getVariant(), "FOUR")) {
2497 errln("FAIL: _Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc4
.getName(), "FOUR", loc4
.getVariant());
2499 Locale
loc5("","Latn","US","FOUR");
2500 if (0 != strcmp(loc5
.getVariant(), "FOUR")) {
2501 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc5
.getName(), "FOUR", loc5
.getVariant());
2503 Locale
loc6("de-1901");
2504 if (0 != strcmp(loc6
.getVariant(), "1901")) {
2505 errln("FAIL: de-1901 didn't get parsed correctly - name is %s - expected %s got %s", loc6
.getName(), "1901", loc6
.getVariant());
2509 static Locale
_canonicalize(int32_t selector
, /* 0==createFromName, 1==createCanonical, 2==Locale ct */
2510 const char* localeID
) {
2513 return Locale::createFromName(localeID
);
2515 return Locale::createCanonical(localeID
);
2517 return Locale(localeID
);
2523 void LocaleTest::TestCanonicalization(void)
2525 static const struct {
2526 const char *localeID
; /* input */
2527 const char *getNameID
; /* expected getName() result */
2528 const char *canonicalID
; /* expected canonicalize() result */
2530 { "ca_ES-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2531 "ca_ES_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2532 "ca_ES_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2533 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2534 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2535 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2536 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2537 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2538 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2539 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2540 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2541 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ_EURO" }, /* qz-qz uses private use iso codes */
2542 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
2543 // TODO: unify this behavior
2544 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
2545 { "de-1901", "de__1901", "de__1901" }, /* registered name */
2546 { "de-1906", "de__1906", "de__1906" }, /* registered name */
2548 /* posix behavior that used to be performed by getName */
2549 { "mr.utf8", "mr.utf8", "mr" },
2550 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2551 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2552 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2553 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2554 { "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 */
2556 /* fleshing out canonicalization */
2557 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2558 { "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" },
2559 /* already-canonical ids are not changed */
2560 { "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" },
2561 /* norwegian is just too weird, if we handle things in their full generality */
2562 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2564 /* test cases reflecting internal resource bundle usage */
2565 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2566 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2567 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
2569 // Before ICU 64, ICU locale canonicalization had some additional mappings.
2570 // They were removed for ICU-20187 "drop support for long-obsolete locale ID variants".
2571 // The following now use standard canonicalization.
2572 // Apple ICU restores these first 3 mappings deleted in open ICU 64
2573 { "", "", "en_US_POSIX" },
2574 { "C", "c", "en_US_POSIX" },
2575 { "POSIX", "posix", "en_US_POSIX" },
2577 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES_PREEURO" },
2578 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT_PREEURO" },
2579 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE_PREEURO" },
2580 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU_PREEURO" },
2581 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR_PREEURO" },
2582 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE_PREEURO" },
2583 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE_PREEURO" },
2584 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES_PREEURO" },
2585 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES_PREEURO" },
2586 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI_PREEURO" },
2587 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE_PREEURO" },
2588 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR_PREEURO" },
2589 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU_PREEURO" },
2590 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE_PREEURO" },
2591 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES_PREEURO" },
2592 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT_PREEURO" },
2593 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE_PREEURO" },
2594 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL_PREEURO" },
2595 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT_PREEURO" },
2596 { "de__PHONEBOOK", "de__PHONEBOOK", "de__PHONEBOOK" },
2597 { "en_GB_EURO", "en_GB_EURO", "en_GB_EURO" },
2598 { "en_GB@EURO", "en_GB@EURO", "en_GB_EURO" }, /* POSIX ID */
2599 { "es__TRADITIONAL", "es__TRADITIONAL", "es__TRADITIONAL" },
2600 { "hi__DIRECT", "hi__DIRECT", "hi__DIRECT" },
2601 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL" },
2602 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH_TRADITIONAL" },
2603 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW_STROKE" },
2604 { "zh__PINYIN", "zh__PINYIN", "zh__PINYIN" },
2605 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_SP_CYRL" }, /* .NET name */
2606 { "sr-SP-Latn", "sr_SP_LATN", "sr_SP_LATN" }, /* .NET name */
2607 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_YU_CYRILLIC" }, /* Linux name */
2608 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_UZ_CYRL" }, /* .NET name */
2609 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_UZ_LATN" }, /* .NET name */
2610 { "zh-CHS", "zh_CHS", "zh_CHS" }, /* .NET name */
2611 { "zh-CHT", "zh_CHT", "zh_CHT" }, /* .NET name This may change back to zh_Hant */
2612 /* PRE_EURO and EURO conversions don't affect other keywords */
2613 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES_PREEURO@calendar=Japanese" },
2614 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah" },
2615 /* currency keyword overrides PRE_EURO and EURO currency */
2616 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR" },
2617 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP" },
2620 static const char* label
[] = { "createFromName", "createCanonical", "Locale" };
2624 for (i
=0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2625 for (j
=0; j
<3; ++j
) {
2626 const char* expected
= (j
==1) ? testCases
[i
].canonicalID
: testCases
[i
].getNameID
;
2627 Locale loc
= _canonicalize(j
, testCases
[i
].localeID
);
2628 const char* getName
= loc
.isBogus() ? "BOGUS" : loc
.getName();
2629 if(uprv_strcmp(expected
, getName
) != 0) {
2630 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"",
2631 label
[j
], testCases
[i
].localeID
, getName
, expected
);
2633 logln("Ok: %s(%s) => \"%s\"",
2634 label
[j
], testCases
[i
].localeID
, getName
);
2640 void LocaleTest::TestCurrencyByDate(void)
2642 #if !UCONFIG_NO_FORMATTING
2643 UErrorCode status
= U_ZERO_ERROR
;
2644 UDate date
= uprv_getUTCtime();
2648 UnicodeString tempStr
, resultStr
;
2650 // Cycle through historical currencies
2651 date
= (UDate
)-630720000000.0; // pre 1961 - no currency defined
2652 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2655 errcheckln(status
, "FAIL: didn't return 0 for eo_AM - %s", u_errorName(status
));
2657 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2659 errcheckln(status
, "FAIL: eo_AM didn't return NULL - %s", u_errorName(status
));
2661 status
= U_ZERO_ERROR
;
2663 date
= (UDate
)0.0; // 1970 - one currency defined
2664 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2667 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2669 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2671 resultStr
.setTo("SUR");
2672 if (resultStr
!= tempStr
) {
2673 errcheckln(status
, "FAIL: didn't return SUR for eo_AM - %s", u_errorName(status
));
2676 date
= (UDate
)693792000000.0; // 1992 - one currency defined
2677 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2680 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2682 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2684 resultStr
.setTo("RUR");
2685 if (resultStr
!= tempStr
) {
2686 errcheckln(status
, "FAIL: didn't return RUR for eo_AM - %s", u_errorName(status
));
2689 date
= (UDate
)977616000000.0; // post 1993 - one currency defined
2690 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2693 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2695 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2697 resultStr
.setTo("AMD");
2698 if (resultStr
!= tempStr
) {
2699 errcheckln(status
, "FAIL: didn't return AMD for eo_AM - %s", u_errorName(status
));
2702 // Locale AD has multiple currencies at once
2703 date
= (UDate
)977616000000.0; // year 2001
2704 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2707 errcheckln(status
, "FAIL: didn't return 4 for eo_AD - %s", u_errorName(status
));
2709 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2711 resultStr
.setTo("EUR");
2712 if (resultStr
!= tempStr
) {
2713 errcheckln(status
, "FAIL: didn't return EUR for eo_AD - %s", u_errorName(status
));
2715 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2717 resultStr
.setTo("ESP");
2718 if (resultStr
!= tempStr
) {
2719 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2721 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2723 resultStr
.setTo("FRF");
2724 if (resultStr
!= tempStr
) {
2725 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2727 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 4, TMP
, 4, &status
);
2729 resultStr
.setTo("ADP");
2730 if (resultStr
!= tempStr
) {
2731 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2734 date
= (UDate
)0.0; // year 1970
2735 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2738 errcheckln(status
, "FAIL: didn't return 3 for eo_AD - %s", u_errorName(status
));
2740 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2742 resultStr
.setTo("ESP");
2743 if (resultStr
!= tempStr
) {
2744 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2746 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2748 resultStr
.setTo("FRF");
2749 if (resultStr
!= tempStr
) {
2750 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2752 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2754 resultStr
.setTo("ADP");
2755 if (resultStr
!= tempStr
) {
2756 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2759 date
= (UDate
)-630720000000.0; // year 1950
2760 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2763 errcheckln(status
, "FAIL: didn't return 2 for eo_AD - %s", u_errorName(status
));
2765 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2767 resultStr
.setTo("ESP");
2768 if (resultStr
!= tempStr
) {
2769 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2771 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2773 resultStr
.setTo("ADP");
2774 if (resultStr
!= tempStr
) {
2775 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2778 date
= (UDate
)-2207520000000.0; // year 1900
2779 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2782 errcheckln(status
, "FAIL: didn't return 1 for eo_AD - %s", u_errorName(status
));
2784 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2786 resultStr
.setTo("ESP");
2787 if (resultStr
!= tempStr
) {
2788 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2791 // Locale UA has gap between years 1994 - 1996
2792 date
= (UDate
)788400000000.0;
2793 index
= ucurr_countCurrencies("eo_UA", date
, &status
);
2796 errcheckln(status
, "FAIL: didn't return 0 for eo_UA - %s", u_errorName(status
));
2798 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, index
, TMP
, 4, &status
);
2800 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2802 status
= U_ZERO_ERROR
;
2804 // Test index bounds
2805 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 100, TMP
, 4, &status
);
2807 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2809 status
= U_ZERO_ERROR
;
2811 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 0, TMP
, 4, &status
);
2813 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2815 status
= U_ZERO_ERROR
;
2817 // Test for bogus locale
2818 index
= ucurr_countCurrencies("eo_QQ", date
, &status
);
2821 errcheckln(status
, "FAIL: didn't return 0 for eo_QQ - %s", u_errorName(status
));
2823 status
= U_ZERO_ERROR
;
2824 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 1, TMP
, 4, &status
);
2826 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2828 status
= U_ZERO_ERROR
;
2829 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 0, TMP
, 4, &status
);
2831 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2833 status
= U_ZERO_ERROR
;
2835 // Cycle through histrocial currencies
2836 date
= (UDate
)977616000000.0; // 2001 - one currency
2837 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2840 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2842 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2844 resultStr
.setTo("AOA");
2845 if (resultStr
!= tempStr
) {
2846 errcheckln(status
, "FAIL: didn't return AOA for eo_AO - %s", u_errorName(status
));
2849 date
= (UDate
)819936000000.0; // 1996 - 2 currencies
2850 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2853 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2855 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2857 resultStr
.setTo("AOR");
2858 if (resultStr
!= tempStr
) {
2859 errcheckln(status
, "FAIL: didn't return AOR for eo_AO - %s", u_errorName(status
));
2861 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2863 resultStr
.setTo("AON");
2864 if (resultStr
!= tempStr
) {
2865 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2868 date
= (UDate
)662256000000.0; // 1991 - 2 currencies
2869 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2872 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2874 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2876 resultStr
.setTo("AON");
2877 if (resultStr
!= tempStr
) {
2878 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2880 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2882 resultStr
.setTo("AOK");
2883 if (resultStr
!= tempStr
) {
2884 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2887 date
= (UDate
)315360000000.0; // 1980 - one currency
2888 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2891 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2893 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2895 resultStr
.setTo("AOK");
2896 if (resultStr
!= tempStr
) {
2897 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2900 date
= (UDate
)0.0; // 1970 - no currencies
2901 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2904 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2906 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2908 errcheckln(status
, "FAIL: eo_AO didn't return NULL - %s", u_errorName(status
));
2910 status
= U_ZERO_ERROR
;
2912 // Test with currency keyword override
2913 date
= (UDate
)977616000000.0; // 2001 - two currencies
2914 index
= ucurr_countCurrencies("eo_DE@currency=DEM", date
, &status
);
2917 errcheckln(status
, "FAIL: didn't return 2 for eo_DE@currency=DEM - %s", u_errorName(status
));
2919 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 1, TMP
, 4, &status
);
2921 resultStr
.setTo("EUR");
2922 if (resultStr
!= tempStr
) {
2923 errcheckln(status
, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s", u_errorName(status
));
2925 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 2, TMP
, 4, &status
);
2927 resultStr
.setTo("DEM");
2928 if (resultStr
!= tempStr
) {
2929 errcheckln(status
, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s", u_errorName(status
));
2932 // Test Euro Support
2933 status
= U_ZERO_ERROR
; // reset
2934 date
= uprv_getUTCtime();
2937 ucurr_forLocaleAndDate("en_US", date
, 1, USD
, 4, &status
);
2940 ucurr_forLocaleAndDate("ja_JP", date
, 1, YEN
, 4, &status
);
2942 ucurr_forLocaleAndDate("en_US", date
, 1, TMP
, 4, &status
);
2943 if (u_strcmp(USD
, TMP
) != 0) {
2944 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
2946 ucurr_forLocaleAndDate("en_US_Q", date
, 1, TMP
, 4, &status
);
2947 if (u_strcmp(USD
, TMP
) != 0) {
2948 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
2950 status
= U_ZERO_ERROR
; // reset
2954 void LocaleTest::TestGetVariantWithKeywords(void)
2956 Locale
l("en_US_VALLEY@foo=value");
2957 const char *variant
= l
.getVariant();
2959 test_assert(strcmp("VALLEY", variant
) == 0);
2961 UErrorCode status
= U_ZERO_ERROR
;
2963 int32_t len
= l
.getKeywordValue("foo", buffer
, 50, status
);
2965 test_assert(strcmp("value", buffer
) == 0);
2968 void LocaleTest::TestIsRightToLeft() {
2969 assertFalse("root LTR", Locale::getRoot().isRightToLeft());
2970 assertFalse("zh LTR", Locale::getChinese().isRightToLeft());
2971 assertTrue("ar RTL", Locale("ar").isRightToLeft());
2972 assertTrue("und-EG RTL", Locale("und-EG").isRightToLeft(), FALSE
, TRUE
);
2973 assertFalse("fa-Cyrl LTR", Locale("fa-Cyrl").isRightToLeft());
2974 assertTrue("en-Hebr RTL", Locale("en-Hebr").isRightToLeft());
2975 assertTrue("ckb RTL", Locale("ckb").isRightToLeft(), FALSE
, TRUE
); // Sorani Kurdish
2976 assertFalse("fil LTR", Locale("fil").isRightToLeft());
2977 assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft());
2978 // Additional Apple tests for rdar://51447187
2979 assertTrue("sd RTL", Locale("sd").isRightToLeft());
2980 assertTrue("sd_Arab RTL", Locale("sd_Arab").isRightToLeft());
2981 assertFalse("sd_Deva LTR", Locale("sd_Deva").isRightToLeft());
2982 assertFalse("mni_Beng LTR", Locale("mni_Beng").isRightToLeft());
2983 assertFalse("mni_Mtei LTR", Locale("mni_Mtei").isRightToLeft());
2984 assertFalse("sat_Deva LTR", Locale("sat_Deva").isRightToLeft());
2985 assertFalse("sat_Olck LTR", Locale("sat_Olck").isRightToLeft());
2986 assertTrue("ks RTL", Locale("ks").isRightToLeft());
2987 assertTrue("ks_Arab RTL", Locale("ks_Arab").isRightToLeft());
2988 assertTrue("ks_Aran RTL", Locale("ks_Aran").isRightToLeft());
2989 assertFalse("ks_Deva LTR", Locale("ks_Deva").isRightToLeft());
2990 assertFalse("pa LTR", Locale("pa").isRightToLeft());
2991 assertFalse("pa_Guru LTR", Locale("pa_Guru").isRightToLeft());
2992 assertTrue("pa_Arab RTL", Locale("pa_Arab").isRightToLeft());
2993 assertTrue("pa_Aran RTL", Locale("pa_Aran").isRightToLeft());
2994 assertTrue("ur RTL", Locale("ur").isRightToLeft());
2995 assertTrue("ur_Arab RTL", Locale("ur_Arab").isRightToLeft());
2996 assertTrue("ur_Aran RTL", Locale("ur_Aran").isRightToLeft());
2999 void LocaleTest::TestBug11421() {
3000 Locale::getDefault().getBaseName();
3002 const Locale
*localeList
= Locale::getAvailableLocales(numLocales
);
3003 for (int localeIndex
= 0; localeIndex
< numLocales
; localeIndex
++) {
3004 const Locale
&loc
= localeList
[localeIndex
];
3005 if (strncmp(loc
.getName(), loc
.getBaseName(), strlen(loc
.getBaseName()))) {
3006 errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"",
3007 __FILE__
, __LINE__
, loc
.getName(), loc
.getBaseName());
3013 // TestBug13277. The failure manifests as valgrind errors.
3014 // See the trac ticket for details.
3017 void LocaleTest::TestBug13277() {
3018 UErrorCode status
= U_ZERO_ERROR
;
3019 CharString
name("en-us-x-foo", -1, status
);
3020 while (name
.length() < 152) {
3021 name
.append("-x-foo", -1, status
);
3024 while (name
.length() < 160) {
3025 name
.append('z', status
);
3026 Locale
loc(name
.data(), nullptr, nullptr, nullptr);
3030 // TestBug13554 Check for read past end of array in getPosixID().
3031 // The bug shows as an Address Sanitizer failure.
3033 void LocaleTest::TestBug13554() {
3034 UErrorCode status
= U_ZERO_ERROR
;
3035 const int BUFFER_SIZE
= 100;
3036 char posixID
[BUFFER_SIZE
];
3038 for (uint32_t hostid
= 0; hostid
< 0x500; ++hostid
) {
3039 status
= U_ZERO_ERROR
;
3040 uprv_convertToPosix(hostid
, posixID
, BUFFER_SIZE
, &status
);
3044 void LocaleTest::TestBug20410() {
3045 IcuTestErrorCode
status(*this, "TestBug20410()");
3047 static const char tag1
[] = "art-lojban-x-0";
3048 static const Locale
expected1("jbo@x=0");
3049 Locale result1
= Locale::forLanguageTag(tag1
, status
);
3050 status
.errIfFailureAndReset("\"%s\"", tag1
);
3051 assertEquals(tag1
, expected1
.getName(), result1
.getName());
3053 static const char tag2
[] = "zh-xiang-u-nu-thai-x-0";
3054 static const Locale
expected2("hsn@numbers=thai;x=0");
3055 Locale result2
= Locale::forLanguageTag(tag2
, status
);
3056 status
.errIfFailureAndReset("\"%s\"", tag2
);
3057 assertEquals(tag2
, expected2
.getName(), result2
.getName());
3059 static const char locid3
[] = "art__lojban@x=0";
3060 Locale result3
= Locale::createCanonical(locid3
);
3061 static const Locale
expected3("art__LOJBAN@x=0");
3062 assertEquals(locid3
, expected3
.getName(), result3
.getName());
3064 static const char locid4
[] = "art-lojban-x-0";
3065 Locale result4
= Locale::createCanonical(locid4
);
3066 static const Locale
expected4("jbo@x=0");
3067 assertEquals(locid4
, expected4
.getName(), result4
.getName());
3070 void LocaleTest::TestForLanguageTag() {
3071 IcuTestErrorCode
status(*this, "TestForLanguageTag()");
3073 static const char tag_en
[] = "en-US";
3074 static const char tag_oed
[] = "en-GB-oed";
3075 static const char tag_af
[] = "af-t-ar-i0-handwrit-u-ca-coptic-x-foo";
3076 static const char tag_ill
[] = "!";
3077 static const char tag_no_nul
[] = { 'e', 'n', '-', 'G', 'B' };
3078 static const char tag_ext
[] = "en-GB-1-abc-efg-a-xyz";
3080 static const Locale
loc_en("en_US");
3081 static const Locale
loc_oed("en_GB_OXENDICT");
3082 static const Locale
loc_af("af@calendar=coptic;t=ar-i0-handwrit;x=foo");
3083 static const Locale
loc_null("");
3084 static const Locale
loc_gb("en_GB");
3085 static const Locale
loc_ext("en_GB@1=abc-efg;a=xyz");
3087 Locale result_en
= Locale::forLanguageTag(tag_en
, status
);
3088 status
.errIfFailureAndReset("\"%s\"", tag_en
);
3089 assertEquals(tag_en
, loc_en
.getName(), result_en
.getName());
3091 Locale result_oed
= Locale::forLanguageTag(tag_oed
, status
);
3092 status
.errIfFailureAndReset("\"%s\"", tag_oed
);
3093 assertEquals(tag_oed
, loc_oed
.getName(), result_oed
.getName());
3095 Locale result_af
= Locale::forLanguageTag(tag_af
, status
);
3096 status
.errIfFailureAndReset("\"%s\"", tag_af
);
3097 assertEquals(tag_af
, loc_af
.getName(), result_af
.getName());
3099 Locale result_ill
= Locale::forLanguageTag(tag_ill
, status
);
3100 assertEquals(tag_ill
, U_ILLEGAL_ARGUMENT_ERROR
, status
.reset());
3101 assertTrue(result_ill
.getName(), result_ill
.isBogus());
3103 Locale result_null
= Locale::forLanguageTag(nullptr, status
);
3104 status
.errIfFailureAndReset("nullptr");
3105 assertEquals("nullptr", loc_null
.getName(), result_null
.getName());
3107 StringPiece
sp_substr(tag_oed
, 5); // "en-GB", no NUL.
3108 Locale result_substr
= Locale::forLanguageTag(sp_substr
, status
);
3109 status
.errIfFailureAndReset("\"%.*s\"", sp_substr
.size(), sp_substr
.data());
3110 assertEquals(CharString(sp_substr
, status
).data(),
3111 loc_gb
.getName(), result_substr
.getName());
3113 StringPiece
sp_no_nul(tag_no_nul
, sizeof tag_no_nul
); // "en-GB", no NUL.
3114 Locale result_no_nul
= Locale::forLanguageTag(sp_no_nul
, status
);
3115 status
.errIfFailureAndReset("\"%.*s\"", sp_no_nul
.size(), sp_no_nul
.data());
3116 assertEquals(CharString(sp_no_nul
, status
).data(),
3117 loc_gb
.getName(), result_no_nul
.getName());
3119 Locale result_ext
= Locale::forLanguageTag(tag_ext
, status
);
3120 status
.errIfFailureAndReset("\"%s\"", tag_ext
);
3121 assertEquals(tag_ext
, loc_ext
.getName(), result_ext
.getName());
3124 void LocaleTest::TestToLanguageTag() {
3125 IcuTestErrorCode
status(*this, "TestToLanguageTag()");
3127 static const Locale
loc_c("en_US_POSIX");
3128 static const Locale
loc_en("en_US");
3129 static const Locale
loc_af("af@calendar=coptic;t=ar-i0-handwrit;x=foo");
3130 static const Locale
loc_ext("en@0=abc;a=xyz");
3131 static const Locale
loc_empty("");
3132 static const Locale
loc_ill("!");
3134 static const char tag_c
[] = "en-US-u-va-posix";
3135 static const char tag_en
[] = "en-US";
3136 static const char tag_af
[] = "af-t-ar-i0-handwrit-u-ca-coptic-x-foo";
3137 static const char tag_ext
[] = "en-0-abc-a-xyz";
3138 static const char tag_und
[] = "und";
3141 StringByteSink
<std::string
> sink(&result
);
3142 loc_c
.toLanguageTag(sink
, status
);
3143 status
.errIfFailureAndReset("\"%s\"", loc_c
.getName());
3144 assertEquals(loc_c
.getName(), tag_c
, result
.c_str());
3146 std::string result_c
= loc_c
.toLanguageTag
<std::string
>(status
);
3147 status
.errIfFailureAndReset("\"%s\"", loc_c
.getName());
3148 assertEquals(loc_c
.getName(), tag_c
, result_c
.c_str());
3150 std::string result_en
= loc_en
.toLanguageTag
<std::string
>(status
);
3151 status
.errIfFailureAndReset("\"%s\"", loc_en
.getName());
3152 assertEquals(loc_en
.getName(), tag_en
, result_en
.c_str());
3154 std::string result_af
= loc_af
.toLanguageTag
<std::string
>(status
);
3155 status
.errIfFailureAndReset("\"%s\"", loc_af
.getName());
3156 assertEquals(loc_af
.getName(), tag_af
, result_af
.c_str());
3158 std::string result_ext
= loc_ext
.toLanguageTag
<std::string
>(status
);
3159 status
.errIfFailureAndReset("\"%s\"", loc_ext
.getName());
3160 assertEquals(loc_ext
.getName(), tag_ext
, result_ext
.c_str());
3162 std::string result_empty
= loc_empty
.toLanguageTag
<std::string
>(status
);
3163 status
.errIfFailureAndReset("\"%s\"", loc_empty
.getName());
3164 assertEquals(loc_empty
.getName(), tag_und
, result_empty
.c_str());
3166 std::string result_ill
= loc_ill
.toLanguageTag
<std::string
>(status
);
3167 status
.errIfFailureAndReset("\"%s\"", loc_ill
.getName());
3168 assertEquals(loc_ill
.getName(), tag_und
, result_ill
.c_str());
3171 loc_bogus
.setToBogus();
3172 std::string result_bogus
= loc_bogus
.toLanguageTag
<std::string
>(status
);
3173 assertEquals("bogus", U_ILLEGAL_ARGUMENT_ERROR
, status
.reset());
3174 assertTrue(result_bogus
.c_str(), result_bogus
.empty());
3177 void LocaleTest::TestMoveAssign() {
3178 // ULOC_FULLNAME_CAPACITY == 157 (uloc.h)
3179 Locale
l1("de@collation=phonebook;x="
3180 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3181 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3182 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3188 assertTrue("l1 == l3", l1
== l3
);
3190 assertTrue("l1 == l2", l1
== l2
);
3191 assertTrue("l2 != l3", l2
.getName() != l3
.getName());
3194 // This should remain true also after l3 has been destructed.
3195 assertTrue("l1 == l2, again", l1
== l2
);
3197 Locale
l4("de@collation=phonebook");
3202 assertTrue("l4 == l6", l4
== l6
);
3204 assertTrue("l4 == l5", l4
== l5
);
3205 assertTrue("l5 != l6", l5
.getName() != l6
.getName());
3208 // This should remain true also after l6 has been destructed.
3209 assertTrue("l4 == l5, again", l4
== l5
);
3211 Locale
l7("vo_Cyrl_AQ_EURO");
3216 assertTrue("l7 == l9", l7
== l9
);
3218 assertTrue("l7 == l8", l7
== l8
);
3219 assertTrue("l8 != l9", l8
.getName() != l9
.getName());
3222 // This should remain true also after l9 has been destructed.
3223 assertTrue("l7 == l8, again", l7
== l8
);
3225 assertEquals("language", l7
.getLanguage(), l8
.getLanguage());
3226 assertEquals("script", l7
.getScript(), l8
.getScript());
3227 assertEquals("country", l7
.getCountry(), l8
.getCountry());
3228 assertEquals("variant", l7
.getVariant(), l8
.getVariant());
3229 assertEquals("bogus", l7
.isBogus(), l8
.isBogus());
3232 void LocaleTest::TestMoveCtor() {
3233 // ULOC_FULLNAME_CAPACITY == 157 (uloc.h)
3234 Locale
l1("de@collation=phonebook;x="
3235 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3236 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3237 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3241 assertTrue("l1 == l3", l1
== l3
);
3242 Locale
l2(std::move(l3
));
3243 assertTrue("l1 == l2", l1
== l2
);
3244 assertTrue("l2 != l3", l2
.getName() != l3
.getName());
3246 Locale
l4("de@collation=phonebook");
3249 assertTrue("l4 == l6", l4
== l6
);
3250 Locale
l5(std::move(l6
));
3251 assertTrue("l4 == l5", l4
== l5
);
3252 assertTrue("l5 != l6", l5
.getName() != l6
.getName());
3254 Locale
l7("vo_Cyrl_AQ_EURO");
3257 assertTrue("l7 == l9", l7
== l9
);
3258 Locale
l8(std::move(l9
));
3259 assertTrue("l7 == l8", l7
== l8
);
3260 assertTrue("l8 != l9", l8
.getName() != l9
.getName());
3262 assertEquals("language", l7
.getLanguage(), l8
.getLanguage());
3263 assertEquals("script", l7
.getScript(), l8
.getScript());
3264 assertEquals("country", l7
.getCountry(), l8
.getCountry());
3265 assertEquals("variant", l7
.getVariant(), l8
.getVariant());
3266 assertEquals("bogus", l7
.isBogus(), l8
.isBogus());
3269 void LocaleTest::TestBug20407iVariantPreferredValue() {
3270 IcuTestErrorCode
status(*this, "TestBug20407iVariantPreferredValue()");
3272 Locale l
= Locale::forLanguageTag("hy-arevela", status
);
3273 status
.errIfFailureAndReset("hy-arevela fail");
3274 assertTrue("!l.isBogus()", !l
.isBogus());
3276 std::string result
= l
.toLanguageTag
<std::string
>(status
);
3277 assertEquals(l
.getName(), "hy", result
.c_str());
3279 l
= Locale::forLanguageTag("hy-arevmda", status
);
3280 status
.errIfFailureAndReset("hy-arevmda");
3281 assertTrue("!l.isBogus()", !l
.isBogus());
3283 result
= l
.toLanguageTag
<std::string
>(status
);
3284 assertEquals(l
.getName(), "hyw", result
.c_str());
3287 void LocaleTest::TestBug13417VeryLongLanguageTag() {
3288 IcuTestErrorCode
status(*this, "TestBug13417VeryLongLanguageTag()");
3290 static const char tag
[] =
3292 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3293 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3294 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3298 Locale l
= Locale::forLanguageTag(tag
, status
);
3299 status
.errIfFailureAndReset("\"%s\"", tag
);
3300 assertTrue("!l.isBogus()", !l
.isBogus());
3302 std::string result
= l
.toLanguageTag
<std::string
>(status
);
3303 status
.errIfFailureAndReset("\"%s\"", l
.getName());
3304 assertEquals("equals", tag
, result
.c_str());
3307 void LocaleTest::TestBug11053UnderlineTimeZone() {
3308 static const char* const tz_in_ext
[] = {
3370 static const char* const tzname_with_underline
[] = {
3371 "America/Buenos_Aires",
3372 "America/Coral_Harbour",
3373 "America/Los_Angeles",
3374 "America/Mexico_City",
3376 "America/Rio_Branco",
3377 "America/Sao_Paulo",
3379 "America/St_Thomas",
3380 "Australia/Broken_Hill",
3381 "Australia/Lord_Howe",
3382 "Pacific/Pago_Pago",
3384 std::string locale_str
;
3385 for (int32_t i
= 0; i
< UPRV_LENGTHOF(tz_in_ext
); i
++) {
3386 locale_str
= "en-u-tz-";
3387 locale_str
+= tz_in_ext
[i
];
3388 Locale
l(locale_str
.c_str());
3389 assertTrue((locale_str
+ " !l.isBogus()").c_str(), !l
.isBogus());
3391 for (int32_t i
= 0; i
< UPRV_LENGTHOF(tzname_with_underline
); i
++) {
3392 locale_str
= "en@timezone=";
3393 locale_str
+= tzname_with_underline
[i
];
3394 Locale
l(locale_str
.c_str());
3395 assertTrue((locale_str
+ " !l.isBogus()").c_str(), !l
.isBogus());
3397 locale_str
= "en_US@timezone=America/Coral_Harbour";
3398 Locale
l2(locale_str
.c_str());
3399 assertTrue((locale_str
+ " !l2.isBogus()").c_str(), !l2
.isBogus());
3400 locale_str
= "en_Latn@timezone=America/New_York";
3401 Locale
l3(locale_str
.c_str());
3402 assertTrue((locale_str
+ " !l3.isBogus()").c_str(), !l3
.isBogus());
3403 locale_str
= "en_Latn_US@timezone=Australia/Broken_Hill";
3404 Locale
l4(locale_str
.c_str());
3405 assertTrue((locale_str
+ " !l4.isBogus()").c_str(), !l4
.isBogus());
3406 locale_str
= "en-u-tz-ciabj";
3407 Locale
l5(locale_str
.c_str());
3408 assertTrue((locale_str
+ " !l5.isBogus()").c_str(), !l5
.isBogus());
3409 locale_str
= "en-US-u-tz-asppg";
3410 Locale
l6(locale_str
.c_str());
3411 assertTrue((locale_str
+ " !l6.isBogus()").c_str(), !l6
.isBogus());
3412 locale_str
= "fil-Latn-u-tz-cvrai";
3413 Locale
l7(locale_str
.c_str());
3414 assertTrue((locale_str
+ " !l7.isBogus()").c_str(), !l7
.isBogus());
3415 locale_str
= "fil-Latn-PH-u-tz-gsgrv";
3416 Locale
l8(locale_str
.c_str());
3417 assertTrue((locale_str
+ " !l8.isBogus()").c_str(), !l8
.isBogus());
3420 void LocaleTest::TestUnd() {
3421 IcuTestErrorCode
status(*this, "TestUnd()");
3423 static const char empty
[] = "";
3424 static const char root
[] = "root";
3425 static const char und
[] = "und";
3427 Locale
empty_ctor(empty
);
3428 Locale empty_tag
= Locale::forLanguageTag(empty
, status
);
3429 status
.errIfFailureAndReset("\"%s\"", empty
);
3431 Locale
root_ctor(root
);
3432 Locale root_tag
= Locale::forLanguageTag(root
, status
);
3433 Locale root_build
= LocaleBuilder().setLanguageTag(root
).build(status
);
3434 status
.errIfFailureAndReset("\"%s\"", root
);
3436 Locale
und_ctor(und
);
3437 Locale und_tag
= Locale::forLanguageTag(und
, status
);
3438 Locale und_build
= LocaleBuilder().setLanguageTag(und
).build(status
);
3439 status
.errIfFailureAndReset("\"%s\"", und
);
3441 assertEquals("getName() 1", empty
, empty_ctor
.getName());
3442 assertEquals("getName() 2", root
, root_ctor
.getName()); // open ICU expects empty
3443 assertEquals("getName() 3", und
, und_ctor
.getName()); // open ICU expects empty
3445 assertEquals("getName() 4", empty
, empty_tag
.getName());
3446 assertEquals("getName() 5", root
, root_tag
.getName()); // open ICU expects empty
3447 assertEquals("getName() 6", empty
, und_tag
.getName());
3449 assertEquals("getName() 7", root
, root_build
.getName()); // open ICU expects empty
3450 assertEquals("getName() 8", empty
, und_build
.getName());
3452 assertEquals("toLanguageTag() 1", und
, empty_ctor
.toLanguageTag
<std::string
>(status
).c_str());
3453 assertEquals("toLanguageTag() 2", root
, root_ctor
.toLanguageTag
<std::string
>(status
).c_str()); // open ICU expects und
3454 assertEquals("toLanguageTag() 3", und
, und_ctor
.toLanguageTag
<std::string
>(status
).c_str());
3455 status
.errIfFailureAndReset();
3457 assertEquals("toLanguageTag() 4", und
, empty_tag
.toLanguageTag
<std::string
>(status
).c_str());
3458 assertEquals("toLanguageTag() 5", root
, root_tag
.toLanguageTag
<std::string
>(status
).c_str()); // open ICU expects und
3459 assertEquals("toLanguageTag() 6", und
, und_tag
.toLanguageTag
<std::string
>(status
).c_str());
3460 status
.errIfFailureAndReset();
3462 assertEquals("toLanguageTag() 7", root
, root_build
.toLanguageTag
<std::string
>(status
).c_str()); // open ICU expects und
3463 assertEquals("toLanguageTag() 8", und
, und_build
.toLanguageTag
<std::string
>(status
).c_str());
3464 status
.errIfFailureAndReset();
3466 assertTrue("empty_ctor == empty_tag", empty_ctor
== empty_tag
);
3468 assertTrue("root_ctor == root_tag", root_ctor
== root_tag
);
3469 assertTrue("root_ctor == root_build", root_ctor
== root_build
);
3470 assertTrue("root_tag == root_build", root_tag
== root_build
);
3472 //assertTrue("und_ctor == und_tag", und_ctor == und_tag); // change from open ICU
3473 //assertTrue("und_ctor == und_build", und_ctor == und_build); // change from open ICU
3474 assertTrue("und_tag == und_build", und_tag
== und_build
);
3476 //assertTrue("empty_ctor == root_ctor", empty_ctor == root_ctor); // change from open ICU
3477 //assertTrue("empty_ctor == und_ctor", empty_ctor == und_ctor); // change from open ICU
3478 //assertTrue("root_ctor == und_ctor", root_ctor == und_ctor); // change from open ICU
3480 //assertTrue("empty_tag == root_tag", empty_tag == root_tag); // change from open ICU
3481 assertTrue("empty_tag == und_tag", empty_tag
== und_tag
);
3482 //assertTrue("root_tag == und_tag", root_tag == und_tag); // change from open ICU
3484 //assertTrue("root_build == und_build", root_build == und_build); // change from open ICU
3486 static const Locale
& displayLocale
= Locale::getEnglish();
3487 static const UnicodeString
displayName("Unknown language");
3488 static const UnicodeString
displayRoot("Root");
3489 static const UnicodeString
displayEmpty("");
3492 assertEquals("getDisplayName() 1", displayEmpty
, empty_ctor
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3493 assertEquals("getDisplayName() 2", displayRoot
, root_ctor
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3494 assertEquals("getDisplayName() 3", displayName
, und_ctor
.getDisplayName(displayLocale
, tmp
));
3496 assertEquals("getDisplayName() 4", displayEmpty
, empty_tag
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3497 assertEquals("getDisplayName() 5", displayRoot
, root_tag
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3498 assertEquals("getDisplayName() 6", displayEmpty
, und_tag
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3500 assertEquals("getDisplayName() 7", displayRoot
, root_build
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3501 assertEquals("getDisplayName() 8", displayEmpty
, und_build
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3504 void LocaleTest::TestUndScript() {
3505 IcuTestErrorCode
status(*this, "TestUndScript()");
3507 static const char id
[] = "_Cyrl";
3508 static const char tag
[] = "und-Cyrl";
3509 static const char script
[] = "Cyrl";
3510 static const char tag_
[] = "und_Cyrl";
3512 Locale
locale_ctor(id
);
3513 Locale
locale_legacy(tag
);
3514 Locale locale_tag
= Locale::forLanguageTag(tag
, status
);
3515 Locale locale_build
= LocaleBuilder().setScript(script
).build(status
);
3516 status
.errIfFailureAndReset("\"%s\"", tag
);
3518 assertEquals("getName() 1", id
, locale_ctor
.getName());
3519 assertEquals("getName() 2", tag_
, locale_legacy
.getName()); // change from open ICU
3520 assertEquals("getName() 3", id
, locale_tag
.getName());
3521 assertEquals("getName() 4", id
, locale_build
.getName());
3523 assertEquals("toLanguageTag()", tag
, locale_ctor
.toLanguageTag
<std::string
>(status
).c_str());
3524 assertEquals("toLanguageTag()", tag
, locale_legacy
.toLanguageTag
<std::string
>(status
).c_str());
3525 assertEquals("toLanguageTag()", tag
, locale_tag
.toLanguageTag
<std::string
>(status
).c_str());
3526 assertEquals("toLanguageTag()", tag
, locale_build
.toLanguageTag
<std::string
>(status
).c_str());
3527 status
.errIfFailureAndReset();
3529 static const Locale
& displayLocale
= Locale::getEnglish();
3530 static const UnicodeString
displayName("Unknown language (Cyrillic)");
3531 static const UnicodeString
displayScript("Cyrillic");
3534 assertEquals("getDisplayName() 1", displayScript
, locale_ctor
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3535 assertEquals("getDisplayName() 2", displayName
, locale_legacy
.getDisplayName(displayLocale
, tmp
));
3536 assertEquals("getDisplayName() 3", displayScript
, locale_tag
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3537 assertEquals("getDisplayName() 4", displayScript
, locale_build
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3540 void LocaleTest::TestUndRegion() {
3541 IcuTestErrorCode
status(*this, "TestUndRegion()");
3543 static const char id
[] = "_AQ";
3544 static const char tag
[] = "und-AQ";
3545 static const char region
[] = "AQ";
3546 static const char tag_
[] = "und_AQ";
3548 Locale
locale_ctor(id
);
3549 Locale
locale_legacy(tag
);
3550 Locale locale_tag
= Locale::forLanguageTag(tag
, status
);
3551 Locale locale_build
= LocaleBuilder().setRegion(region
).build(status
);
3552 status
.errIfFailureAndReset("\"%s\"", tag
);
3554 assertEquals("getName() 1", id
, locale_ctor
.getName());
3555 assertEquals("getName() 2", tag_
, locale_legacy
.getName()); // change from open ICU
3556 assertEquals("getName() 3", id
, locale_tag
.getName());
3557 assertEquals("getName() 4", id
, locale_build
.getName());
3559 assertEquals("toLanguageTag()", tag
, locale_ctor
.toLanguageTag
<std::string
>(status
).c_str());
3560 assertEquals("toLanguageTag()", tag
, locale_legacy
.toLanguageTag
<std::string
>(status
).c_str());
3561 assertEquals("toLanguageTag()", tag
, locale_tag
.toLanguageTag
<std::string
>(status
).c_str());
3562 assertEquals("toLanguageTag()", tag
, locale_build
.toLanguageTag
<std::string
>(status
).c_str());
3563 status
.errIfFailureAndReset();
3565 static const Locale
& displayLocale
= Locale::getEnglish();
3566 static const UnicodeString
displayName("Unknown language (Antarctica)");
3567 static const UnicodeString
displayRegion("Antarctica");
3570 assertEquals("getDisplayName() 1", displayRegion
, locale_ctor
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3571 assertEquals("getDisplayName() 2", displayName
, locale_legacy
.getDisplayName(displayLocale
, tmp
));
3572 assertEquals("getDisplayName() 3", displayRegion
, locale_tag
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3573 assertEquals("getDisplayName() 4", displayRegion
, locale_build
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3576 void LocaleTest::TestUndCAPI() {
3577 IcuTestErrorCode
status(*this, "TestUndCAPI()");
3579 static const char empty
[] = "";
3580 static const char root
[] = "root";
3581 static const char und
[] = "und";
3583 static const char empty_script
[] = "_Cyrl";
3584 static const char empty_region
[] = "_AQ";
3586 static const char und_script
[] = "und_Cyrl";
3587 static const char und_region
[] = "und_AQ";
3589 char tmp
[ULOC_FULLNAME_CAPACITY
];
3594 uprv_memset(tmp
, '!', sizeof tmp
);
3595 reslen
= uloc_getName(empty
, tmp
, sizeof tmp
, status
);
3596 status
.errIfFailureAndReset("\"%s\"", empty
);
3597 assertTrue("reslen >= 0", reslen
>= 0);
3598 assertEquals("uloc_getName() 1", empty
, tmp
);
3600 uprv_memset(tmp
, '!', sizeof tmp
);
3601 reslen
= uloc_getName(root
, tmp
, sizeof tmp
, status
);
3602 status
.errIfFailureAndReset("\"%s\"", root
);
3603 assertTrue("reslen >= 0", reslen
>= 0);
3604 assertEquals("uloc_getName() 2", root
, tmp
); // change from open ICU
3606 uprv_memset(tmp
, '!', sizeof tmp
);
3607 reslen
= uloc_getName(und
, tmp
, sizeof tmp
, status
);
3608 status
.errIfFailureAndReset("\"%s\"", und
);
3609 assertTrue("reslen >= 0", reslen
>= 0);
3610 assertEquals("uloc_getName() 3", und
, tmp
); // change from open ICU
3612 uprv_memset(tmp
, '!', sizeof tmp
);
3613 reslen
= uloc_getName(empty_script
, tmp
, sizeof tmp
, status
);
3614 status
.errIfFailureAndReset("\"%s\"", empty_script
);
3615 assertTrue("reslen >= 0", reslen
>= 0);
3616 assertEquals("uloc_getName() 4", empty_script
, tmp
);
3618 uprv_memset(tmp
, '!', sizeof tmp
);
3619 reslen
= uloc_getName(empty_region
, tmp
, sizeof tmp
, status
);
3620 status
.errIfFailureAndReset("\"%s\"", empty_region
);
3621 assertTrue("reslen >= 0", reslen
>= 0);
3622 assertEquals("uloc_getName() 5", empty_region
, tmp
);
3624 uprv_memset(tmp
, '!', sizeof tmp
);
3625 reslen
= uloc_getName(und_script
, tmp
, sizeof tmp
, status
);
3626 status
.errIfFailureAndReset("\"%s\"", und_script
);
3627 assertTrue("reslen >= 0", reslen
>= 0);
3628 assertEquals("uloc_getName() 6", und_script
, tmp
); // change from open ICU
3630 uprv_memset(tmp
, '!', sizeof tmp
);
3631 reslen
= uloc_getName(und_region
, tmp
, sizeof tmp
, status
);
3632 status
.errIfFailureAndReset("\"%s\"", und_region
);
3633 assertTrue("reslen >= 0", reslen
>= 0);
3634 assertEquals("uloc_getName() 7", und_region
, tmp
); // change from open ICU
3636 // uloc_getBaseName()
3638 uprv_memset(tmp
, '!', sizeof tmp
);
3639 reslen
= uloc_getBaseName(empty
, tmp
, sizeof tmp
, status
);
3640 status
.errIfFailureAndReset("\"%s\"", empty
);
3641 assertTrue("reslen >= 0", reslen
>= 0);
3642 assertEquals("uloc_getBaseName() 1", empty
, tmp
);
3644 uprv_memset(tmp
, '!', sizeof tmp
);
3645 reslen
= uloc_getBaseName(root
, tmp
, sizeof tmp
, status
);
3646 status
.errIfFailureAndReset("\"%s\"", root
);
3647 assertTrue("reslen >= 0", reslen
>= 0);
3648 assertEquals("uloc_getBaseName() 2", root
, tmp
); // change from open ICU
3650 uprv_memset(tmp
, '!', sizeof tmp
);
3651 reslen
= uloc_getBaseName(und
, tmp
, sizeof tmp
, status
);
3652 status
.errIfFailureAndReset("\"%s\"", und
);
3653 assertTrue("reslen >= 0", reslen
>= 0);
3654 assertEquals("uloc_getBaseName() 3", und
, tmp
); // change from open ICU
3656 uprv_memset(tmp
, '!', sizeof tmp
);
3657 reslen
= uloc_getBaseName(empty_script
, tmp
, sizeof tmp
, status
);
3658 status
.errIfFailureAndReset("\"%s\"", empty_script
);
3659 assertTrue("reslen >= 0", reslen
>= 0);
3660 assertEquals("uloc_getBaseName() 4", empty_script
, tmp
);
3662 uprv_memset(tmp
, '!', sizeof tmp
);
3663 reslen
= uloc_getBaseName(empty_region
, tmp
, sizeof tmp
, status
);
3664 status
.errIfFailureAndReset("\"%s\"", empty_region
);
3665 assertTrue("reslen >= 0", reslen
>= 0);
3666 assertEquals("uloc_getBaseName() 5", empty_region
, tmp
);
3668 uprv_memset(tmp
, '!', sizeof tmp
);
3669 reslen
= uloc_getBaseName(und_script
, tmp
, sizeof tmp
, status
);
3670 status
.errIfFailureAndReset("\"%s\"", und_script
);
3671 assertTrue("reslen >= 0", reslen
>= 0);
3672 assertEquals("uloc_getBaseName() 6", und_script
, tmp
); // change from open ICU
3674 uprv_memset(tmp
, '!', sizeof tmp
);
3675 reslen
= uloc_getBaseName(und_region
, tmp
, sizeof tmp
, status
);
3676 status
.errIfFailureAndReset("\"%s\"", und_region
);
3677 assertTrue("reslen >= 0", reslen
>= 0);
3678 assertEquals("uloc_getBaseName() 7", und_region
, tmp
); // change from open ICU
3682 uprv_memset(tmp
, '!', sizeof tmp
);
3683 reslen
= uloc_getParent(empty
, tmp
, sizeof tmp
, status
);
3684 status
.errIfFailureAndReset("\"%s\"", empty
);
3685 assertTrue("reslen >= 0", reslen
>= 0);
3686 assertEquals("uloc_getParent() 1", empty
, tmp
);
3688 uprv_memset(tmp
, '!', sizeof tmp
);
3689 reslen
= uloc_getParent(root
, tmp
, sizeof tmp
, status
);
3690 status
.errIfFailureAndReset("\"%s\"", root
);
3691 assertTrue("reslen >= 0", reslen
>= 0);
3692 assertEquals("uloc_getParent() 2", empty
, tmp
);
3694 uprv_memset(tmp
, '!', sizeof tmp
);
3695 reslen
= uloc_getParent(und
, tmp
, sizeof tmp
, status
);
3696 status
.errIfFailureAndReset("\"%s\"", und
);
3697 assertTrue("reslen >= 0", reslen
>= 0);
3698 assertEquals("uloc_getParent() 3", empty
, tmp
);
3700 uprv_memset(tmp
, '!', sizeof tmp
);
3701 reslen
= uloc_getParent(empty_script
, tmp
, sizeof tmp
, status
);
3702 status
.errIfFailureAndReset("\"%s\"", empty_script
);
3703 assertTrue("reslen >= 0", reslen
>= 0);
3704 assertEquals("uloc_getParent() 4", empty
, tmp
);
3706 uprv_memset(tmp
, '!', sizeof tmp
);
3707 reslen
= uloc_getParent(empty_region
, tmp
, sizeof tmp
, status
);
3708 status
.errIfFailureAndReset("\"%s\"", empty_region
);
3709 assertTrue("reslen >= 0", reslen
>= 0);
3710 assertEquals("uloc_getParent() 5", empty
, tmp
);
3712 uprv_memset(tmp
, '!', sizeof tmp
);
3713 reslen
= uloc_getParent(und_script
, tmp
, sizeof tmp
, status
);
3714 status
.errIfFailureAndReset("\"%s\"", und_script
);
3715 assertTrue("reslen >= 0", reslen
>= 0);
3716 assertEquals("uloc_getParent() 6", und
, tmp
); // change from open ICU
3718 uprv_memset(tmp
, '!', sizeof tmp
);
3719 reslen
= uloc_getParent(und_region
, tmp
, sizeof tmp
, status
);
3720 status
.errIfFailureAndReset("\"%s\"", und_region
);
3721 assertTrue("reslen >= 0", reslen
>= 0);
3722 assertEquals("uloc_getParent() 7", und
, tmp
); // change from open ICU
3724 // uloc_getLanguage()
3726 uprv_memset(tmp
, '!', sizeof tmp
);
3727 reslen
= uloc_getLanguage(empty
, tmp
, sizeof tmp
, status
);
3728 status
.errIfFailureAndReset("\"%s\"", empty
);
3729 assertTrue("reslen >= 0", reslen
>= 0);
3730 assertEquals("uloc_getLanguage() 1", empty
, tmp
);
3732 uprv_memset(tmp
, '!', sizeof tmp
);
3733 reslen
= uloc_getLanguage(root
, tmp
, sizeof tmp
, status
);
3734 status
.errIfFailureAndReset("\"%s\"", root
);
3735 assertTrue("reslen >= 0", reslen
>= 0);
3736 assertEquals("uloc_getLanguage() 2", root
, tmp
); // change from open ICU
3738 uprv_memset(tmp
, '!', sizeof tmp
);
3739 reslen
= uloc_getLanguage(und
, tmp
, sizeof tmp
, status
);
3740 status
.errIfFailureAndReset("\"%s\"", und
);
3741 assertTrue("reslen >= 0", reslen
>= 0);
3742 assertEquals("uloc_getLanguage() 3", und
, tmp
); // change from open ICU
3744 uprv_memset(tmp
, '!', sizeof tmp
);
3745 reslen
= uloc_getLanguage(empty_script
, tmp
, sizeof tmp
, status
);
3746 status
.errIfFailureAndReset("\"%s\"", empty_script
);
3747 assertTrue("reslen >= 0", reslen
>= 0);
3748 assertEquals("uloc_getLanguage() 4", empty
, tmp
);
3750 uprv_memset(tmp
, '!', sizeof tmp
);
3751 reslen
= uloc_getLanguage(empty_region
, tmp
, sizeof tmp
, status
);
3752 status
.errIfFailureAndReset("\"%s\"", empty_region
);
3753 assertTrue("reslen >= 0", reslen
>= 0);
3754 assertEquals("uloc_getLanguage() 5", empty
, tmp
);
3756 uprv_memset(tmp
, '!', sizeof tmp
);
3757 reslen
= uloc_getLanguage(und_script
, tmp
, sizeof tmp
, status
);
3758 status
.errIfFailureAndReset("\"%s\"", und_script
);
3759 assertTrue("reslen >= 0", reslen
>= 0);
3760 assertEquals("uloc_getLanguage() 6", und
, tmp
); // change from open ICU
3762 uprv_memset(tmp
, '!', sizeof tmp
);
3763 reslen
= uloc_getLanguage(und_region
, tmp
, sizeof tmp
, status
);
3764 status
.errIfFailureAndReset("\"%s\"", und_region
);
3765 assertTrue("reslen >= 0", reslen
>= 0);
3766 assertEquals("uloc_getLanguage() 7", und
, tmp
); // change from open ICU