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 ********************************************************************/
15 #include "unicode/localebuilder.h"
16 #include "unicode/localpointer.h"
17 #include "unicode/decimfmt.h"
18 #include "unicode/ucurr.h"
19 #include "unicode/smpdtfmt.h"
20 #include "unicode/strenum.h"
21 #include "unicode/dtfmtsym.h"
22 #include "unicode/brkiter.h"
23 #include "unicode/coll.h"
24 #include "unicode/ustring.h"
25 #include "unicode/std_string.h"
35 static const char* const rawData
[33][8] = {
38 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
40 { "", "", "", "", "", "", "", "Hans" },
42 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" },
44 { "", "", "", "", "NY", "", "", "" },
46 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" },
48 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" },
50 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" },
52 { "409", "40c", "403", "408", "814", "10", "0", "804" },
54 // display language (English)
55 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" },
56 // display script (English)
57 { "", "", "", "", "", "", "", "Simplified Han" },
58 // display country (English)
59 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China mainland" },
60 // display variant (English)
61 { "", "", "", "", "NY", "", "", ""},
62 // display name (English)
63 // Updated no_NO_NY English display name for new pattern-based algorithm
64 // (part of Euro support).
65 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese, Simplified (China mainland)" },
67 // display language (French)
68 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
69 // display script (French)
70 { "", "", "", "", "", "", "", "sinogrammes simplifi\\u00E9s" },
71 // display country (French)
72 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine continentale" },
73 // display variant (French)
74 { "", "", "", "", "NY", "", "", "" },
75 // display name (French)
76 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
77 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois simplifi\\u00E9 (Chine continentale)" },
80 /* display language (Catalan) */
81 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E8s" },
82 /* display script (Catalan) */
83 { "", "", "", "", "", "", "", "han simplificat" },
84 /* display country (Catalan) */
85 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina continental" },
86 /* display variant (Catalan) */
87 { "", "", "", "", "NY", "", "" },
88 /* display name (Catalan) */
89 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E8s simplificat (Xina continental)" },
91 // display language (Greek)[actual values listed below]
92 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
93 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
94 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
95 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
96 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
97 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
99 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
101 // display script (Greek)
102 { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd" },
103 // display country (Greek)[actual values listed below]
104 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
105 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
106 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
107 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
108 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
111 "\\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE"
113 // display variant (Greek)
114 { "", "", "", "", "NY", "", "" },
115 // display name (Greek)[actual values listed below]
116 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
117 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
118 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
119 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
120 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
121 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
123 "\\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)"
126 // display language (<root>)
127 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" },
128 // display script (<root>)
129 { "", "", "", "", "", "", "", ""},
130 // display country (<root>)
131 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" },
132 // display variant (<root>)
133 { "", "", "", "", "Nynorsk", "", "", ""},
134 // display name (<root>)
135 //{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" },
136 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
142 test_assert( Test (should be TRUE) )
147 the macro is ugly but makes the tests pretty.
150 #define test_assert(test) UPRV_BLOCK_MACRO_BEGIN { \
152 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \
154 logln("PASS: asserted " #test); \
155 } UPRV_BLOCK_MACRO_END
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) UPRV_BLOCK_MACRO_BEGIN { \
169 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \
171 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \
172 } UPRV_BLOCK_MACRO_END
175 #define test_dumpLocale(l) UPRV_BLOCK_MACRO_BEGIN { \
176 logln(#l " = " + UnicodeString(l.getName(), "")); \
177 } UPRV_BLOCK_MACRO_END
179 LocaleTest::LocaleTest()
185 LocaleTest::~LocaleTest()
187 if (dataTable
!= 0) {
188 for (int32_t i
= 0; i
< 33; i
++) {
189 delete []dataTable
[i
];
196 void LocaleTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
199 TESTCASE_AUTO(TestBug11421
); // Must run early in list to trigger failure.
200 TESTCASE_AUTO(TestBasicGetters
);
201 TESTCASE_AUTO(TestSimpleResourceInfo
);
202 TESTCASE_AUTO(TestDisplayNames
);
203 TESTCASE_AUTO(TestSimpleObjectStuff
);
204 TESTCASE_AUTO(TestPOSIXParsing
);
205 TESTCASE_AUTO(TestGetAvailableLocales
);
206 TESTCASE_AUTO(TestDataDirectory
);
207 TESTCASE_AUTO(TestISO3Fallback
);
208 TESTCASE_AUTO(TestGetLangsAndCountries
);
209 TESTCASE_AUTO(TestSimpleDisplayNames
);
210 TESTCASE_AUTO(TestUninstalledISO3Names
);
211 TESTCASE_AUTO(TestAtypicalLocales
);
212 #if !UCONFIG_NO_FORMATTING
213 TESTCASE_AUTO(TestThaiCurrencyFormat
);
214 TESTCASE_AUTO(TestEuroSupport
);
216 TESTCASE_AUTO(TestToString
);
217 #if !UCONFIG_NO_FORMATTING
218 TESTCASE_AUTO(Test4139940
);
219 TESTCASE_AUTO(Test4143951
);
221 TESTCASE_AUTO(Test4147315
);
222 TESTCASE_AUTO(Test4147317
);
223 TESTCASE_AUTO(Test4147552
);
224 TESTCASE_AUTO(TestVariantParsing
);
225 TESTCASE_AUTO(Test20639_DeprecatesISO3Language
);
226 #if !UCONFIG_NO_FORMATTING
227 TESTCASE_AUTO(Test4105828
);
229 TESTCASE_AUTO(TestSetIsBogus
);
230 TESTCASE_AUTO(TestParallelAPIValues
);
231 TESTCASE_AUTO(TestAddLikelySubtags
);
232 TESTCASE_AUTO(TestMinimizeSubtags
);
233 TESTCASE_AUTO(TestAddLikelyAndMinimizeSubtags
);
234 TESTCASE_AUTO(TestKeywordVariants
);
235 TESTCASE_AUTO(TestCreateUnicodeKeywords
);
236 TESTCASE_AUTO(TestKeywordVariantParsing
);
237 TESTCASE_AUTO(TestCreateKeywordSet
);
238 TESTCASE_AUTO(TestCreateKeywordSetEmpty
);
239 TESTCASE_AUTO(TestCreateUnicodeKeywordSet
);
240 TESTCASE_AUTO(TestCreateUnicodeKeywordSetEmpty
);
241 TESTCASE_AUTO(TestGetKeywordValueStdString
);
242 TESTCASE_AUTO(TestGetUnicodeKeywordValueStdString
);
243 TESTCASE_AUTO(TestSetKeywordValue
);
244 TESTCASE_AUTO(TestSetKeywordValueStringPiece
);
245 TESTCASE_AUTO(TestSetUnicodeKeywordValueStringPiece
);
246 TESTCASE_AUTO(TestGetBaseName
);
247 #if !UCONFIG_NO_FILE_IO
248 TESTCASE_AUTO(TestGetLocale
);
250 TESTCASE_AUTO(TestVariantWithOutCountry
);
251 TESTCASE_AUTO(TestCanonicalization
);
252 TESTCASE_AUTO(TestCurrencyByDate
);
253 TESTCASE_AUTO(TestGetVariantWithKeywords
);
254 TESTCASE_AUTO(TestIsRightToLeft
);
255 TESTCASE_AUTO(TestBug13277
);
256 TESTCASE_AUTO(TestBug13554
);
257 TESTCASE_AUTO(TestBug20410
);
258 TESTCASE_AUTO(TestConstructorAcceptsBCP47
);
259 TESTCASE_AUTO(TestForLanguageTag
);
260 TESTCASE_AUTO(TestToLanguageTag
);
261 TESTCASE_AUTO(TestMoveAssign
);
262 TESTCASE_AUTO(TestMoveCtor
);
263 TESTCASE_AUTO(TestBug20407iVariantPreferredValue
);
264 TESTCASE_AUTO(TestBug13417VeryLongLanguageTag
);
265 TESTCASE_AUTO(TestBug11053UnderlineTimeZone
);
266 TESTCASE_AUTO(TestUnd
);
267 TESTCASE_AUTO(TestUndScript
);
268 TESTCASE_AUTO(TestUndRegion
);
269 TESTCASE_AUTO(TestUndCAPI
);
270 TESTCASE_AUTO(TestRangeIterator
);
271 TESTCASE_AUTO(TestPointerConvertingIterator
);
272 TESTCASE_AUTO(TestTagConvertingIterator
);
273 TESTCASE_AUTO(TestCapturingTagConvertingIterator
);
274 TESTCASE_AUTO(TestSetUnicodeKeywordValueInLongLocale
);
275 TESTCASE_AUTO(TestSetUnicodeKeywordValueNullInLongLocale
);
279 void LocaleTest::TestBasicGetters() {
283 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
284 Locale
testLocale("");
285 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
286 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
289 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
291 logln("Testing " + (UnicodeString
)testLocale
.getName() + "...");
293 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
294 errln(" Language code mismatch: " + temp
+ " versus "
295 + dataTable
[LANG
][i
]);
296 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
297 errln(" Script code mismatch: " + temp
+ " versus "
298 + dataTable
[SCRIPT
][i
]);
299 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
300 errln(" Country code mismatch: " + temp
+ " versus "
301 + dataTable
[CTRY
][i
]);
302 if ( (temp
=testLocale
.getVariant()) != (dataTable
[VAR
][i
]))
303 errln(" Variant code mismatch: " + temp
+ " versus "
304 + dataTable
[VAR
][i
]);
305 if ( (temp
=testLocale
.getName()) != (dataTable
[NAME
][i
]))
306 errln(" Locale name mismatch: " + temp
+ " versus "
307 + dataTable
[NAME
][i
]);
310 logln("Same thing without variant codes...");
311 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
312 Locale
testLocale("");
313 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
314 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
]);
317 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
]);
319 logln("Testing " + (temp
=testLocale
.getName()) + "...");
321 if ( (temp
=testLocale
.getLanguage()) != (dataTable
[LANG
][i
]))
322 errln("Language code mismatch: " + temp
+ " versus "
323 + dataTable
[LANG
][i
]);
324 if ( (temp
=testLocale
.getScript()) != (dataTable
[SCRIPT
][i
]))
325 errln("Script code mismatch: " + temp
+ " versus "
326 + dataTable
[SCRIPT
][i
]);
327 if ( (temp
=testLocale
.getCountry()) != (dataTable
[CTRY
][i
]))
328 errln("Country code mismatch: " + temp
+ " versus "
329 + dataTable
[CTRY
][i
]);
330 if (testLocale
.getVariant()[0] != 0)
331 errln("Variant code mismatch: something versus \"\"");
334 logln("Testing long language names and getters");
335 Locale test8
= Locale::createFromName("x-klingon-latn-zx.utf32be@special");
337 temp
= test8
.getLanguage();
338 if (temp
!= UnicodeString("x-klingon") )
339 errln("Language code mismatch: " + temp
+ " versus \"x-klingon\"");
341 temp
= test8
.getScript();
342 if (temp
!= UnicodeString("Latn") )
343 errln("Script code mismatch: " + temp
+ " versus \"Latn\"");
345 temp
= test8
.getCountry();
346 if (temp
!= UnicodeString("ZX") )
347 errln("Country code mismatch: " + temp
+ " versus \"ZX\"");
349 temp
= test8
.getVariant();
350 //if (temp != UnicodeString("SPECIAL") )
351 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\"");
352 // As of 3.0, the "@special" will *not* be parsed by uloc_getName()
353 if (temp
!= UnicodeString("") )
354 errln("Variant code mismatch: " + temp
+ " versus \"\"");
356 if (Locale::getDefault() != Locale::createFromName(NULL
))
357 errln("Locale::getDefault() == Locale::createFromName(NULL)");
360 // NOTE: There used to be a special test for locale names that had language or
361 // country codes that were longer than two letters. The new version of Locale
362 // doesn't support anything that isn't an officially recognized language or
363 // country code, so we no longer support this feature.
365 Locale
bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code too long
366 if(!bogusLang
.isBogus()) {
367 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE");
370 bogusLang
=Locale("eo");
371 if( bogusLang
.isBogus() ||
372 strcmp(bogusLang
.getLanguage(), "eo")!=0 ||
373 *bogusLang
.getCountry()!=0 ||
374 *bogusLang
.getVariant()!=0 ||
375 strcmp(bogusLang
.getName(), "eo")!=0
377 errln("assignment to bogus Locale does not unbogus it or sets bad data");
380 Locale
a("eo_DE@currency=DEM");
381 Locale
*pb
=a
.clone();
382 if(pb
==&a
|| *pb
!=a
) {
383 errln("Locale.clone() failed");
388 void LocaleTest::TestParallelAPIValues() {
389 logln("Test synchronization between C and C++ API");
390 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE
) != 0) {
391 errln("Differences for ULOC_CHINESE Locale");
393 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH
) != 0) {
394 errln("Differences for ULOC_ENGLISH Locale");
396 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH
) != 0) {
397 errln("Differences for ULOC_FRENCH Locale");
399 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN
) != 0) {
400 errln("Differences for ULOC_GERMAN Locale");
402 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN
) != 0) {
403 errln("Differences for ULOC_ITALIAN Locale");
405 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE
) != 0) {
406 errln("Differences for ULOC_JAPANESE Locale");
408 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN
) != 0) {
409 errln("Differences for ULOC_KOREAN Locale");
411 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE
) != 0) {
412 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale");
414 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINESE
) != 0) {
415 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale");
419 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA
) != 0) {
420 errln("Differences for ULOC_CANADA Locale");
422 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH
) != 0) {
423 errln("Differences for ULOC_CANADA_FRENCH Locale");
425 if (strcmp(Locale::getChina().getName(), ULOC_CHINA
) != 0) {
426 errln("Differences for ULOC_CHINA Locale");
428 if (strcmp(Locale::getPRC().getName(), ULOC_PRC
) != 0) {
429 errln("Differences for ULOC_PRC Locale");
431 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE
) != 0) {
432 errln("Differences for ULOC_FRANCE Locale");
434 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY
) != 0) {
435 errln("Differences for ULOC_GERMANY Locale");
437 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY
) != 0) {
438 errln("Differences for ULOC_ITALY Locale");
440 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN
) != 0) {
441 errln("Differences for ULOC_JAPAN Locale");
443 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA
) != 0) {
444 errln("Differences for ULOC_KOREA Locale");
446 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN
) != 0) {
447 errln("Differences for ULOC_TAIWAN Locale");
449 if (strcmp(Locale::getUK().getName(), ULOC_UK
) != 0) {
450 errln("Differences for ULOC_UK Locale");
452 if (strcmp(Locale::getUS().getName(), ULOC_US
) != 0) {
453 errln("Differences for ULOC_US Locale");
458 void LocaleTest::TestSimpleResourceInfo() {
461 UErrorCode err
= U_ZERO_ERROR
;
464 for (i
= 0; i
<= MAX_LOCALES
; i
++) {
465 Locale
testLocale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
466 logln("Testing " + (temp
=testLocale
.getName()) + "...");
468 if ( (temp
=testLocale
.getISO3Language()) != (dataTable
[LANG3
][i
]))
469 errln(" ISO-3 language code mismatch: " + temp
470 + " versus " + dataTable
[LANG3
][i
]);
471 if ( (temp
=testLocale
.getISO3Country()) != (dataTable
[CTRY3
][i
]))
472 errln(" ISO-3 country code mismatch: " + temp
473 + " versus " + dataTable
[CTRY3
][i
]);
475 sprintf(temp2
, "%x", (int)testLocale
.getLCID());
476 if (UnicodeString(temp2
) != dataTable
[LCID
][i
])
477 errln((UnicodeString
)" LCID mismatch: " + temp2
+ " versus "
478 + dataTable
[LCID
][i
]);
482 errln((UnicodeString
)"Some error on number " + i
+ u_errorName(err
));
488 if(strcmp(locale
.getName(), "en") != 0||
489 strcmp(locale
.getLanguage(), "en") != 0) {
490 errln("construction of Locale(en) failed\n");
497 * Jitterbug 2439 -- markus 20030425
499 * The lookup of display names must not fall back through the default
500 * locale because that yields useless results.
503 LocaleTest::TestDisplayNames()
505 Locale
english("en", "US");
506 Locale
french("fr", "FR");
507 Locale
croatian("ca", "ES");
508 Locale
greek("el", "GR");
510 logln(" In locale = en_US...");
511 doTestDisplayNames(english
, DLANG_EN
);
512 logln(" In locale = fr_FR...");
513 doTestDisplayNames(french
, DLANG_FR
);
514 logln(" In locale = ca_ES...");
515 doTestDisplayNames(croatian
, DLANG_CA
);
516 logln(" In locale = el_GR...");
517 doTestDisplayNames(greek
, DLANG_EL
);
520 UErrorCode status
= U_ZERO_ERROR
;
522 #if !UCONFIG_NO_FORMATTING
523 DecimalFormatSymbols
symb(status
);
524 /* Check to see if ICU supports this locale */
525 if (symb
.getLocale(ULOC_VALID_LOCALE
, status
) != Locale("root")) {
526 /* test that the default locale has a display name for its own language */
527 /* Currently, there is no language information in the "tl" data file so this test will fail if default locale is "tl" */
528 if (uprv_strcmp(Locale().getLanguage(), "tl") != 0) {
529 Locale().getDisplayLanguage(Locale(), s
);
530 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
531 /* check <=3 to reject getting the language code as a display name */
532 dataerrln("unable to get a display string for the language of the default locale: " + s
);
536 * API coverage improvements: call
537 * Locale::getDisplayLanguage(UnicodeString &) and
538 * Locale::getDisplayCountry(UnicodeString &)
541 Locale().getDisplayLanguage(s
);
542 if(s
.length()<=3 && s
.charAt(0)<=0x7f) {
543 dataerrln("unable to get a display string for the language of the default locale [2]: " + s
);
548 logln("Default locale %s is unsupported by ICU\n", Locale().getName());
553 french
.getDisplayCountry(s
);
555 errln("unable to get any default-locale display string for the country of fr_FR\n");
558 Locale("zh", "Hant").getDisplayScript(s
);
560 errln("unable to get any default-locale display string for the country of zh_Hant\n");
564 void LocaleTest::TestSimpleObjectStuff() {
565 Locale
test1("aa", "AA");
566 Locale
test2("aa", "AA");
568 Locale
test4("zz", "ZZ");
569 Locale
test5("aa", "AA", "");
570 Locale
test6("aa", "AA", "ANTARES");
571 Locale
test7("aa", "AA", "JUPITER");
572 Locale test8
= Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that
574 // now list them all for debugging usage.
575 test_dumpLocale(test1
);
576 test_dumpLocale(test2
);
577 test_dumpLocale(test3
);
578 test_dumpLocale(test4
);
579 test_dumpLocale(test5
);
580 test_dumpLocale(test6
);
581 test_dumpLocale(test7
);
582 test_dumpLocale(test8
);
584 // Make sure things compare to themselves!
585 test_assert(test1
== test1
);
586 test_assert(test2
== test2
);
587 test_assert(test3
== test3
);
588 test_assert(test4
== test4
);
589 test_assert(test5
== test5
);
590 test_assert(test6
== test6
);
591 test_assert(test7
== test7
);
592 test_assert(test8
== test8
);
594 // make sure things are not equal to themselves.
595 test_assert(!(test1
!= test1
));
596 test_assert(!(test2
!= test2
));
597 test_assert(!(test3
!= test3
));
598 test_assert(!(test4
!= test4
));
599 test_assert(!(test5
!= test5
));
600 test_assert(!(test6
!= test6
));
601 test_assert(!(test7
!= test7
));
602 test_assert(!(test8
!= test8
));
604 // make sure things that are equal to each other don't show up as unequal.
605 test_assert(!(test1
!= test2
));
606 test_assert(!(test2
!= test1
));
607 test_assert(!(test1
!= test3
));
608 test_assert(!(test2
!= test3
));
609 test_assert(test5
== test1
);
610 test_assert(test6
!= test2
);
611 test_assert(test6
!= test5
);
613 test_assert(test6
!= test7
);
615 // test for things that shouldn't compare equal.
616 test_assert(!(test1
== test4
));
617 test_assert(!(test2
== test4
));
618 test_assert(!(test3
== test4
));
620 test_assert(test7
== test8
);
622 // test for hash codes to be the same.
623 int32_t hash1
= test1
.hashCode();
624 int32_t hash2
= test2
.hashCode();
625 int32_t hash3
= test3
.hashCode();
627 test_assert(hash1
== hash2
);
628 test_assert(hash1
== hash3
);
629 test_assert(hash2
== hash3
);
631 // test that the assignment operator works.
633 logln("test4=test1;");
634 test_dumpLocale(test4
);
635 test_assert(test4
== test4
);
637 test_assert(!(test1
!= test4
));
638 test_assert(!(test2
!= test4
));
639 test_assert(!(test3
!= test4
));
640 test_assert(test1
== test4
);
641 test_assert(test4
== test1
);
643 // test assignments with a variant
644 logln("test7 = test6");
646 test_dumpLocale(test7
);
647 test_assert(test7
== test7
);
648 test_assert(test7
== test6
);
649 test_assert(test7
!= test5
);
651 logln("test6 = test1");
653 test_dumpLocale(test6
);
654 test_assert(test6
!= test7
);
655 test_assert(test6
== test1
);
656 test_assert(test6
== test6
);
659 // A class which exposes constructors that are implemented in terms of the POSIX parsing code.
660 class POSIXLocale
: public Locale
663 POSIXLocale(const UnicodeString
& l
)
667 ch
= new char[l
.length() + 1];
668 ch
[l
.extract(0, 0x7fffffff, ch
, "")] = 0;
672 POSIXLocale(const char *l
)
679 void LocaleTest::TestPOSIXParsing()
681 POSIXLocale
test1("ab_AB");
682 POSIXLocale
test2(UnicodeString("ab_AB"));
683 Locale
test3("ab","AB");
685 POSIXLocale
test4("ab_AB_Antares");
686 POSIXLocale
test5(UnicodeString("ab_AB_Antares"));
687 Locale
test6("ab", "AB", "Antares");
689 test_dumpLocale(test1
);
690 test_dumpLocale(test2
);
691 test_dumpLocale(test3
);
692 test_dumpLocale(test4
);
693 test_dumpLocale(test5
);
694 test_dumpLocale(test6
);
696 test_assert(test1
== test1
);
698 test_assert(test1
== test2
);
699 test_assert(test2
== test3
);
700 test_assert(test3
== test1
);
702 test_assert(test4
== test5
);
703 test_assert(test5
== test6
);
704 test_assert(test6
== test4
);
706 test_assert(test1
!= test4
);
707 test_assert(test5
!= test3
);
708 test_assert(test5
!= test2
);
710 int32_t hash1
= test1
.hashCode();
711 int32_t hash2
= test2
.hashCode();
712 int32_t hash3
= test3
.hashCode();
714 test_assert(hash1
== hash2
);
715 test_assert(hash2
== hash3
);
716 test_assert(hash3
== hash1
);
719 void LocaleTest::TestGetAvailableLocales()
721 int32_t locCount
= 0;
722 const Locale
* locList
= Locale::getAvailableLocales(locCount
);
725 dataerrln("getAvailableLocales() returned an empty list!");
727 logln(UnicodeString("Number of locales returned = ") + locCount
);
729 for(int32_t i
= 0; i
< locCount
; ++i
)
730 logln(locList
[i
].getName());
732 // I have no idea how to test this function...
735 // This test isn't applicable anymore - getISO3Language is
736 // independent of the data directory
737 void LocaleTest::TestDataDirectory()
740 char oldDirectory[80];
742 UErrorCode err = U_ZERO_ERROR;
743 UnicodeString testValue;
745 temp = Locale::getDataDirectory();
746 strcpy(oldDirectory, temp);
747 logln(UnicodeString("oldDirectory = ") + oldDirectory);
749 Locale test(Locale::US);
750 test.getISO3Language(testValue);
751 logln("first fetch of language retrieved " + testValue);
752 if (testValue != "eng")
753 errln("Initial check of ISO3 language failed: expected \"eng\", got \"" + testValue + "\"");
757 path=IntlTest::getTestDirectory();
758 Locale::setDataDirectory( path );
761 test.getISO3Language(testValue);
762 logln("second fetch of language retrieved " + testValue);
763 if (testValue != "xxx")
764 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue + "\"");
766 Locale::setDataDirectory(oldDirectory);
767 test.getISO3Language(testValue);
768 logln("third fetch of language retrieved " + testValue);
769 if (testValue != "eng")
770 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testValue + "\"");
774 //===========================================================
776 void LocaleTest::doTestDisplayNames(Locale
& displayLocale
, int32_t compareIndex
) {
779 for (int32_t i
= 0; i
<= MAX_LOCALES
; i
++) {
780 Locale
testLocale("");
781 if (rawData
[SCRIPT
][i
] && rawData
[SCRIPT
][i
][0] != 0) {
782 testLocale
= Locale(rawData
[LANG
][i
], rawData
[SCRIPT
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
785 testLocale
= Locale(rawData
[LANG
][i
], rawData
[CTRY
][i
], rawData
[VAR
][i
]);
787 logln(" Testing " + (temp
=testLocale
.getName()) + "...");
789 UnicodeString testLang
;
790 UnicodeString testScript
;
791 UnicodeString testCtry
;
792 UnicodeString testVar
;
793 UnicodeString testName
;
795 testLocale
.getDisplayLanguage(displayLocale
, testLang
);
796 testLocale
.getDisplayScript(displayLocale
, testScript
);
797 testLocale
.getDisplayCountry(displayLocale
, testCtry
);
798 testLocale
.getDisplayVariant(displayLocale
, testVar
);
799 testLocale
.getDisplayName(displayLocale
, testName
);
801 UnicodeString expectedLang
;
802 UnicodeString expectedScript
;
803 UnicodeString expectedCtry
;
804 UnicodeString expectedVar
;
805 UnicodeString expectedName
;
807 expectedLang
= dataTable
[compareIndex
][i
];
808 if (expectedLang
.length() == 0)
809 expectedLang
= dataTable
[DLANG_EN
][i
];
811 expectedScript
= dataTable
[compareIndex
+ 1][i
];
812 if (expectedScript
.length() == 0)
813 expectedScript
= dataTable
[DSCRIPT_EN
][i
];
815 expectedCtry
= dataTable
[compareIndex
+ 2][i
];
816 if (expectedCtry
.length() == 0)
817 expectedCtry
= dataTable
[DCTRY_EN
][i
];
819 expectedVar
= dataTable
[compareIndex
+ 3][i
];
820 if (expectedVar
.length() == 0)
821 expectedVar
= dataTable
[DVAR_EN
][i
];
823 expectedName
= dataTable
[compareIndex
+ 4][i
];
824 if (expectedName
.length() == 0)
825 expectedName
= dataTable
[DNAME_EN
][i
];
827 if (testLang
!= expectedLang
)
828 dataerrln("Display language (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testLang
+ " expected " + expectedLang
);
829 if (testScript
!= expectedScript
)
830 dataerrln("Display script (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testScript
+ " expected " + expectedScript
);
831 if (testCtry
!= expectedCtry
)
832 dataerrln("Display country (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testCtry
+ " expected " + expectedCtry
);
833 if (testVar
!= expectedVar
)
834 dataerrln("Display variant (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testVar
+ " expected " + expectedVar
);
835 if (testName
!= expectedName
)
836 dataerrln("Display name (" + UnicodeString(displayLocale
.getName()) + ") of (" + UnicodeString(testLocale
.getName()) + ") got " + testName
+ " expected " + expectedName
);
840 //---------------------------------------------------
841 // table of valid data
842 //---------------------------------------------------
846 void LocaleTest::setUpDataTable()
848 if (dataTable
== 0) {
849 dataTable
= new UnicodeString
*[33];
851 for (int32_t i
= 0; i
< 33; i
++) {
852 dataTable
[i
] = new UnicodeString
[8];
853 for (int32_t j
= 0; j
< 8; j
++) {
854 dataTable
[i
][j
] = CharsToUnicodeString(rawData
[i
][j
]);
860 // ====================
864 * @bug 4011756 4011380
867 LocaleTest::TestISO3Fallback()
869 Locale
test("xx", "YY");
873 result
= test
.getISO3Language();
875 // Conform to C API usage
877 if (!result
|| (result
[0] != 0))
878 errln("getISO3Language() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
880 result
= test
.getISO3Country();
882 if (!result
|| (result
[0] != 0))
883 errln("getISO3Country() on xx_YY returned " + UnicodeString(result
) + " instead of \"\"");
887 * @bug 4106155 4118587
890 LocaleTest::TestGetLangsAndCountries()
892 // It didn't seem right to just do an exhaustive test of everything here, so I check
893 // for the following things:
894 // 1) Does each list have the right total number of entries?
895 // 2) Does each list contain certain language and country codes we think are important
896 // (the G7 countries, plus a couple others)?
897 // 3) Does each list have every entry formatted correctly? (i.e., two characters,
898 // all lower case for the language codes, all upper case for the country codes)
899 // 4) Is each list in sorted order?
900 int32_t testCount
= 0;
901 const char * const * test
= Locale::getISOLanguages();
902 const char spotCheck1
[ ][4] = { "en", "es", "fr", "de", "it",
903 "ja", "ko", "zh", "th", "he",
904 "id", "iu", "ug", "yi", "za" };
908 for(testCount
= 0;test
[testCount
];testCount
++)
911 /* TODO: Change this test to be more like the cloctst version? */
912 if (testCount
!= 596)
913 errln("Expected getISOLanguages() to return 596 languages; it returned %d", testCount
);
915 for (i
= 0; i
< 15; i
++) {
917 for (j
= 0; j
< testCount
; j
++)
918 if (uprv_strcmp(test
[j
],spotCheck1
[i
])== 0)
920 if (j
== testCount
|| (uprv_strcmp(test
[j
],spotCheck1
[i
])!=0))
921 errln("Couldn't find " + (UnicodeString
)spotCheck1
[i
] + " in language list.");
924 for (i
= 0; i
< testCount
; i
++) {
925 UnicodeString
testee(test
[i
],"");
926 UnicodeString
lc(test
[i
],"");
927 if (testee
!= lc
.toLower())
928 errln(lc
+ " is not all lower case.");
929 if ( (testee
.length() != 2) && (testee
.length() != 3))
930 errln(testee
+ " is not two or three characters long.");
931 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
932 errln(testee
+ " appears in an out-of-order position in the list.");
935 test
= Locale::getISOCountries();
936 UnicodeString spotCheck2
[] = { "US", "CA", "GB", "FR", "DE",
937 "IT", "JP", "KR", "CN", "TW",
939 int32_t spot2Len
= 11;
940 for(testCount
=0;test
[testCount
];testCount
++)
943 if (testCount
!= 256){
944 errln("Expected getISOCountries to return 256 countries; it returned %d", testCount
);
946 for (i
= 0; i
< spot2Len
; i
++) {
948 for (j
= 0; j
< testCount
; j
++)
950 UnicodeString
testee(test
[j
],"");
952 if (testee
== spotCheck2
[i
])
955 UnicodeString
testee(test
[j
],"");
956 if (j
== testCount
|| testee
!= spotCheck2
[i
])
957 errln("Couldn't find " + spotCheck2
[i
] + " in country list.");
960 for (i
= 0; i
< testCount
; i
++) {
961 UnicodeString
testee(test
[i
],"");
962 UnicodeString
uc(test
[i
],"");
963 if (testee
!= uc
.toUpper())
964 errln(testee
+ " is not all upper case.");
965 if (testee
.length() != 2)
966 errln(testee
+ " is not two characters long.");
967 if (i
> 0 && testee
.compare(test
[i
- 1]) <= 0)
968 errln(testee
+ " appears in an out-of-order position in the list.");
971 // This getAvailableLocales and getISO3Language
973 int32_t numOfLocales
;
975 const Locale
*pLocales
= Locale::getAvailableLocales(numOfLocales
);
977 for (int i
= 0; i
< numOfLocales
; i
++) {
978 const Locale
&loc(pLocales
[i
]);
982 loc
.getDisplayName (enLoc
, name
);
983 name
.extract (0, 200, szName
, sizeof(szName
));
985 if (strlen(loc
.getISO3Language()) == 0) {
986 errln("getISO3Language() returned an empty string for: " + name
);
996 LocaleTest::TestSimpleDisplayNames()
998 // This test is different from TestDisplayNames because TestDisplayNames checks
999 // fallback behavior, combination of language and country names to form locale
1000 // names, and other stuff like that. This test just checks specific language
1001 // and country codes to make sure we have the correct names for them.
1002 char languageCodes
[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
1003 UnicodeString languageNames
[] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
1006 for (int32_t i
= 0; i
< 6; i
++) {
1008 Locale
l(languageCodes
[i
], "", "");
1009 l
.getDisplayLanguage(Locale::getUS(), test
);
1010 if (test
!= languageNames
[i
])
1011 dataerrln("Got wrong display name for " + UnicodeString(languageCodes
[i
]) + ": Expected \"" +
1012 languageNames
[i
] + "\", got \"" + test
+ "\".");
1020 LocaleTest::TestUninstalledISO3Names()
1022 // This test checks to make sure getISO3Language and getISO3Country work right
1023 // even for locales that are not installed.
1024 const char iso2Languages
[][4] = { "am", "ba", "fy", "mr", "rn",
1026 const char iso3Languages
[][5] = { "amh", "bak", "fry", "mar", "run",
1027 "ssw", "twi", "zul" };
1031 for (i
= 0; i
< 8; i
++) {
1032 UErrorCode err
= U_ZERO_ERROR
;
1035 Locale
l(iso2Languages
[i
], "", "");
1036 test
= l
.getISO3Language();
1037 if((test
!= iso3Languages
[i
]) || U_FAILURE(err
))
1038 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages
[i
]) + ": Expected \"" +
1039 iso3Languages
[i
] + "\", got \"" + test
+ "\"." + UnicodeString(u_errorName(err
)));
1042 char iso2Countries
[][4] = { "AF", "BW", "KZ", "MO", "MN",
1044 char iso3Countries
[][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
1045 "SLB", "TCA", "ZWE" };
1047 for (i
= 0; i
< 8; i
++) {
1048 UErrorCode err
= U_ZERO_ERROR
;
1049 Locale
l("", iso2Countries
[i
], "");
1050 UnicodeString
test(l
.getISO3Country(), "");
1051 if (test
!= iso3Countries
[i
])
1052 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries
[i
]) + ": Expected \"" +
1053 UnicodeString(iso3Countries
[i
]) + "\", got \"" + test
+ "\"." + u_errorName(err
));
1059 * I could not reproduce this bug. I'm pretty convinced it was fixed with the
1060 * big locale-data reorg of 10/28/97. The lookup logic for language and country
1061 * display names was also changed at that time in that check-in. --rtg 3/20/98
1064 LocaleTest::TestAtypicalLocales()
1066 Locale localesToTest
[] = { Locale("de", "CA"),
1076 UnicodeString englishDisplayNames
[] = { "German (Canada)",
1077 "Japanese (South Africa)",
1080 "Spanish (Germany)",
1083 "Dominican Republic",
1085 UnicodeString frenchDisplayNames
[]= { "allemand (Canada)",
1086 "japonais (Afrique du Sud)",
1089 "espagnol (Allemagne)",
1092 u
"République dominicaine",
1094 UnicodeString spanishDisplayNames
[] = {
1096 u
"japonés (Sudáfrica)",
1098 u
"inglés (Francia)",
1099 u
"español (Alemania)",
1102 u
"República Dominicana",
1104 // De-Anglicizing root required the change from
1105 // English display names to ISO Codes - ram 2003/09/26
1106 UnicodeString invDisplayNames
[] = { "German (Canada)",
1107 "Japanese (South Africa)",
1110 "Spanish (Germany)",
1113 "Dominican Republic",
1117 UErrorCode status
= U_ZERO_ERROR
;
1119 Locale::setDefault(Locale::getUS(), status
);
1120 for (i
= 0; i
< 9; ++i
) {
1122 localesToTest
[i
].getDisplayName(Locale::getUS(), name
);
1124 if (name
!= englishDisplayNames
[i
])
1126 dataerrln("Lookup in English failed: expected \"" + englishDisplayNames
[i
]
1127 + "\", got \"" + name
+ "\"");
1128 logln("Locale name was-> " + (name
=localesToTest
[i
].getName()));
1132 for (i
= 0; i
< 9; i
++) {
1134 localesToTest
[i
].getDisplayName(Locale("es", "ES"), name
);
1136 if (name
!= spanishDisplayNames
[i
])
1137 dataerrln("Lookup in Spanish failed: expected \"" + spanishDisplayNames
[i
]
1138 + "\", got \"" + name
+ "\"");
1141 for (i
= 0; i
< 9; i
++) {
1143 localesToTest
[i
].getDisplayName(Locale::getFrance(), name
);
1145 if (name
!= frenchDisplayNames
[i
])
1146 dataerrln("Lookup in French failed: expected \"" + frenchDisplayNames
[i
]
1147 + "\", got \"" + name
+ "\"");
1150 for (i
= 0; i
< 9; i
++) {
1152 localesToTest
[i
].getDisplayName(Locale("inv", "IN"), name
);
1153 logln(name
+ " Locale fallback to be, and data fallback to root");
1154 if (name
!= invDisplayNames
[i
])
1155 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1156 + "\", got \"" + prettify(name
) + "\"");
1157 localesToTest
[i
].getDisplayName(Locale("inv", "BD"), name
);
1158 logln(name
+ " Data fallback to root");
1159 if (name
!= invDisplayNames
[i
])
1160 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames
[i
])
1161 + "\", got \"" + prettify(name
)+ "\"");
1163 Locale::setDefault(saveLocale
, status
);
1166 #if !UCONFIG_NO_FORMATTING
1170 * This would be better tested by the LocaleDataTest. Will move it when I
1171 * get the LocaleDataTest working again.
1174 LocaleTest::TestThaiCurrencyFormat()
1176 UErrorCode status
= U_ZERO_ERROR
;
1177 DecimalFormat
*thaiCurrency
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(
1178 Locale("th", "TH"), status
);
1179 UnicodeString
posPrefix(u
"\u0E3F");
1182 if(U_FAILURE(status
) || !thaiCurrency
)
1184 dataerrln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status
)));
1187 if (thaiCurrency
->getPositivePrefix(temp
) != posPrefix
)
1188 errln("Thai currency prefix wrong: expected Baht sign, got \"" +
1189 thaiCurrency
->getPositivePrefix(temp
) + "\"");
1190 if (thaiCurrency
->getPositiveSuffix(temp
) != "")
1191 errln("Thai currency suffix wrong: expected \"\", got \"" +
1192 thaiCurrency
->getPositiveSuffix(temp
) + "\"");
1194 delete thaiCurrency
;
1199 * Confirm that Euro support works. This test is pretty rudimentary; all it does
1200 * is check that any locales with the EURO variant format a number using the
1201 * Euro currency symbol.
1203 * ASSUME: All locales encode the Euro character "\u20AC".
1204 * If this is changed to use the single-character Euro symbol, this
1205 * test must be updated.
1209 LocaleTest::TestEuroSupport()
1211 UChar euro
= 0x20ac;
1212 const UnicodeString
EURO_CURRENCY(&euro
, 1, 1); // Look for this UnicodeString in formatted Euro currency
1213 const char* localeArr
[] = {
1221 "en_GB@currency=EUR",
1222 "en_US@currency=EUR",
1237 const char** locales
= localeArr
;
1239 UErrorCode status
= U_ZERO_ERROR
;
1243 for (;*locales
!=NULL
;locales
++) {
1244 Locale
loc (*locales
);
1246 NumberFormat
*nf
= NumberFormat::createCurrencyInstance(loc
, status
);
1249 if (U_FAILURE(status
)) {
1250 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales
);
1254 nf
->format(271828.182845, pos
);
1256 nf
->format(-271828.182845, neg
);
1257 if (pos
.indexOf(EURO_CURRENCY
) >= 0 &&
1258 neg
.indexOf(EURO_CURRENCY
) >= 0) {
1259 logln("Ok: " + (temp
=loc
.getName()) +
1260 ": " + pos
+ " / " + neg
);
1263 errln("Fail: " + (temp
=loc
.getName()) +
1264 " formats without " + EURO_CURRENCY
+
1265 ": " + pos
+ " / " + neg
+
1266 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***");
1272 UnicodeString
dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar
)0x00a4), resultStr
;
1274 status
= U_ZERO_ERROR
;
1276 ucurr_forLocale("en_US", tmp
, 4, &status
);
1277 resultStr
.setTo(tmp
);
1278 if (dollarStr
!= resultStr
) {
1279 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
1281 ucurr_forLocale("en_US@currency=EUR", tmp
, 4, &status
);
1282 resultStr
.setTo(tmp
);
1283 if (euroStr
!= resultStr
) {
1284 errcheckln(status
, "Fail: en_US@currency=EUR didn't return EUR - %s", u_errorName(status
));
1286 ucurr_forLocale("en_GB@currency=EUR", tmp
, 4, &status
);
1287 resultStr
.setTo(tmp
);
1288 if (euroStr
!= resultStr
) {
1289 errcheckln(status
, "Fail: en_GB@currency=EUR didn't return EUR - %s", u_errorName(status
));
1291 ucurr_forLocale("en_US_Q", tmp
, 4, &status
);
1292 resultStr
.setTo(tmp
);
1293 if (dollarStr
!= resultStr
) {
1294 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
1296 int32_t invalidLen
= ucurr_forLocale("en_QQ", tmp
, 4, &status
);
1297 if (invalidLen
|| U_SUCCESS(status
)) {
1298 errln("Fail: en_QQ didn't return NULL");
1301 // The currency keyword value is as long as the destination buffer.
1302 // It should detect the overflow internally, and default to the locale's currency.
1304 status
= U_ZERO_ERROR
;
1305 int32_t length
= ucurr_forLocale("en_US@currency=euro", tmp
, 4, &status
);
1306 if (U_FAILURE(status
) || dollarStr
!= UnicodeString(tmp
, length
)) {
1307 if (U_SUCCESS(status
) && tmp
[0] == u
'¤') {
1308 errln("Fail: ucurr_forLocale(en_US@currency=euro) succeeded without writing output");
1310 errln("Fail: ucurr_forLocale(en_US@currency=euro) != USD - %s", u_errorName(status
));
1319 * toString() doesn't work with language_VARIANT.
1322 LocaleTest::TestToString() {
1324 Locale("xx", "", ""),
1325 Locale("", "YY", ""),
1326 Locale("", "", "ZZ"),
1327 Locale("xx", "YY", ""),
1328 Locale("xx", "", "ZZ"),
1329 Locale("", "YY", "ZZ"),
1330 Locale("xx", "YY", "ZZ"),
1333 const char DATA_S
[][20] = {
1343 for (int32_t i
=0; i
< 7; ++i
) {
1345 name
= DATA
[i
].getName();
1347 if (strcmp(name
, DATA_S
[i
]) != 0)
1349 errln("Fail: Locale.getName(), got:" + UnicodeString(name
) + ", expected: " + DATA_S
[i
]);
1352 logln("Pass: Locale.getName(), got:" + UnicodeString(name
) );
1356 #if !UCONFIG_NO_FORMATTING
1360 * Couldn't reproduce this bug -- probably was fixed earlier.
1362 * ORIGINAL BUG REPORT:
1363 * -- basically, hungarian for monday shouldn't have an \u00f4
1364 * (o circumflex)in it instead it should be an o with 2 inclined
1365 * (right) lines over it..
1367 * You may wonder -- why do all this -- why not just add a line to
1368 * LocaleData? Well, I could see by inspection that the locale file had the
1369 * right character in it, so I wanted to check the rest of the pipeline -- a
1370 * very remote possibility, but I wanted to be sure. The other possibility
1371 * is that something is wrong with the font mapping subsystem, but we can't
1375 LocaleTest::Test4139940()
1377 Locale
mylocale("hu", "", "");
1378 UDate mydate
= date(98,3,13); // A Monday
1379 UErrorCode status
= U_ZERO_ERROR
;
1380 SimpleDateFormat
df_full("EEEE", mylocale
, status
);
1381 if(U_FAILURE(status
)){
1382 dataerrln(UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: ") + UnicodeString(u_errorName(status
)));
1386 FieldPosition
pos(FieldPosition::DONT_CARE
);
1387 df_full
.format(mydate
, str
, pos
);
1388 // Make sure that o circumflex (\u00F4) is NOT there, and
1389 // o double acute (\u0151) IS.
1392 if (str
.indexOf(oda
) < 0 || str
.indexOf(ocf
) >= 0) {
1393 /* If the default locale is "th" this test will fail because of the buddhist calendar. */
1394 if (strcmp(Locale::getDefault().getLanguage(), "th") != 0) {
1395 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
1396 str
.indexOf(oda
), str
.indexOf(ocf
));
1398 logln(UnicodeString("An error is produce in buddhist calendar."));
1400 logln(UnicodeString("String is: ") + str
);
1405 LocaleTest::date(int32_t y
, int32_t m
, int32_t d
, int32_t hr
, int32_t min
, int32_t sec
)
1407 UErrorCode status
= U_ZERO_ERROR
;
1408 Calendar
*cal
= Calendar::createInstance(status
);
1412 cal
->set(1900 + y
, m
, d
, hr
, min
, sec
); // Add 1900 to follow java.util.Date protocol
1413 UDate dt
= cal
->getTime(status
);
1414 if (U_FAILURE(status
))
1423 * Russian first day of week should be Monday. Confirmed.
1426 LocaleTest::Test4143951()
1428 UErrorCode status
= U_ZERO_ERROR
;
1429 Calendar
*cal
= Calendar::createInstance(Locale("ru", "", ""), status
);
1430 if(U_SUCCESS(status
)) {
1431 if (cal
->getFirstDayOfWeek(status
) != UCAL_MONDAY
) {
1432 dataerrln("Fail: First day of week in Russia should be Monday");
1442 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes.
1443 * Should throw an exception for unknown locales
1446 LocaleTest::Test4147315()
1449 // Try with codes that are the wrong length but happen to match text
1450 // at a valid offset in the mapping table
1451 Locale
locale("xxx", "CCC");
1453 const char *result
= locale
.getISO3Country();
1455 // Change to conform to C api usage
1456 if((result
==NULL
)||(result
[0] != 0))
1457 errln("ERROR: getISO3Country() returns: " + UnicodeString(result
,"") +
1458 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1463 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
1464 * Should throw an exception for unknown locales
1467 LocaleTest::Test4147317()
1470 // Try with codes that are the wrong length but happen to match text
1471 // at a valid offset in the mapping table
1472 Locale
locale("xxx", "CCC");
1474 const char *result
= locale
.getISO3Language();
1476 // Change to conform to C api usage
1477 if((result
==NULL
)||(result
[0] != 0))
1478 errln("ERROR: getISO3Language() returns: " + UnicodeString(result
,"") +
1479 " for locale '" + (temp
=locale
.getName()) + "' rather than exception" );
1486 LocaleTest::Test4147552()
1488 Locale locales
[] = { Locale("no", "NO"),
1489 Locale("no", "NO", "B"),
1490 Locale("no", "NO", "NY")
1493 UnicodeString
edn("Norwegian (Norway, B)");
1494 UnicodeString englishDisplayNames
[] = {
1495 "Norwegian (Norway)",
1497 // "Norwegian (Norway,B)",
1498 //"Norwegian (Norway,NY)"
1499 "Norwegian (Norway, NY)"
1501 UnicodeString
ndn("norsk (Norge, B");
1502 UnicodeString norwegianDisplayNames
[] = {
1507 //"Norsk (Noreg, Nynorsk)"
1509 UErrorCode status
= U_ZERO_ERROR
;
1512 Locale::setDefault(Locale::getEnglish(), status
);
1513 for (int32_t i
= 0; i
< 3; ++i
) {
1514 Locale loc
= locales
[i
];
1516 if (loc
.getDisplayName(temp
) != englishDisplayNames
[i
])
1517 dataerrln("English display-name mismatch: expected " +
1518 englishDisplayNames
[i
] + ", got " + loc
.getDisplayName(temp
));
1519 if (loc
.getDisplayName(loc
, temp
) != norwegianDisplayNames
[i
])
1520 dataerrln("Norwegian display-name mismatch: expected " +
1521 norwegianDisplayNames
[i
] + ", got " +
1522 loc
.getDisplayName(loc
, temp
));
1524 Locale::setDefault(saveLocale
, status
);
1528 LocaleTest::TestVariantParsing()
1530 Locale
en_US_custom("en", "US", "De Anza_Cupertino_California_United States_Earth");
1532 UnicodeString
dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)");
1533 UnicodeString
dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH");
1537 en_US_custom
.getDisplayVariant(Locale::getUS(), got
);
1538 if(got
!= dispVar
) {
1539 errln("FAIL: getDisplayVariant()");
1540 errln("Wanted: " + dispVar
);
1541 errln("Got : " + got
);
1544 en_US_custom
.getDisplayName(Locale::getUS(), got
);
1545 if(got
!= dispName
) {
1546 dataerrln("FAIL: getDisplayName()");
1547 dataerrln("Wanted: " + dispName
);
1548 dataerrln("Got : " + got
);
1551 Locale
shortVariant("fr", "FR", "foo");
1552 shortVariant
.getDisplayVariant(got
);
1555 errln("FAIL: getDisplayVariant()");
1556 errln("Wanted: foo");
1557 errln("Got : " + got
);
1560 Locale
bogusVariant("fr", "FR", "_foo");
1561 bogusVariant
.getDisplayVariant(got
);
1564 errln("FAIL: getDisplayVariant()");
1565 errln("Wanted: foo");
1566 errln("Got : " + got
);
1569 Locale
bogusVariant2("fr", "FR", "foo_");
1570 bogusVariant2
.getDisplayVariant(got
);
1573 errln("FAIL: getDisplayVariant()");
1574 errln("Wanted: foo");
1575 errln("Got : " + got
);
1578 Locale
bogusVariant3("fr", "FR", "_foo_");
1579 bogusVariant3
.getDisplayVariant(got
);
1582 errln("FAIL: getDisplayVariant()");
1583 errln("Wanted: foo");
1584 errln("Got : " + got
);
1588 void LocaleTest::Test20639_DeprecatesISO3Language() {
1589 IcuTestErrorCode
status(*this, "Test20639_DeprecatesISO3Language");
1591 const struct TestCase
{
1592 const char* localeName
;
1593 const char* expectedISO3Language
;
1596 {"no", "nor"}, // why not nob?
1602 for (auto& cas
: cases
) {
1603 Locale
loc(cas
.localeName
);
1604 const char* actual
= loc
.getISO3Language();
1605 assertEquals(cas
.localeName
, cas
.expectedISO3Language
, actual
);
1609 #if !UCONFIG_NO_FORMATTING
1613 * Currency symbol in zh is wrong. We will test this at the NumberFormat
1614 * end to test the whole pipe.
1617 LocaleTest::Test4105828()
1619 Locale LOC
[] = { Locale::getChinese(), Locale("zh", "CN", ""),
1620 Locale("zh", "TW", ""), Locale("zh", "HK", "") };
1621 UErrorCode status
= U_ZERO_ERROR
;
1622 for (int32_t i
= 0; i
< 4; ++i
) {
1623 NumberFormat
*fmt
= NumberFormat::createPercentInstance(LOC
[i
], status
);
1624 if(U_FAILURE(status
)) {
1625 dataerrln("Couldn't create NumberFormat - %s", u_errorName(status
));
1628 UnicodeString result
;
1629 FieldPosition
pos(FieldPosition::DONT_CARE
);
1630 fmt
->format((int32_t)1, result
, pos
);
1632 if(result
!= "100%") {
1633 errln(UnicodeString("Percent for ") + LOC
[i
].getDisplayName(temp
) + " should be 100%, got " + result
);
1641 // Tests setBogus and isBogus APIs for Locale
1644 LocaleTest::TestSetIsBogus() {
1647 if(l
.isBogus() != TRUE
) {
1648 errln("After setting bogus, didn't return TRUE");
1650 l
= "en_US"; // This should reset bogus
1651 if(l
.isBogus() != FALSE
) {
1652 errln("After resetting bogus, didn't return FALSE");
1658 LocaleTest::TestAddLikelySubtags() {
1659 IcuTestErrorCode
status(*this, "TestAddLikelySubtags()");
1661 static const Locale
min("sv");
1662 static const Locale
max("sv_Latn_SE");
1665 result
.addLikelySubtags(status
);
1666 status
.errIfFailureAndReset("\"%s\"", min
.getName());
1667 assertEquals("addLikelySubtags", max
.getName(), result
.getName());
1672 LocaleTest::TestMinimizeSubtags() {
1673 IcuTestErrorCode
status(*this, "TestMinimizeSubtags()");
1675 static const Locale
max("zh_Hant_TW");
1676 static const Locale
min("zh_TW");
1679 result
.minimizeSubtags(status
);
1680 status
.errIfFailureAndReset("\"%s\"", max
.getName());
1681 assertEquals("minimizeSubtags", min
.getName(), result
.getName());
1686 LocaleTest::TestAddLikelyAndMinimizeSubtags() {
1687 IcuTestErrorCode
status(*this, "TestAddLikelyAndMinimizeSubtags()");
1689 static const struct {
1690 const char* const from
;
1691 const char* const add
;
1692 const char* const remove
;
1713 for (const auto& item
: full_data
) {
1714 const char* const org
= item
.from
;
1715 const char* const exp
= item
.add
;
1717 res
.addLikelySubtags(status
);
1718 status
.errIfFailureAndReset("\"%s\"", org
);
1719 assertEquals("addLikelySubtags", exp
, res
.getName());
1722 for (const auto& item
: full_data
) {
1723 const char* const org
= item
.from
;
1724 const char* const exp
= item
.remove
;
1726 res
.minimizeSubtags(status
);
1727 status
.errIfFailureAndReset("\"%s\"", org
);
1728 assertEquals("minimizeSubtags", exp
, res
.getName());
1734 LocaleTest::TestKeywordVariants(void) {
1735 static const struct {
1736 const char *localeID
;
1737 const char *expectedLocaleID
;
1738 //const char *expectedLocaleIDNoKeywords;
1739 //const char *expectedCanonicalID;
1740 const char *expectedKeywords
[10];
1741 int32_t numKeywords
;
1742 UErrorCode expectedStatus
;
1745 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1746 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1748 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1749 {"calendar", "collation", "currency"},
1757 //"de_DE@currency=EUR",
1758 {"","","","","","",""},
1760 U_INVALID_FORMAT_ERROR
/* must have '=' after '@' */
1763 UErrorCode status
= U_ZERO_ERROR
;
1765 int32_t i
= 0, j
= 0;
1766 const char *result
= NULL
;
1767 StringEnumeration
*keywords
;
1768 int32_t keyCount
= 0;
1769 const char *keyword
= NULL
;
1770 const UnicodeString
*keywordString
;
1771 int32_t keywordLen
= 0;
1773 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1774 status
= U_ZERO_ERROR
;
1775 Locale
l(testCases
[i
].localeID
);
1776 keywords
= l
.createKeywords(status
);
1778 if(status
!= testCases
[i
].expectedStatus
) {
1779 err("Expected to get status %s. Got %s instead\n",
1780 u_errorName(testCases
[i
].expectedStatus
), u_errorName(status
));
1782 status
= U_ZERO_ERROR
;
1784 if((keyCount
= keywords
->count(status
)) != testCases
[i
].numKeywords
) {
1785 err("Expected to get %i keywords, got %i\n", testCases
[i
].numKeywords
, keyCount
);
1790 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1793 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1794 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1797 if((keywordString
= keywords
->snext(status
)) == NULL
) {
1800 if(*keywordString
!= UnicodeString(testCases
[i
].expectedKeywords
[j
], "")) {
1801 err("Expected to get keyword UnicodeString %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1806 if(j
== keyCount
/ 2) {
1807 // replace keywords with a clone of itself
1808 StringEnumeration
*k2
= keywords
->clone();
1809 if(k2
== NULL
|| keyCount
!= k2
->count(status
)) {
1810 errln("KeywordEnumeration.clone() failed");
1817 keywords
->reset(status
); // Make sure that reset works.
1819 if((keyword
= keywords
->next(&keywordLen
, status
)) == NULL
) {
1822 if(strcmp(keyword
, testCases
[i
].expectedKeywords
[j
]) != 0) {
1823 err("Expected to get keyword value %s, got %s\n", testCases
[i
].expectedKeywords
[j
], keyword
);
1830 result
= l
.getName();
1831 if(uprv_strcmp(testCases
[i
].expectedLocaleID
, result
) != 0) {
1832 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n",
1833 testCases
[i
].expectedLocaleID
, testCases
[i
].localeID
, result
);
1842 LocaleTest::TestCreateUnicodeKeywords(void) {
1843 IcuTestErrorCode
status(*this, "TestCreateUnicodeKeywords()");
1845 static const Locale
l("de@calendar=buddhist;collation=phonebook");
1847 LocalPointer
<StringEnumeration
> keys(l
.createUnicodeKeywords(status
));
1848 status
.errIfFailureAndReset("\"%s\"", l
.getName());
1851 int32_t resultLength
;
1853 key
= keys
->next(&resultLength
, status
);
1854 status
.errIfFailureAndReset("key #1");
1855 assertEquals("resultLength", 2, resultLength
);
1856 assertTrue("key != nullptr", key
!= nullptr);
1857 if (key
!= nullptr) {
1858 assertEquals("calendar", "ca", key
);
1861 key
= keys
->next(&resultLength
, status
);
1862 status
.errIfFailureAndReset("key #2");
1863 assertEquals("resultLength", 2, resultLength
);
1864 assertTrue("key != nullptr", key
!= nullptr);
1865 if (key
!= nullptr) {
1866 assertEquals("collation", "co", key
);
1869 key
= keys
->next(&resultLength
, status
);
1870 status
.errIfFailureAndReset("end of keys");
1871 assertEquals("resultLength", 0, resultLength
);
1872 assertTrue("key == nullptr", key
== nullptr);
1874 const UnicodeString
* skey
;
1875 keys
->reset(status
); // KeywordEnumeration::reset() never touches status.
1877 skey
= keys
->snext(status
);
1878 status
.errIfFailureAndReset("skey #1");
1879 assertTrue("skey != nullptr", skey
!= nullptr);
1880 if (skey
!= nullptr) {
1881 assertEquals("calendar", "ca", *skey
);
1884 skey
= keys
->snext(status
);
1885 status
.errIfFailureAndReset("skey #2");
1886 assertTrue("skey != nullptr", skey
!= nullptr);
1887 if (skey
!= nullptr) {
1888 assertEquals("collation", "co", *skey
);
1891 skey
= keys
->snext(status
);
1892 status
.errIfFailureAndReset("end of keys");
1893 assertTrue("skey == nullptr", skey
== nullptr);
1898 LocaleTest::TestKeywordVariantParsing(void) {
1899 static const struct {
1900 const char *localeID
;
1901 const char *keyword
;
1902 const char *expectedValue
;
1904 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook" },
1905 { "de_DE", "collation", ""},
1906 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" },
1907 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation", "PHONEBOOk" },
1910 UErrorCode status
= U_ZERO_ERROR
;
1913 int32_t resultLen
= 0;
1916 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
1918 Locale
l(testCases
[i
].localeID
);
1919 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
1920 (void)resultLen
; // Suppress unused variable warning.
1921 if(uprv_strcmp(testCases
[i
].expectedValue
, buffer
) != 0) {
1922 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1923 testCases
[i
].expectedValue
, testCases
[i
].localeID
, testCases
[i
].keyword
, buffer
);
1929 LocaleTest::TestCreateKeywordSet(void) {
1930 IcuTestErrorCode
status(*this, "TestCreateKeywordSet()");
1932 static const Locale
l("de@calendar=buddhist;collation=phonebook");
1934 std::set
<std::string
> result
;
1935 l
.getKeywords
<std::string
>(
1936 std::insert_iterator
<decltype(result
)>(result
, result
.begin()),
1938 status
.errIfFailureAndReset("\"%s\"", l
.getName());
1940 assertEquals("set::size()", 2, static_cast<int32_t>(result
.size()));
1941 assertTrue("set::find(\"calendar\")",
1942 result
.find("calendar") != result
.end());
1943 assertTrue("set::find(\"collation\")",
1944 result
.find("collation") != result
.end());
1948 LocaleTest::TestCreateKeywordSetEmpty(void) {
1949 IcuTestErrorCode
status(*this, "TestCreateKeywordSetEmpty()");
1951 static const Locale
l("de");
1953 std::set
<std::string
> result
;
1954 l
.getKeywords
<std::string
>(
1955 std::insert_iterator
<decltype(result
)>(result
, result
.begin()),
1957 status
.errIfFailureAndReset("\"%s\"", l
.getName());
1959 assertEquals("set::size()", 0, static_cast<int32_t>(result
.size()));
1963 LocaleTest::TestCreateUnicodeKeywordSet(void) {
1964 IcuTestErrorCode
status(*this, "TestCreateUnicodeKeywordSet()");
1966 static const Locale
l("de@calendar=buddhist;collation=phonebook");
1968 std::set
<std::string
> result
;
1969 l
.getUnicodeKeywords
<std::string
>(
1970 std::insert_iterator
<decltype(result
)>(result
, result
.begin()),
1972 status
.errIfFailureAndReset("\"%s\"", l
.getName());
1974 assertEquals("set::size()", 2, static_cast<int32_t>(result
.size()));
1975 assertTrue("set::find(\"ca\")",
1976 result
.find("ca") != result
.end());
1977 assertTrue("set::find(\"co\")",
1978 result
.find("co") != result
.end());
1982 LocaleTest::TestCreateUnicodeKeywordSetEmpty(void) {
1983 IcuTestErrorCode
status(*this, "TestCreateUnicodeKeywordSetEmpty()");
1985 static const Locale
l("de");
1987 std::set
<std::string
> result
;
1988 l
.getUnicodeKeywords
<std::string
>(
1989 std::insert_iterator
<decltype(result
)>(result
, result
.begin()),
1991 status
.errIfFailureAndReset("\"%s\"", l
.getName());
1993 assertEquals("set::size()", 0, static_cast<int32_t>(result
.size()));
1997 LocaleTest::TestGetKeywordValueStdString(void) {
1998 IcuTestErrorCode
status(*this, "TestGetKeywordValueStdString()");
2000 static const char tag
[] = "fa-u-nu-latn";
2001 static const char keyword
[] = "numbers";
2002 static const char expected
[] = "latn";
2004 Locale l
= Locale::forLanguageTag(tag
, status
);
2005 status
.errIfFailureAndReset("\"%s\"", tag
);
2007 std::string result
= l
.getKeywordValue
<std::string
>(keyword
, status
);
2008 status
.errIfFailureAndReset("\"%s\"", keyword
);
2009 assertEquals(keyword
, expected
, result
.c_str());
2013 LocaleTest::TestGetUnicodeKeywordValueStdString(void) {
2014 IcuTestErrorCode
status(*this, "TestGetUnicodeKeywordValueStdString()");
2016 static const char keyword
[] = "co";
2017 static const char expected
[] = "phonebk";
2019 static const Locale
l("de@calendar=buddhist;collation=phonebook");
2021 std::string result
= l
.getUnicodeKeywordValue
<std::string
>(keyword
, status
);
2022 status
.errIfFailureAndReset("\"%s\"", keyword
);
2023 assertEquals(keyword
, expected
, result
.c_str());
2027 LocaleTest::TestSetKeywordValue(void) {
2028 static const struct {
2029 const char *keyword
;
2032 { "collation", "phonebook" },
2033 { "currency", "euro" },
2034 { "calendar", "buddhist" }
2037 UErrorCode status
= U_ZERO_ERROR
;
2040 int32_t resultLen
= 0;
2043 Locale
l(Locale::getGerman());
2045 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2046 l
.setKeywordValue(testCases
[i
].keyword
, testCases
[i
].value
, status
);
2047 if(U_FAILURE(status
)) {
2048 err("FAIL: Locale::setKeywordValue failed - %s\n", u_errorName(status
));
2052 resultLen
= l
.getKeywordValue(testCases
[i
].keyword
, buffer
, 256, status
);
2053 (void)resultLen
; // Suppress unused variable warning.
2054 if(uprv_strcmp(testCases
[i
].value
, buffer
) != 0) {
2055 err("Expected to extract \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
2056 testCases
[i
].value
, testCases
[i
].keyword
, buffer
);
2062 LocaleTest::TestSetKeywordValueStringPiece(void) {
2063 IcuTestErrorCode
status(*this, "TestSetKeywordValueStringPiece()");
2064 Locale
l(Locale::getGerman());
2066 l
.setKeywordValue(StringPiece("collation"), StringPiece("phonebook"), status
);
2067 l
.setKeywordValue(StringPiece("calendarxxx", 8), StringPiece("buddhistxxx", 8), status
);
2069 static const char expected
[] = "de@calendar=buddhist;collation=phonebook";
2070 assertEquals("", expected
, l
.getName());
2074 LocaleTest::TestSetUnicodeKeywordValueStringPiece(void) {
2075 IcuTestErrorCode
status(*this, "TestSetUnicodeKeywordValueStringPiece()");
2076 Locale
l(Locale::getGerman());
2078 l
.setUnicodeKeywordValue(StringPiece("co"), StringPiece("phonebk"), status
);
2079 status
.errIfFailureAndReset();
2081 l
.setUnicodeKeywordValue(StringPiece("caxxx", 2), StringPiece("buddhistxxx", 8), status
);
2082 status
.errIfFailureAndReset();
2084 static const char expected
[] = "de@calendar=buddhist;collation=phonebook";
2085 assertEquals("", expected
, l
.getName());
2087 l
.setUnicodeKeywordValue("cu", nullptr, status
);
2088 status
.errIfFailureAndReset();
2089 assertEquals("", expected
, l
.getName());
2091 l
.setUnicodeKeywordValue("!!", nullptr, status
);
2092 assertEquals("status", U_ILLEGAL_ARGUMENT_ERROR
, status
.reset());
2093 assertEquals("", expected
, l
.getName());
2095 l
.setUnicodeKeywordValue("co", "!!", status
);
2096 assertEquals("status", U_ILLEGAL_ARGUMENT_ERROR
, status
.reset());
2097 assertEquals("", expected
, l
.getName());
2099 l
.setUnicodeKeywordValue("co", nullptr, status
);
2100 status
.errIfFailureAndReset();
2102 l
.setUnicodeKeywordValue("ca", "", status
);
2103 status
.errIfFailureAndReset();
2105 assertEquals("", Locale::getGerman().getName(), l
.getName());
2109 LocaleTest::TestGetBaseName(void) {
2110 static const struct {
2111 const char *localeID
;
2112 const char *baseName
;
2114 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2115 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2116 { "ja@calendar = buddhist", "ja" },
2117 { "de-u-co-phonebk", "de"}
2122 for(i
= 0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2123 Locale
loc(testCases
[i
].localeID
);
2124 if(strcmp(testCases
[i
].baseName
, loc
.getBaseName())) {
2125 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
2126 testCases
[i
].localeID
, testCases
[i
].baseName
, loc
.getBaseName());
2131 // Verify that adding a keyword to an existing Locale doesn't change the base name.
2132 UErrorCode status
= U_ZERO_ERROR
;
2133 Locale
loc2("en-US");
2134 if (strcmp("en_US", loc2
.getBaseName())) {
2135 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
2137 loc2
.setKeywordValue("key", "value", status
);
2138 if (strcmp("en_US@key=value", loc2
.getName())) {
2139 errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getName());
2141 if (strcmp("en_US", loc2
.getBaseName())) {
2142 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__
, __LINE__
, loc2
.getBaseName());
2147 * Compare two locale IDs. If they are equal, return 0. If `string'
2148 * starts with `prefix' plus an additional element, that is, string ==
2149 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2151 static UBool
_loccmp(const char* string
, const char* prefix
) {
2152 int32_t slen
= (int32_t)strlen(string
),
2153 plen
= (int32_t)strlen(prefix
);
2154 int32_t c
= uprv_strncmp(string
, prefix
, plen
);
2155 /* 'root' is "less than" everything */
2156 if (prefix
[0] == '\0') {
2157 return string
[0] != '\0';
2159 if (c
) return -1; /* mismatch */
2160 if (slen
== plen
) return 0;
2161 if (string
[plen
] == '_') return 1;
2162 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2166 * Check the relationship between requested locales, and report problems.
2167 * The caller specifies the expected relationships between requested
2168 * and valid (expReqValid) and between valid and actual (expValidActual).
2169 * Possible values are:
2170 * "gt" strictly greater than, e.g., en_US > en
2171 * "ge" greater or equal, e.g., en >= en
2172 * "eq" equal, e.g., en == en
2174 void LocaleTest::_checklocs(const char* label
,
2176 const Locale
& validLoc
,
2177 const Locale
& actualLoc
,
2178 const char* expReqValid
,
2179 const char* expValidActual
) {
2180 const char* valid
= validLoc
.getName();
2181 const char* actual
= actualLoc
.getName();
2182 int32_t reqValid
= _loccmp(req
, valid
);
2183 int32_t validActual
= _loccmp(valid
, actual
);
2184 if (((0 == uprv_strcmp(expReqValid
, "gt") && reqValid
> 0) ||
2185 (0 == uprv_strcmp(expReqValid
, "ge") && reqValid
>= 0) ||
2186 (0 == uprv_strcmp(expReqValid
, "eq") && reqValid
== 0)) &&
2187 ((0 == uprv_strcmp(expValidActual
, "gt") && validActual
> 0) ||
2188 (0 == uprv_strcmp(expValidActual
, "ge") && validActual
>= 0) ||
2189 (0 == uprv_strcmp(expValidActual
, "eq") && validActual
== 0))) {
2190 logln("%s; req=%s, valid=%s, actual=%s",
2191 label
, req
, valid
, actual
);
2193 dataerrln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
2194 label
, req
, valid
, actual
,
2195 expReqValid
, expValidActual
);
2199 void LocaleTest::TestGetLocale(void) {
2200 #if !UCONFIG_NO_SERVICE
2202 Locale valid
, actual
, reqLoc
;
2205 #if !UCONFIG_NO_FORMATTING
2207 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2208 req
= "en_US_BROOKLYN";
2209 Calendar
* cal
= Calendar::createInstance(Locale::createFromName(req
), ec
);
2210 if (U_FAILURE(ec
)) {
2211 dataerrln("FAIL: Calendar::createInstance failed - %s", u_errorName(ec
));
2213 valid
= cal
->getLocale(ULOC_VALID_LOCALE
, ec
);
2214 actual
= cal
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2215 if (U_FAILURE(ec
)) {
2216 errln("FAIL: Calendar::getLocale() failed");
2218 _checklocs("Calendar", req
, valid
, actual
);
2220 /* Make sure that it fails correctly */
2221 ec
= U_FILE_ACCESS_ERROR
;
2222 if (cal
->getLocale(ULOC_VALID_LOCALE
, ec
).getName()[0] != 0) {
2223 errln("FAIL: Calendar::getLocale() failed to fail correctly. It should have returned \"\"");
2231 // DecimalFormat, DecimalFormatSymbols
2232 #if !UCONFIG_NO_FORMATTING
2234 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2236 NumberFormat
* nf
= NumberFormat::createInstance(Locale::createFromName(req
), ec
);
2237 if (U_FAILURE(ec
)) {
2238 dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec
));
2240 DecimalFormat
* dec
= dynamic_cast<DecimalFormat
*>(nf
);
2242 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
2245 valid
= dec
->getLocale(ULOC_VALID_LOCALE
, ec
);
2246 actual
= dec
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2247 if (U_FAILURE(ec
)) {
2248 errln("FAIL: DecimalFormat::getLocale() failed");
2250 _checklocs("DecimalFormat", req
, valid
, actual
);
2253 const DecimalFormatSymbols
* sym
= dec
->getDecimalFormatSymbols();
2255 errln("FAIL: getDecimalFormatSymbols returned NULL");
2258 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
2259 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2260 if (U_FAILURE(ec
)) {
2261 errln("FAIL: DecimalFormatSymbols::getLocale() failed");
2263 _checklocs("DecimalFormatSymbols", req
, valid
, actual
);
2270 // DateFormat, DateFormatSymbols
2271 #if !UCONFIG_NO_FORMATTING
2273 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2274 req
= "de_CH_LUCERNE";
2276 DateFormat::createDateInstance(DateFormat::kDefault
,
2277 Locale::createFromName(req
));
2279 dataerrln("Error calling DateFormat::createDateInstance()");
2281 SimpleDateFormat
* dat
= dynamic_cast<SimpleDateFormat
*>(df
);
2283 errln("FAIL: DateFormat::createInstance does not return a SimpleDateFormat");
2286 valid
= dat
->getLocale(ULOC_VALID_LOCALE
, ec
);
2287 actual
= dat
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2288 if (U_FAILURE(ec
)) {
2289 errln("FAIL: SimpleDateFormat::getLocale() failed");
2291 _checklocs("SimpleDateFormat", req
, valid
, actual
);
2294 const DateFormatSymbols
* sym
= dat
->getDateFormatSymbols();
2296 errln("FAIL: getDateFormatSymbols returned NULL");
2299 valid
= sym
->getLocale(ULOC_VALID_LOCALE
, ec
);
2300 actual
= sym
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2301 if (U_FAILURE(ec
)) {
2302 errln("FAIL: DateFormatSymbols::getLocale() failed");
2304 _checklocs("DateFormatSymbols", req
, valid
, actual
);
2312 #if !UCONFIG_NO_BREAK_ITERATION
2314 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2315 req
= "es_ES_BARCELONA";
2316 reqLoc
= Locale::createFromName(req
);
2317 BreakIterator
* brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2318 if (U_FAILURE(ec
)) {
2319 dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_errorName(ec
));
2321 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2322 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2323 if (U_FAILURE(ec
)) {
2324 errln("FAIL: BreakIterator::getLocale() failed");
2326 _checklocs("BreakIterator", req
, valid
, actual
);
2329 // After registering something, the behavior should be different
2330 URegistryKey key
= BreakIterator::registerInstance(brk
, reqLoc
, UBRK_WORD
, ec
);
2331 brk
= 0; // registerInstance adopts
2332 if (U_FAILURE(ec
)) {
2333 errln("FAIL: BreakIterator::registerInstance() failed");
2335 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2336 if (U_FAILURE(ec
)) {
2337 errln("FAIL: BreakIterator::createWordInstance failed");
2339 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2340 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2341 if (U_FAILURE(ec
)) {
2342 errln("FAIL: BreakIterator::getLocale() failed");
2344 // N.B.: now expect valid==actual==req
2345 _checklocs("BreakIterator(registered)",
2346 req
, valid
, actual
, "eq", "eq");
2349 // No matter what, unregister
2350 BreakIterator::unregister(key
, ec
);
2351 if (U_FAILURE(ec
)) {
2352 errln("FAIL: BreakIterator::unregister() failed");
2358 // After unregistering, should behave normally again
2359 brk
= BreakIterator::createWordInstance(reqLoc
, ec
);
2360 if (U_FAILURE(ec
)) {
2361 errln("FAIL: BreakIterator::createWordInstance failed");
2363 valid
= brk
->getLocale(ULOC_VALID_LOCALE
, ec
);
2364 actual
= brk
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2365 if (U_FAILURE(ec
)) {
2366 errln("FAIL: BreakIterator::getLocale() failed");
2368 _checklocs("BreakIterator(unregistered)", req
, valid
, actual
);
2377 #if !UCONFIG_NO_COLLATION
2379 UErrorCode ec
= U_ZERO_ERROR
; // give each resource type its own error code
2381 checkRegisteredCollators(NULL
); // Don't expect any extras
2383 req
= "hi_IN_BHOPAL";
2384 reqLoc
= Locale::createFromName(req
);
2385 Collator
* coll
= Collator::createInstance(reqLoc
, ec
);
2386 if (U_FAILURE(ec
)) {
2387 dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(ec
));
2389 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2390 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2391 if (U_FAILURE(ec
)) {
2392 errln("FAIL: Collator::getLocale() failed");
2394 _checklocs("Collator", req
, valid
, actual
);
2397 // After registering something, the behavior should be different
2398 URegistryKey key
= Collator::registerInstance(coll
, reqLoc
, ec
);
2399 coll
= 0; // registerInstance adopts
2400 if (U_FAILURE(ec
)) {
2401 errln("FAIL: Collator::registerInstance() failed");
2403 coll
= Collator::createInstance(reqLoc
, ec
);
2404 if (U_FAILURE(ec
)) {
2405 errln("FAIL: Collator::createWordInstance failed");
2407 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2408 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2409 if (U_FAILURE(ec
)) {
2410 errln("FAIL: Collator::getLocale() failed");
2412 // N.B.: now expect valid==actual==req
2413 _checklocs("Collator(registered)",
2414 req
, valid
, actual
, "eq", "eq");
2417 checkRegisteredCollators(req
); // include hi_IN_BHOPAL
2419 // No matter what, unregister
2420 Collator::unregister(key
, ec
);
2421 if (U_FAILURE(ec
)) {
2422 errln("FAIL: Collator::unregister() failed");
2428 // After unregistering, should behave normally again
2429 coll
= Collator::createInstance(reqLoc
, ec
);
2430 if (U_FAILURE(ec
)) {
2431 errln("FAIL: Collator::createInstance failed");
2433 valid
= coll
->getLocale(ULOC_VALID_LOCALE
, ec
);
2434 actual
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, ec
);
2435 if (U_FAILURE(ec
)) {
2436 errln("FAIL: Collator::getLocale() failed");
2438 _checklocs("Collator(unregistered)", req
, valid
, actual
);
2444 checkRegisteredCollators(NULL
); // extra should be gone again
2450 #if !UCONFIG_NO_COLLATION
2452 * Compare Collator::getAvailableLocales(int) [ "old", returning an array ]
2453 * with Collator::getAvailableLocales() [ "new", returning a StringEnumeration ]
2454 * These should be identical (check their API docs) EXCEPT that
2455 * if expectExtra is non-NULL, it will be in the "new" array but not "old".
2456 * Does not return any status but calls errln on error.
2457 * @param expectExtra an extra locale, will be in "new" but not "old". Or NULL.
2459 void LocaleTest::checkRegisteredCollators(const char *expectExtra
) {
2460 UErrorCode status
= U_ZERO_ERROR
;
2461 int32_t count1
=0,count2
=0;
2462 Hashtable
oldHash(status
);
2463 Hashtable
newHash(status
);
2464 assertSuccess(WHERE
, status
);
2466 UnicodeString
expectStr(expectExtra
?expectExtra
:"n/a", "");
2468 // the 'old' list (non enumeration)
2469 const Locale
* oldList
= Collator::getAvailableLocales(count1
);
2470 if(oldList
== NULL
) {
2471 dataerrln("Error: Collator::getAvailableLocales(count) returned NULL");
2475 // the 'new' list (enumeration)
2476 LocalPointer
<StringEnumeration
> newEnum(Collator::getAvailableLocales());
2477 if(newEnum
.isNull()) {
2478 errln("Error: collator::getAvailableLocales() returned NULL");
2482 // OK. Let's add all of the OLD
2483 // then check for any in the NEW not in OLD
2484 // then check for any in OLD not in NEW.
2486 // 1. add all of OLD
2487 for(int32_t i
=0;i
<count1
;i
++) {
2488 const UnicodeString
key(oldList
[i
].getName(), "");
2489 int32_t oldI
= oldHash
.puti(key
, 1, status
);
2491 errln("Error: duplicate key %s in Collator::getAvailableLocales(count) list.\n",
2492 oldList
[i
].getName());
2495 if(expectExtra
!= NULL
&& !strcmp(expectExtra
, oldList
[i
].getName())) {
2496 errln("Inexplicably, Collator::getAvailableCollators(count) had registered collator %s. This shouldn't happen, so I am going to consider it an error.\n", expectExtra
);
2500 // 2. add all of NEW
2501 const UnicodeString
*locStr
;
2502 UBool foundExpected
= FALSE
;
2503 while((locStr
= newEnum
->snext(status
)) && U_SUCCESS(status
)) {
2506 if(expectExtra
!= NULL
&& expectStr
== *locStr
) {
2507 foundExpected
= TRUE
;
2508 logln(UnicodeString("Found expected registered collator: ","") + expectStr
);
2510 (void)foundExpected
; // Hush unused variable compiler warning.
2512 if( oldHash
.geti(*locStr
) == 0 ) {
2513 if(expectExtra
!= NULL
&& expectStr
==*locStr
) {
2514 logln(UnicodeString("As expected, Collator::getAvailableLocales(count) is missing registered collator ") + expectStr
);
2516 errln(UnicodeString("Error: Collator::getAvailableLocales(count) is missing: ","")
2520 newHash
.puti(*locStr
, 1, status
);
2523 // 3. check all of OLD again
2524 for(int32_t i
=0;i
<count1
;i
++) {
2525 const UnicodeString
key(oldList
[i
].getName(), "");
2526 int32_t newI
= newHash
.geti(key
);
2528 errln(UnicodeString("Error: Collator::getAvailableLocales() is missing: ","")
2533 int32_t expectCount2
= count1
;
2534 if(expectExtra
!= NULL
) {
2535 expectCount2
++; // if an extra item registered, bump the expect count
2538 assertEquals("Collator::getAvail() count", expectCount2
, count2
);
2544 void LocaleTest::TestVariantWithOutCountry(void) {
2545 Locale
loc("en","","POSIX");
2546 if (0 != strcmp(loc
.getVariant(), "POSIX")) {
2547 errln("FAIL: en__POSIX didn't get parsed correctly - name is %s - expected %s got %s", loc
.getName(), "POSIX", loc
.getVariant());
2549 Locale
loc2("en","","FOUR");
2550 if (0 != strcmp(loc2
.getVariant(), "FOUR")) {
2551 errln("FAIL: en__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc2
.getName(), "FOUR", loc2
.getVariant());
2553 Locale
loc3("en","Latn","","FOUR");
2554 if (0 != strcmp(loc3
.getVariant(), "FOUR")) {
2555 errln("FAIL: en_Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc3
.getName(), "FOUR", loc3
.getVariant());
2557 Locale
loc4("","Latn","","FOUR");
2558 if (0 != strcmp(loc4
.getVariant(), "FOUR")) {
2559 errln("FAIL: _Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc4
.getName(), "FOUR", loc4
.getVariant());
2561 Locale
loc5("","Latn","US","FOUR");
2562 if (0 != strcmp(loc5
.getVariant(), "FOUR")) {
2563 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc5
.getName(), "FOUR", loc5
.getVariant());
2565 Locale
loc6("de-1901");
2566 if (0 != strcmp(loc6
.getVariant(), "1901")) {
2567 errln("FAIL: de-1901 didn't get parsed correctly - name is %s - expected %s got %s", loc6
.getName(), "1901", loc6
.getVariant());
2571 static Locale
_canonicalize(int32_t selector
, /* 0==createFromName, 1==createCanonical, 2==Locale ct */
2572 const char* localeID
) {
2575 return Locale::createFromName(localeID
);
2577 return Locale::createCanonical(localeID
);
2579 return Locale(localeID
);
2585 void LocaleTest::TestCanonicalization(void)
2587 static const struct {
2588 const char *localeID
; /* input */
2589 const char *getNameID
; /* expected getName() result */
2590 const char *canonicalID
; /* expected canonicalize() result */
2592 { "ca_ES-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2593 "ca_ES_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2594 "ca_ES_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2595 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2596 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2597 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2598 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2599 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2600 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2601 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2602 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2603 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ_EURO" }, /* qz-qz uses private use iso codes */
2604 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
2605 // TODO: unify this behavior
2606 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
2607 { "de-1901", "de__1901", "de__1901" }, /* registered name */
2608 { "de-1906", "de__1906", "de__1906" }, /* registered name */
2610 /* posix behavior that used to be performed by getName */
2611 { "mr.utf8", "mr.utf8", "mr" },
2612 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2613 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2614 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2615 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2616 { "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 */
2618 /* fleshing out canonicalization */
2619 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2620 { "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" },
2621 /* already-canonical ids are not changed */
2622 { "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" },
2623 /* norwegian is just too weird, if we handle things in their full generality */
2624 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2626 /* test cases reflecting internal resource bundle usage */
2627 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2628 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2629 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
2631 // Before ICU 64, ICU locale canonicalization had some additional mappings.
2632 // They were removed for ICU-20187 "drop support for long-obsolete locale ID variants".
2633 // The following now use standard canonicalization.
2634 // Apple ICU restores these first 3 mappings deleted in open ICU 64
2635 { "", "", "en_US_POSIX" },
2636 { "C", "c", "en_US_POSIX" },
2637 { "POSIX", "posix", "en_US_POSIX" },
2639 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES_PREEURO" },
2640 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT_PREEURO" },
2641 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE_PREEURO" },
2642 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU_PREEURO" },
2643 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR_PREEURO" },
2644 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE_PREEURO" },
2645 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE_PREEURO" },
2646 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES_PREEURO" },
2647 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES_PREEURO" },
2648 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI_PREEURO" },
2649 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE_PREEURO" },
2650 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR_PREEURO" },
2651 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU_PREEURO" },
2652 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE_PREEURO" },
2653 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES_PREEURO" },
2654 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT_PREEURO" },
2655 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE_PREEURO" },
2656 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL_PREEURO" },
2657 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT_PREEURO" },
2658 { "de__PHONEBOOK", "de__PHONEBOOK", "de__PHONEBOOK" },
2659 { "en_GB_EURO", "en_GB_EURO", "en_GB_EURO" },
2660 { "en_GB@EURO", "en_GB@EURO", "en_GB_EURO" }, /* POSIX ID */
2661 { "es__TRADITIONAL", "es__TRADITIONAL", "es__TRADITIONAL" },
2662 { "hi__DIRECT", "hi__DIRECT", "hi__DIRECT" },
2663 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL" },
2664 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH_TRADITIONAL" },
2665 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW_STROKE" },
2666 { "zh__PINYIN", "zh__PINYIN", "zh__PINYIN" },
2667 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_SP_CYRL" }, /* .NET name */
2668 { "sr-SP-Latn", "sr_SP_LATN", "sr_SP_LATN" }, /* .NET name */
2669 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_YU_CYRILLIC" }, /* Linux name */
2670 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_UZ_CYRL" }, /* .NET name */
2671 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_UZ_LATN" }, /* .NET name */
2672 { "zh-CHS", "zh_CHS", "zh_CHS" }, /* .NET name */
2673 { "zh-CHT", "zh_CHT", "zh_CHT" }, /* .NET name This may change back to zh_Hant */
2674 /* PRE_EURO and EURO conversions don't affect other keywords */
2675 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES_PREEURO@calendar=Japanese" },
2676 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah" },
2677 /* currency keyword overrides PRE_EURO and EURO currency */
2678 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR" },
2679 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP" },
2682 static const char* label
[] = { "createFromName", "createCanonical", "Locale" };
2686 for (i
=0; i
< UPRV_LENGTHOF(testCases
); i
++) {
2687 for (j
=0; j
<3; ++j
) {
2688 const char* expected
= (j
==1) ? testCases
[i
].canonicalID
: testCases
[i
].getNameID
;
2689 Locale loc
= _canonicalize(j
, testCases
[i
].localeID
);
2690 const char* getName
= loc
.isBogus() ? "BOGUS" : loc
.getName();
2691 if(uprv_strcmp(expected
, getName
) != 0) {
2692 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"",
2693 label
[j
], testCases
[i
].localeID
, getName
, expected
);
2695 logln("Ok: %s(%s) => \"%s\"",
2696 label
[j
], testCases
[i
].localeID
, getName
);
2702 void LocaleTest::TestCurrencyByDate(void)
2704 #if !UCONFIG_NO_FORMATTING
2705 UErrorCode status
= U_ZERO_ERROR
;
2706 UDate date
= uprv_getUTCtime();
2707 UChar TMP
[4] = {0, 0, 0, 0};
2710 UnicodeString tempStr
, resultStr
;
2712 // Cycle through historical currencies
2713 date
= (UDate
)-630720000000.0; // pre 1961 - no currency defined
2714 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2717 errcheckln(status
, "FAIL: didn't return 0 for eo_AM - %s", u_errorName(status
));
2719 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2721 errcheckln(status
, "FAIL: eo_AM didn't return NULL - %s", u_errorName(status
));
2723 status
= U_ZERO_ERROR
;
2725 date
= (UDate
)0.0; // 1970 - one currency defined
2726 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2729 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2731 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2733 resultStr
.setTo("SUR");
2734 if (resultStr
!= tempStr
) {
2735 errcheckln(status
, "FAIL: didn't return SUR for eo_AM - %s", u_errorName(status
));
2738 date
= (UDate
)693792000000.0; // 1992 - one currency defined
2739 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2742 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2744 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2746 resultStr
.setTo("RUR");
2747 if (resultStr
!= tempStr
) {
2748 errcheckln(status
, "FAIL: didn't return RUR for eo_AM - %s", u_errorName(status
));
2751 date
= (UDate
)977616000000.0; // post 1993 - one currency defined
2752 index
= ucurr_countCurrencies("eo_AM", date
, &status
);
2755 errcheckln(status
, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status
));
2757 resLen
= ucurr_forLocaleAndDate("eo_AM", date
, index
, TMP
, 4, &status
);
2759 resultStr
.setTo("AMD");
2760 if (resultStr
!= tempStr
) {
2761 errcheckln(status
, "FAIL: didn't return AMD for eo_AM - %s", u_errorName(status
));
2764 // Locale AD has multiple currencies at once
2765 date
= (UDate
)977616000000.0; // year 2001
2766 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2769 errcheckln(status
, "FAIL: didn't return 4 for eo_AD - %s", u_errorName(status
));
2771 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2773 resultStr
.setTo("EUR");
2774 if (resultStr
!= tempStr
) {
2775 errcheckln(status
, "FAIL: didn't return EUR for eo_AD - %s", u_errorName(status
));
2777 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2779 resultStr
.setTo("ESP");
2780 if (resultStr
!= tempStr
) {
2781 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2783 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2785 resultStr
.setTo("FRF");
2786 if (resultStr
!= tempStr
) {
2787 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2789 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 4, TMP
, 4, &status
);
2791 resultStr
.setTo("ADP");
2792 if (resultStr
!= tempStr
) {
2793 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2796 date
= (UDate
)0.0; // year 1970
2797 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2800 errcheckln(status
, "FAIL: didn't return 3 for eo_AD - %s", u_errorName(status
));
2802 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2804 resultStr
.setTo("ESP");
2805 if (resultStr
!= tempStr
) {
2806 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2808 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2810 resultStr
.setTo("FRF");
2811 if (resultStr
!= tempStr
) {
2812 errcheckln(status
, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status
));
2814 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 3, TMP
, 4, &status
);
2816 resultStr
.setTo("ADP");
2817 if (resultStr
!= tempStr
) {
2818 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2821 date
= (UDate
)-630720000000.0; // year 1950
2822 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2825 errcheckln(status
, "FAIL: didn't return 2 for eo_AD - %s", u_errorName(status
));
2827 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2829 resultStr
.setTo("ESP");
2830 if (resultStr
!= tempStr
) {
2831 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2833 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 2, TMP
, 4, &status
);
2835 resultStr
.setTo("ADP");
2836 if (resultStr
!= tempStr
) {
2837 errcheckln(status
, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status
));
2840 date
= (UDate
)-2207520000000.0; // year 1900
2841 index
= ucurr_countCurrencies("eo_AD", date
, &status
);
2844 errcheckln(status
, "FAIL: didn't return 1 for eo_AD - %s", u_errorName(status
));
2846 resLen
= ucurr_forLocaleAndDate("eo_AD", date
, 1, TMP
, 4, &status
);
2848 resultStr
.setTo("ESP");
2849 if (resultStr
!= tempStr
) {
2850 errcheckln(status
, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status
));
2853 // Locale UA has gap between years 1994 - 1996
2854 date
= (UDate
)788400000000.0;
2855 index
= ucurr_countCurrencies("eo_UA", date
, &status
);
2858 errcheckln(status
, "FAIL: didn't return 0 for eo_UA - %s", u_errorName(status
));
2860 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, index
, TMP
, 4, &status
);
2862 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2864 status
= U_ZERO_ERROR
;
2866 // Test index bounds
2867 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 100, TMP
, 4, &status
);
2869 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2871 status
= U_ZERO_ERROR
;
2873 resLen
= ucurr_forLocaleAndDate("eo_UA", date
, 0, TMP
, 4, &status
);
2875 errcheckln(status
, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status
));
2877 status
= U_ZERO_ERROR
;
2879 // Test for bogus locale
2880 index
= ucurr_countCurrencies("eo_QQ", date
, &status
);
2883 errcheckln(status
, "FAIL: didn't return 0 for eo_QQ - %s", u_errorName(status
));
2885 status
= U_ZERO_ERROR
;
2886 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 1, TMP
, 4, &status
);
2888 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2890 status
= U_ZERO_ERROR
;
2891 resLen
= ucurr_forLocaleAndDate("eo_QQ", date
, 0, TMP
, 4, &status
);
2893 errcheckln(status
, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status
));
2895 status
= U_ZERO_ERROR
;
2897 // Cycle through histrocial currencies
2898 date
= (UDate
)977616000000.0; // 2001 - one currency
2899 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2902 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2904 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2906 resultStr
.setTo("AOA");
2907 if (resultStr
!= tempStr
) {
2908 errcheckln(status
, "FAIL: didn't return AOA for eo_AO - %s", u_errorName(status
));
2911 date
= (UDate
)819936000000.0; // 1996 - 2 currencies
2912 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2915 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2917 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2919 resultStr
.setTo("AOR");
2920 if (resultStr
!= tempStr
) {
2921 errcheckln(status
, "FAIL: didn't return AOR for eo_AO - %s", u_errorName(status
));
2923 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2925 resultStr
.setTo("AON");
2926 if (resultStr
!= tempStr
) {
2927 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2930 date
= (UDate
)662256000000.0; // 1991 - 2 currencies
2931 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2934 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2936 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2938 resultStr
.setTo("AON");
2939 if (resultStr
!= tempStr
) {
2940 errcheckln(status
, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status
));
2942 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 2, TMP
, 4, &status
);
2944 resultStr
.setTo("AOK");
2945 if (resultStr
!= tempStr
) {
2946 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2949 date
= (UDate
)315360000000.0; // 1980 - one currency
2950 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2953 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2955 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2957 resultStr
.setTo("AOK");
2958 if (resultStr
!= tempStr
) {
2959 errcheckln(status
, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status
));
2962 date
= (UDate
)0.0; // 1970 - no currencies
2963 index
= ucurr_countCurrencies("eo_AO", date
, &status
);
2966 errcheckln(status
, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status
));
2968 resLen
= ucurr_forLocaleAndDate("eo_AO", date
, 1, TMP
, 4, &status
);
2970 errcheckln(status
, "FAIL: eo_AO didn't return NULL - %s", u_errorName(status
));
2972 status
= U_ZERO_ERROR
;
2974 // Test with currency keyword override
2975 date
= (UDate
)977616000000.0; // 2001 - two currencies
2976 index
= ucurr_countCurrencies("eo_DE@currency=DEM", date
, &status
);
2979 errcheckln(status
, "FAIL: didn't return 2 for eo_DE@currency=DEM - %s", u_errorName(status
));
2981 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 1, TMP
, 4, &status
);
2983 resultStr
.setTo("EUR");
2984 if (resultStr
!= tempStr
) {
2985 errcheckln(status
, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s", u_errorName(status
));
2987 resLen
= ucurr_forLocaleAndDate("eo_DE@currency=DEM", date
, 2, TMP
, 4, &status
);
2989 resultStr
.setTo("DEM");
2990 if (resultStr
!= tempStr
) {
2991 errcheckln(status
, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s", u_errorName(status
));
2994 // Test Euro Support
2995 status
= U_ZERO_ERROR
; // reset
2996 date
= uprv_getUTCtime();
2999 ucurr_forLocaleAndDate("en_US", date
, 1, USD
, 4, &status
);
3002 ucurr_forLocaleAndDate("ja_JP", date
, 1, YEN
, 4, &status
);
3004 ucurr_forLocaleAndDate("en_US", date
, 1, TMP
, 4, &status
);
3005 if (u_strcmp(USD
, TMP
) != 0) {
3006 errcheckln(status
, "Fail: en_US didn't return USD - %s", u_errorName(status
));
3008 ucurr_forLocaleAndDate("en_US_Q", date
, 1, TMP
, 4, &status
);
3009 if (u_strcmp(USD
, TMP
) != 0) {
3010 errcheckln(status
, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status
));
3012 status
= U_ZERO_ERROR
; // reset
3016 void LocaleTest::TestGetVariantWithKeywords(void)
3018 Locale
l("en_US_VALLEY@foo=value");
3019 const char *variant
= l
.getVariant();
3021 test_assert(strcmp("VALLEY", variant
) == 0);
3023 UErrorCode status
= U_ZERO_ERROR
;
3025 int32_t len
= l
.getKeywordValue("foo", buffer
, 50, status
);
3027 test_assert(strcmp("value", buffer
) == 0);
3030 void LocaleTest::TestIsRightToLeft() {
3031 assertFalse("root LTR", Locale::getRoot().isRightToLeft());
3032 assertFalse("zh LTR", Locale::getChinese().isRightToLeft());
3033 assertTrue("ar RTL", Locale("ar").isRightToLeft());
3034 assertTrue("und-EG RTL", Locale("und-EG").isRightToLeft(), FALSE
, TRUE
);
3035 assertFalse("fa-Cyrl LTR", Locale("fa-Cyrl").isRightToLeft());
3036 assertTrue("en-Hebr RTL", Locale("en-Hebr").isRightToLeft());
3037 assertTrue("ckb RTL", Locale("ckb").isRightToLeft(), FALSE
, TRUE
); // Sorani Kurdish
3038 assertFalse("fil LTR", Locale("fil").isRightToLeft());
3039 assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft());
3040 // Additional Apple tests for rdar://51447187
3041 assertTrue("sd RTL", Locale("sd").isRightToLeft());
3042 assertTrue("sd_Arab RTL", Locale("sd_Arab").isRightToLeft());
3043 assertFalse("sd_Deva LTR", Locale("sd_Deva").isRightToLeft());
3044 assertFalse("mni_Beng LTR", Locale("mni_Beng").isRightToLeft());
3045 assertFalse("mni_Mtei LTR", Locale("mni_Mtei").isRightToLeft());
3046 assertFalse("sat_Deva LTR", Locale("sat_Deva").isRightToLeft());
3047 assertFalse("sat_Olck LTR", Locale("sat_Olck").isRightToLeft());
3048 assertTrue("ks RTL", Locale("ks").isRightToLeft());
3049 assertTrue("ks_Arab RTL", Locale("ks_Arab").isRightToLeft());
3050 assertTrue("ks_Aran RTL", Locale("ks_Aran").isRightToLeft());
3051 assertFalse("ks_Deva LTR", Locale("ks_Deva").isRightToLeft());
3052 assertFalse("pa LTR", Locale("pa").isRightToLeft());
3053 assertFalse("pa_Guru LTR", Locale("pa_Guru").isRightToLeft());
3054 assertTrue("pa_Arab RTL", Locale("pa_Arab").isRightToLeft());
3055 assertTrue("pa_Aran RTL", Locale("pa_Aran").isRightToLeft());
3056 assertTrue("ur RTL", Locale("ur").isRightToLeft());
3057 assertTrue("ur_Arab RTL", Locale("ur_Arab").isRightToLeft());
3058 assertTrue("ur_Aran RTL", Locale("ur_Aran").isRightToLeft());
3061 void LocaleTest::TestBug11421() {
3062 Locale::getDefault().getBaseName();
3064 const Locale
*localeList
= Locale::getAvailableLocales(numLocales
);
3065 for (int localeIndex
= 0; localeIndex
< numLocales
; localeIndex
++) {
3066 const Locale
&loc
= localeList
[localeIndex
];
3067 if (strncmp(loc
.getName(), loc
.getBaseName(), strlen(loc
.getBaseName()))) {
3068 errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"",
3069 __FILE__
, __LINE__
, loc
.getName(), loc
.getBaseName());
3075 // TestBug13277. The failure manifests as valgrind errors.
3076 // See the trac ticket for details.
3079 void LocaleTest::TestBug13277() {
3080 UErrorCode status
= U_ZERO_ERROR
;
3081 CharString
name("en-us-x-foo", -1, status
);
3082 while (name
.length() < 152) {
3083 name
.append("-x-foo", -1, status
);
3086 while (name
.length() < 160) {
3087 name
.append('z', status
);
3088 Locale
loc(name
.data(), nullptr, nullptr, nullptr);
3092 // TestBug13554 Check for read past end of array in getPosixID().
3093 // The bug shows as an Address Sanitizer failure.
3095 void LocaleTest::TestBug13554() {
3096 UErrorCode status
= U_ZERO_ERROR
;
3097 const int BUFFER_SIZE
= 100;
3098 char posixID
[BUFFER_SIZE
];
3100 for (uint32_t hostid
= 0; hostid
< 0x500; ++hostid
) {
3101 status
= U_ZERO_ERROR
;
3102 uprv_convertToPosix(hostid
, posixID
, BUFFER_SIZE
, &status
);
3106 void LocaleTest::TestBug20410() {
3107 IcuTestErrorCode
status(*this, "TestBug20410()");
3109 static const char tag1
[] = "art-lojban-x-0";
3110 static const Locale
expected1("jbo@x=0");
3111 Locale result1
= Locale::forLanguageTag(tag1
, status
);
3112 status
.errIfFailureAndReset("\"%s\"", tag1
);
3113 assertEquals(tag1
, expected1
.getName(), result1
.getName());
3115 static const char tag2
[] = "zh-xiang-u-nu-thai-x-0";
3116 static const Locale
expected2("hsn@numbers=thai;x=0");
3117 Locale result2
= Locale::forLanguageTag(tag2
, status
);
3118 status
.errIfFailureAndReset("\"%s\"", tag2
);
3119 assertEquals(tag2
, expected2
.getName(), result2
.getName());
3121 static const char locid3
[] = "art__lojban@x=0";
3122 Locale result3
= Locale::createCanonical(locid3
);
3123 static const Locale
expected3("art__LOJBAN@x=0");
3124 assertEquals(locid3
, expected3
.getName(), result3
.getName());
3126 static const char locid4
[] = "art-lojban-x-0";
3127 Locale result4
= Locale::createCanonical(locid4
);
3128 static const Locale
expected4("jbo@x=0");
3129 assertEquals(locid4
, expected4
.getName(), result4
.getName());
3132 void LocaleTest::TestConstructorAcceptsBCP47() {
3133 IcuTestErrorCode
status(*this, "TestConstructorAcceptsBCP47");
3135 Locale
loc1("ar-EG-u-nu-latn");
3136 Locale
loc2("ar-EG@numbers=latn");
3137 Locale
loc3("ar-EG");
3140 // Check getKeywordValue "numbers"
3141 val
= loc1
.getKeywordValue
<std::string
>("numbers", status
);
3142 assertEquals("BCP47 syntax has ICU keyword value", "latn", val
.c_str());
3144 val
= loc2
.getKeywordValue
<std::string
>("numbers", status
);
3145 assertEquals("ICU syntax has ICU keyword value", "latn", val
.c_str());
3147 val
= loc3
.getKeywordValue
<std::string
>("numbers", status
);
3148 assertEquals("Default, ICU keyword", "", val
.c_str());
3150 // Check getUnicodeKeywordValue "nu"
3151 val
= loc1
.getUnicodeKeywordValue
<std::string
>("nu", status
);
3152 assertEquals("BCP47 syntax has short unicode keyword value", "latn", val
.c_str());
3154 val
= loc2
.getUnicodeKeywordValue
<std::string
>("nu", status
);
3155 assertEquals("ICU syntax has short unicode keyword value", "latn", val
.c_str());
3157 val
= loc3
.getUnicodeKeywordValue
<std::string
>("nu", status
);
3158 status
.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR
, "Default, short unicode keyword");
3160 // Check getUnicodeKeywordValue "numbers"
3161 val
= loc1
.getUnicodeKeywordValue
<std::string
>("numbers", status
);
3162 assertEquals("BCP47 syntax has long unicode keyword value", "latn", val
.c_str());
3164 val
= loc2
.getUnicodeKeywordValue
<std::string
>("numbers", status
);
3165 assertEquals("ICU syntax has long unicode keyword value", "latn", val
.c_str());
3167 val
= loc3
.getUnicodeKeywordValue
<std::string
>("numbers", status
);
3168 status
.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR
, "Default, long unicode keyword");
3171 void LocaleTest::TestForLanguageTag() {
3172 IcuTestErrorCode
status(*this, "TestForLanguageTag()");
3174 static const char tag_en
[] = "en-US";
3175 static const char tag_oed
[] = "en-GB-oed";
3176 static const char tag_af
[] = "af-t-ar-i0-handwrit-u-ca-coptic-x-foo";
3177 static const char tag_ill
[] = "!";
3178 static const char tag_no_nul
[] = { 'e', 'n', '-', 'G', 'B' };
3179 static const char tag_ext
[] = "en-GB-1-abc-efg-a-xyz";
3181 static const Locale
loc_en("en_US");
3182 static const Locale
loc_oed("en_GB_OXENDICT");
3183 static const Locale
loc_af("af@calendar=coptic;t=ar-i0-handwrit;x=foo");
3184 static const Locale
loc_null("");
3185 static const Locale
loc_gb("en_GB");
3186 static const Locale
loc_ext("en_GB@1=abc-efg;a=xyz");
3188 Locale result_en
= Locale::forLanguageTag(tag_en
, status
);
3189 status
.errIfFailureAndReset("\"%s\"", tag_en
);
3190 assertEquals(tag_en
, loc_en
.getName(), result_en
.getName());
3192 Locale result_oed
= Locale::forLanguageTag(tag_oed
, status
);
3193 status
.errIfFailureAndReset("\"%s\"", tag_oed
);
3194 assertEquals(tag_oed
, loc_oed
.getName(), result_oed
.getName());
3196 Locale result_af
= Locale::forLanguageTag(tag_af
, status
);
3197 status
.errIfFailureAndReset("\"%s\"", tag_af
);
3198 assertEquals(tag_af
, loc_af
.getName(), result_af
.getName());
3200 Locale result_ill
= Locale::forLanguageTag(tag_ill
, status
);
3201 assertEquals(tag_ill
, U_ILLEGAL_ARGUMENT_ERROR
, status
.reset());
3202 assertTrue(result_ill
.getName(), result_ill
.isBogus());
3204 Locale result_null
= Locale::forLanguageTag(nullptr, status
);
3205 status
.errIfFailureAndReset("nullptr");
3206 assertEquals("nullptr", loc_null
.getName(), result_null
.getName());
3208 StringPiece
sp_substr(tag_oed
, 5); // "en-GB", no NUL.
3209 Locale result_substr
= Locale::forLanguageTag(sp_substr
, status
);
3210 status
.errIfFailureAndReset("\"%.*s\"", sp_substr
.size(), sp_substr
.data());
3211 assertEquals(CharString(sp_substr
, status
).data(),
3212 loc_gb
.getName(), result_substr
.getName());
3214 StringPiece
sp_no_nul(tag_no_nul
, sizeof tag_no_nul
); // "en-GB", no NUL.
3215 Locale result_no_nul
= Locale::forLanguageTag(sp_no_nul
, status
);
3216 status
.errIfFailureAndReset("\"%.*s\"", sp_no_nul
.size(), sp_no_nul
.data());
3217 assertEquals(CharString(sp_no_nul
, status
).data(),
3218 loc_gb
.getName(), result_no_nul
.getName());
3220 Locale result_ext
= Locale::forLanguageTag(tag_ext
, status
);
3221 status
.errIfFailureAndReset("\"%s\"", tag_ext
);
3222 assertEquals(tag_ext
, loc_ext
.getName(), result_ext
.getName());
3225 void LocaleTest::TestToLanguageTag() {
3226 IcuTestErrorCode
status(*this, "TestToLanguageTag()");
3228 static const Locale
loc_c("en_US_POSIX");
3229 static const Locale
loc_en("en_US");
3230 static const Locale
loc_af("af@calendar=coptic;t=ar-i0-handwrit;x=foo");
3231 static const Locale
loc_ext("en@0=abc;a=xyz");
3232 static const Locale
loc_empty("");
3233 static const Locale
loc_ill("!");
3235 static const char tag_c
[] = "en-US-u-va-posix";
3236 static const char tag_en
[] = "en-US";
3237 static const char tag_af
[] = "af-t-ar-i0-handwrit-u-ca-coptic-x-foo";
3238 static const char tag_ext
[] = "en-0-abc-a-xyz";
3239 static const char tag_und
[] = "und";
3242 StringByteSink
<std::string
> sink(&result
);
3243 loc_c
.toLanguageTag(sink
, status
);
3244 status
.errIfFailureAndReset("\"%s\"", loc_c
.getName());
3245 assertEquals(loc_c
.getName(), tag_c
, result
.c_str());
3247 std::string result_c
= loc_c
.toLanguageTag
<std::string
>(status
);
3248 status
.errIfFailureAndReset("\"%s\"", loc_c
.getName());
3249 assertEquals(loc_c
.getName(), tag_c
, result_c
.c_str());
3251 std::string result_en
= loc_en
.toLanguageTag
<std::string
>(status
);
3252 status
.errIfFailureAndReset("\"%s\"", loc_en
.getName());
3253 assertEquals(loc_en
.getName(), tag_en
, result_en
.c_str());
3255 std::string result_af
= loc_af
.toLanguageTag
<std::string
>(status
);
3256 status
.errIfFailureAndReset("\"%s\"", loc_af
.getName());
3257 assertEquals(loc_af
.getName(), tag_af
, result_af
.c_str());
3259 std::string result_ext
= loc_ext
.toLanguageTag
<std::string
>(status
);
3260 status
.errIfFailureAndReset("\"%s\"", loc_ext
.getName());
3261 assertEquals(loc_ext
.getName(), tag_ext
, result_ext
.c_str());
3263 std::string result_empty
= loc_empty
.toLanguageTag
<std::string
>(status
);
3264 status
.errIfFailureAndReset("\"%s\"", loc_empty
.getName());
3265 assertEquals(loc_empty
.getName(), tag_und
, result_empty
.c_str());
3267 std::string result_ill
= loc_ill
.toLanguageTag
<std::string
>(status
);
3268 status
.errIfFailureAndReset("\"%s\"", loc_ill
.getName());
3269 assertEquals(loc_ill
.getName(), tag_und
, result_ill
.c_str());
3272 loc_bogus
.setToBogus();
3273 std::string result_bogus
= loc_bogus
.toLanguageTag
<std::string
>(status
);
3274 assertEquals("bogus", U_ILLEGAL_ARGUMENT_ERROR
, status
.reset());
3275 assertTrue(result_bogus
.c_str(), result_bogus
.empty());
3278 void LocaleTest::TestMoveAssign() {
3279 // ULOC_FULLNAME_CAPACITY == 157 (uloc.h)
3280 Locale
l1("de@collation=phonebook;x="
3281 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3282 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3283 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3289 assertTrue("l1 == l3", l1
== l3
);
3291 assertTrue("l1 == l2", l1
== l2
);
3292 assertTrue("l2 != l3", l2
.getName() != l3
.getName());
3295 // This should remain true also after l3 has been destructed.
3296 assertTrue("l1 == l2, again", l1
== l2
);
3298 Locale
l4("de@collation=phonebook");
3303 assertTrue("l4 == l6", l4
== l6
);
3305 assertTrue("l4 == l5", l4
== l5
);
3306 assertTrue("l5 != l6", l5
.getName() != l6
.getName());
3309 // This should remain true also after l6 has been destructed.
3310 assertTrue("l4 == l5, again", l4
== l5
);
3312 Locale
l7("vo_Cyrl_AQ_EURO");
3317 assertTrue("l7 == l9", l7
== l9
);
3319 assertTrue("l7 == l8", l7
== l8
);
3320 assertTrue("l8 != l9", l8
.getName() != l9
.getName());
3323 // This should remain true also after l9 has been destructed.
3324 assertTrue("l7 == l8, again", l7
== l8
);
3326 assertEquals("language", l7
.getLanguage(), l8
.getLanguage());
3327 assertEquals("script", l7
.getScript(), l8
.getScript());
3328 assertEquals("country", l7
.getCountry(), l8
.getCountry());
3329 assertEquals("variant", l7
.getVariant(), l8
.getVariant());
3330 assertEquals("bogus", l7
.isBogus(), l8
.isBogus());
3333 void LocaleTest::TestMoveCtor() {
3334 // ULOC_FULLNAME_CAPACITY == 157 (uloc.h)
3335 Locale
l1("de@collation=phonebook;x="
3336 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3337 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3338 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3342 assertTrue("l1 == l3", l1
== l3
);
3343 Locale
l2(std::move(l3
));
3344 assertTrue("l1 == l2", l1
== l2
);
3345 assertTrue("l2 != l3", l2
.getName() != l3
.getName());
3347 Locale
l4("de@collation=phonebook");
3350 assertTrue("l4 == l6", l4
== l6
);
3351 Locale
l5(std::move(l6
));
3352 assertTrue("l4 == l5", l4
== l5
);
3353 assertTrue("l5 != l6", l5
.getName() != l6
.getName());
3355 Locale
l7("vo_Cyrl_AQ_EURO");
3358 assertTrue("l7 == l9", l7
== l9
);
3359 Locale
l8(std::move(l9
));
3360 assertTrue("l7 == l8", l7
== l8
);
3361 assertTrue("l8 != l9", l8
.getName() != l9
.getName());
3363 assertEquals("language", l7
.getLanguage(), l8
.getLanguage());
3364 assertEquals("script", l7
.getScript(), l8
.getScript());
3365 assertEquals("country", l7
.getCountry(), l8
.getCountry());
3366 assertEquals("variant", l7
.getVariant(), l8
.getVariant());
3367 assertEquals("bogus", l7
.isBogus(), l8
.isBogus());
3370 void LocaleTest::TestBug20407iVariantPreferredValue() {
3371 IcuTestErrorCode
status(*this, "TestBug20407iVariantPreferredValue()");
3373 Locale l
= Locale::forLanguageTag("hy-arevela", status
);
3374 status
.errIfFailureAndReset("hy-arevela fail");
3375 assertTrue("!l.isBogus()", !l
.isBogus());
3377 std::string result
= l
.toLanguageTag
<std::string
>(status
);
3378 assertEquals(l
.getName(), "hy", result
.c_str());
3380 l
= Locale::forLanguageTag("hy-arevmda", status
);
3381 status
.errIfFailureAndReset("hy-arevmda");
3382 assertTrue("!l.isBogus()", !l
.isBogus());
3384 result
= l
.toLanguageTag
<std::string
>(status
);
3385 assertEquals(l
.getName(), "hyw", result
.c_str());
3388 void LocaleTest::TestBug13417VeryLongLanguageTag() {
3389 IcuTestErrorCode
status(*this, "TestBug13417VeryLongLanguageTag()");
3391 static const char tag
[] =
3393 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3394 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3395 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3399 Locale l
= Locale::forLanguageTag(tag
, status
);
3400 status
.errIfFailureAndReset("\"%s\"", tag
);
3401 assertTrue("!l.isBogus()", !l
.isBogus());
3403 std::string result
= l
.toLanguageTag
<std::string
>(status
);
3404 status
.errIfFailureAndReset("\"%s\"", l
.getName());
3405 assertEquals("equals", tag
, result
.c_str());
3408 void LocaleTest::TestBug11053UnderlineTimeZone() {
3409 static const char* const tz_in_ext
[] = {
3471 static const char* const tzname_with_underline
[] = {
3472 "America/Buenos_Aires",
3473 "America/Coral_Harbour",
3474 "America/Los_Angeles",
3475 "America/Mexico_City",
3477 "America/Rio_Branco",
3478 "America/Sao_Paulo",
3480 "America/St_Thomas",
3481 "Australia/Broken_Hill",
3482 "Australia/Lord_Howe",
3483 "Pacific/Pago_Pago",
3485 std::string locale_str
;
3486 for (int32_t i
= 0; i
< UPRV_LENGTHOF(tz_in_ext
); i
++) {
3487 locale_str
= "en-u-tz-";
3488 locale_str
+= tz_in_ext
[i
];
3489 Locale
l(locale_str
.c_str());
3490 assertTrue((locale_str
+ " !l.isBogus()").c_str(), !l
.isBogus());
3492 for (int32_t i
= 0; i
< UPRV_LENGTHOF(tzname_with_underline
); i
++) {
3493 locale_str
= "en@timezone=";
3494 locale_str
+= tzname_with_underline
[i
];
3495 Locale
l(locale_str
.c_str());
3496 assertTrue((locale_str
+ " !l.isBogus()").c_str(), !l
.isBogus());
3498 locale_str
= "en_US@timezone=America/Coral_Harbour";
3499 Locale
l2(locale_str
.c_str());
3500 assertTrue((locale_str
+ " !l2.isBogus()").c_str(), !l2
.isBogus());
3501 locale_str
= "en_Latn@timezone=America/New_York";
3502 Locale
l3(locale_str
.c_str());
3503 assertTrue((locale_str
+ " !l3.isBogus()").c_str(), !l3
.isBogus());
3504 locale_str
= "en_Latn_US@timezone=Australia/Broken_Hill";
3505 Locale
l4(locale_str
.c_str());
3506 assertTrue((locale_str
+ " !l4.isBogus()").c_str(), !l4
.isBogus());
3507 locale_str
= "en-u-tz-ciabj";
3508 Locale
l5(locale_str
.c_str());
3509 assertTrue((locale_str
+ " !l5.isBogus()").c_str(), !l5
.isBogus());
3510 locale_str
= "en-US-u-tz-asppg";
3511 Locale
l6(locale_str
.c_str());
3512 assertTrue((locale_str
+ " !l6.isBogus()").c_str(), !l6
.isBogus());
3513 locale_str
= "fil-Latn-u-tz-cvrai";
3514 Locale
l7(locale_str
.c_str());
3515 assertTrue((locale_str
+ " !l7.isBogus()").c_str(), !l7
.isBogus());
3516 locale_str
= "fil-Latn-PH-u-tz-gsgrv";
3517 Locale
l8(locale_str
.c_str());
3518 assertTrue((locale_str
+ " !l8.isBogus()").c_str(), !l8
.isBogus());
3521 void LocaleTest::TestUnd() {
3522 IcuTestErrorCode
status(*this, "TestUnd()");
3524 static const char empty
[] = "";
3525 static const char root
[] = "root";
3526 static const char und
[] = "und";
3528 Locale
empty_ctor(empty
);
3529 Locale empty_tag
= Locale::forLanguageTag(empty
, status
);
3530 status
.errIfFailureAndReset("\"%s\"", empty
);
3532 Locale
root_ctor(root
);
3533 Locale root_tag
= Locale::forLanguageTag(root
, status
);
3534 Locale root_build
= LocaleBuilder().setLanguageTag(root
).build(status
);
3535 status
.errIfFailureAndReset("\"%s\"", root
);
3537 Locale
und_ctor(und
);
3538 Locale und_tag
= Locale::forLanguageTag(und
, status
);
3539 Locale und_build
= LocaleBuilder().setLanguageTag(und
).build(status
);
3540 status
.errIfFailureAndReset("\"%s\"", und
);
3542 assertEquals("getName() 1", empty
, empty_ctor
.getName());
3543 assertEquals("getName() 2", root
, root_ctor
.getName()); // open ICU expects empty
3544 assertEquals("getName() 3", und
, und_ctor
.getName()); // open ICU expects empty
3546 assertEquals("getName() 4", empty
, empty_tag
.getName());
3547 assertEquals("getName() 5", root
, root_tag
.getName()); // open ICU expects empty
3548 assertEquals("getName() 6", empty
, und_tag
.getName());
3550 assertEquals("getName() 7", root
, root_build
.getName()); // open ICU expects empty
3551 assertEquals("getName() 8", empty
, und_build
.getName());
3553 assertEquals("toLanguageTag() 1", und
, empty_ctor
.toLanguageTag
<std::string
>(status
).c_str());
3554 assertEquals("toLanguageTag() 2", root
, root_ctor
.toLanguageTag
<std::string
>(status
).c_str()); // open ICU expects und
3555 assertEquals("toLanguageTag() 3", und
, und_ctor
.toLanguageTag
<std::string
>(status
).c_str());
3556 status
.errIfFailureAndReset();
3558 assertEquals("toLanguageTag() 4", und
, empty_tag
.toLanguageTag
<std::string
>(status
).c_str());
3559 assertEquals("toLanguageTag() 5", root
, root_tag
.toLanguageTag
<std::string
>(status
).c_str()); // open ICU expects und
3560 assertEquals("toLanguageTag() 6", und
, und_tag
.toLanguageTag
<std::string
>(status
).c_str());
3561 status
.errIfFailureAndReset();
3563 assertEquals("toLanguageTag() 7", root
, root_build
.toLanguageTag
<std::string
>(status
).c_str()); // open ICU expects und
3564 assertEquals("toLanguageTag() 8", und
, und_build
.toLanguageTag
<std::string
>(status
).c_str());
3565 status
.errIfFailureAndReset();
3567 assertTrue("empty_ctor == empty_tag", empty_ctor
== empty_tag
);
3569 assertTrue("root_ctor == root_tag", root_ctor
== root_tag
);
3570 assertTrue("root_ctor == root_build", root_ctor
== root_build
);
3571 assertTrue("root_tag == root_build", root_tag
== root_build
);
3573 //assertTrue("und_ctor == und_tag", und_ctor == und_tag); // change from open ICU
3574 //assertTrue("und_ctor == und_build", und_ctor == und_build); // change from open ICU
3575 assertTrue("und_tag == und_build", und_tag
== und_build
);
3577 //assertTrue("empty_ctor == root_ctor", empty_ctor == root_ctor); // change from open ICU
3578 //assertTrue("empty_ctor == und_ctor", empty_ctor == und_ctor); // change from open ICU
3579 //assertTrue("root_ctor == und_ctor", root_ctor == und_ctor); // change from open ICU
3581 //assertTrue("empty_tag == root_tag", empty_tag == root_tag); // change from open ICU
3582 assertTrue("empty_tag == und_tag", empty_tag
== und_tag
);
3583 //assertTrue("root_tag == und_tag", root_tag == und_tag); // change from open ICU
3585 //assertTrue("root_build == und_build", root_build == und_build); // change from open ICU
3587 static const Locale
& displayLocale
= Locale::getEnglish();
3588 static const UnicodeString
displayName("Unknown language");
3589 static const UnicodeString
displayRoot("Root");
3590 static const UnicodeString
displayEmpty("");
3593 assertEquals("getDisplayName() 1", displayEmpty
, empty_ctor
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3594 assertEquals("getDisplayName() 2", displayRoot
, root_ctor
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3595 assertEquals("getDisplayName() 3", displayName
, und_ctor
.getDisplayName(displayLocale
, tmp
));
3597 assertEquals("getDisplayName() 4", displayEmpty
, empty_tag
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3598 assertEquals("getDisplayName() 5", displayRoot
, root_tag
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3599 assertEquals("getDisplayName() 6", displayEmpty
, und_tag
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3601 assertEquals("getDisplayName() 7", displayRoot
, root_build
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3602 assertEquals("getDisplayName() 8", displayEmpty
, und_build
.getDisplayName(displayLocale
, tmp
)); // change from open ICU
3605 void LocaleTest::TestUndScript() {
3606 IcuTestErrorCode
status(*this, "TestUndScript()");
3608 static const char id
[] = "_Cyrl";
3609 static const char tag
[] = "und-Cyrl";
3610 static const char script
[] = "Cyrl";
3611 static const char tag_
[] = "und_Cyrl";
3613 Locale
locale_ctor(id
);
3614 Locale
locale_legacy(tag
);
3615 Locale locale_tag
= Locale::forLanguageTag(tag
, status
);
3616 Locale locale_build
= LocaleBuilder().setScript(script
).build(status
);
3617 status
.errIfFailureAndReset("\"%s\"", tag
);
3619 assertEquals("getName() 1", id
, locale_ctor
.getName());
3620 assertEquals("getName() 2", tag_
, locale_legacy
.getName()); // change from open ICU
3621 assertEquals("getName() 3", id
, locale_tag
.getName());
3622 assertEquals("getName() 4", id
, locale_build
.getName());
3624 assertEquals("toLanguageTag()", tag
, locale_ctor
.toLanguageTag
<std::string
>(status
).c_str());
3625 assertEquals("toLanguageTag()", tag
, locale_legacy
.toLanguageTag
<std::string
>(status
).c_str());
3626 assertEquals("toLanguageTag()", tag
, locale_tag
.toLanguageTag
<std::string
>(status
).c_str());
3627 assertEquals("toLanguageTag()", tag
, locale_build
.toLanguageTag
<std::string
>(status
).c_str());
3628 status
.errIfFailureAndReset();
3630 static const Locale
& displayLocale
= Locale::getEnglish();
3631 static const UnicodeString
displayName("Unknown language (Cyrillic)");
3632 static const UnicodeString
displayScript("Cyrillic");
3635 assertEquals("getDisplayName() 1", displayScript
, locale_ctor
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3636 assertEquals("getDisplayName() 2", displayName
, locale_legacy
.getDisplayName(displayLocale
, tmp
));
3637 assertEquals("getDisplayName() 3", displayScript
, locale_tag
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3638 assertEquals("getDisplayName() 4", displayScript
, locale_build
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3641 void LocaleTest::TestUndRegion() {
3642 IcuTestErrorCode
status(*this, "TestUndRegion()");
3644 static const char id
[] = "_AQ";
3645 static const char tag
[] = "und-AQ";
3646 static const char region
[] = "AQ";
3647 static const char tag_
[] = "und_AQ";
3649 Locale
locale_ctor(id
);
3650 Locale
locale_legacy(tag
);
3651 Locale locale_tag
= Locale::forLanguageTag(tag
, status
);
3652 Locale locale_build
= LocaleBuilder().setRegion(region
).build(status
);
3653 status
.errIfFailureAndReset("\"%s\"", tag
);
3655 assertEquals("getName() 1", id
, locale_ctor
.getName());
3656 assertEquals("getName() 2", tag_
, locale_legacy
.getName()); // change from open ICU
3657 assertEquals("getName() 3", id
, locale_tag
.getName());
3658 assertEquals("getName() 4", id
, locale_build
.getName());
3660 assertEquals("toLanguageTag()", tag
, locale_ctor
.toLanguageTag
<std::string
>(status
).c_str());
3661 assertEquals("toLanguageTag()", tag
, locale_legacy
.toLanguageTag
<std::string
>(status
).c_str());
3662 assertEquals("toLanguageTag()", tag
, locale_tag
.toLanguageTag
<std::string
>(status
).c_str());
3663 assertEquals("toLanguageTag()", tag
, locale_build
.toLanguageTag
<std::string
>(status
).c_str());
3664 status
.errIfFailureAndReset();
3666 static const Locale
& displayLocale
= Locale::getEnglish();
3667 static const UnicodeString
displayName("Unknown language (Antarctica)");
3668 static const UnicodeString
displayRegion("Antarctica");
3671 assertEquals("getDisplayName() 1", displayRegion
, locale_ctor
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3672 assertEquals("getDisplayName() 2", displayName
, locale_legacy
.getDisplayName(displayLocale
, tmp
));
3673 assertEquals("getDisplayName() 3", displayRegion
, locale_tag
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3674 assertEquals("getDisplayName() 4", displayRegion
, locale_build
.getDisplayName(displayLocale
, tmp
)); // change from open-source
3677 void LocaleTest::TestUndCAPI() {
3678 IcuTestErrorCode
status(*this, "TestUndCAPI()");
3680 static const char empty
[] = "";
3681 static const char root
[] = "root";
3682 static const char und
[] = "und";
3684 static const char empty_script
[] = "_Cyrl";
3685 static const char empty_region
[] = "_AQ";
3687 static const char und_script
[] = "und_Cyrl";
3688 static const char und_region
[] = "und_AQ";
3690 char tmp
[ULOC_FULLNAME_CAPACITY
];
3695 uprv_memset(tmp
, '!', sizeof tmp
);
3696 reslen
= uloc_getName(empty
, tmp
, sizeof tmp
, status
);
3697 status
.errIfFailureAndReset("\"%s\"", empty
);
3698 assertTrue("reslen >= 0", reslen
>= 0);
3699 assertEquals("uloc_getName() 1", empty
, tmp
);
3701 uprv_memset(tmp
, '!', sizeof tmp
);
3702 reslen
= uloc_getName(root
, tmp
, sizeof tmp
, status
);
3703 status
.errIfFailureAndReset("\"%s\"", root
);
3704 assertTrue("reslen >= 0", reslen
>= 0);
3705 assertEquals("uloc_getName() 2", root
, tmp
); // change from open ICU
3707 uprv_memset(tmp
, '!', sizeof tmp
);
3708 reslen
= uloc_getName(und
, tmp
, sizeof tmp
, status
);
3709 status
.errIfFailureAndReset("\"%s\"", und
);
3710 assertTrue("reslen >= 0", reslen
>= 0);
3711 assertEquals("uloc_getName() 3", und
, tmp
); // change from open ICU
3713 uprv_memset(tmp
, '!', sizeof tmp
);
3714 reslen
= uloc_getName(empty_script
, tmp
, sizeof tmp
, status
);
3715 status
.errIfFailureAndReset("\"%s\"", empty_script
);
3716 assertTrue("reslen >= 0", reslen
>= 0);
3717 assertEquals("uloc_getName() 4", empty_script
, tmp
);
3719 uprv_memset(tmp
, '!', sizeof tmp
);
3720 reslen
= uloc_getName(empty_region
, tmp
, sizeof tmp
, status
);
3721 status
.errIfFailureAndReset("\"%s\"", empty_region
);
3722 assertTrue("reslen >= 0", reslen
>= 0);
3723 assertEquals("uloc_getName() 5", empty_region
, tmp
);
3725 uprv_memset(tmp
, '!', sizeof tmp
);
3726 reslen
= uloc_getName(und_script
, tmp
, sizeof tmp
, status
);
3727 status
.errIfFailureAndReset("\"%s\"", und_script
);
3728 assertTrue("reslen >= 0", reslen
>= 0);
3729 assertEquals("uloc_getName() 6", und_script
, tmp
); // change from open ICU
3731 uprv_memset(tmp
, '!', sizeof tmp
);
3732 reslen
= uloc_getName(und_region
, tmp
, sizeof tmp
, status
);
3733 status
.errIfFailureAndReset("\"%s\"", und_region
);
3734 assertTrue("reslen >= 0", reslen
>= 0);
3735 assertEquals("uloc_getName() 7", und_region
, tmp
); // change from open ICU
3737 // uloc_getBaseName()
3739 uprv_memset(tmp
, '!', sizeof tmp
);
3740 reslen
= uloc_getBaseName(empty
, tmp
, sizeof tmp
, status
);
3741 status
.errIfFailureAndReset("\"%s\"", empty
);
3742 assertTrue("reslen >= 0", reslen
>= 0);
3743 assertEquals("uloc_getBaseName() 1", empty
, tmp
);
3745 uprv_memset(tmp
, '!', sizeof tmp
);
3746 reslen
= uloc_getBaseName(root
, tmp
, sizeof tmp
, status
);
3747 status
.errIfFailureAndReset("\"%s\"", root
);
3748 assertTrue("reslen >= 0", reslen
>= 0);
3749 assertEquals("uloc_getBaseName() 2", root
, tmp
); // change from open ICU
3751 uprv_memset(tmp
, '!', sizeof tmp
);
3752 reslen
= uloc_getBaseName(und
, tmp
, sizeof tmp
, status
);
3753 status
.errIfFailureAndReset("\"%s\"", und
);
3754 assertTrue("reslen >= 0", reslen
>= 0);
3755 assertEquals("uloc_getBaseName() 3", und
, tmp
); // change from open ICU
3757 uprv_memset(tmp
, '!', sizeof tmp
);
3758 reslen
= uloc_getBaseName(empty_script
, tmp
, sizeof tmp
, status
);
3759 status
.errIfFailureAndReset("\"%s\"", empty_script
);
3760 assertTrue("reslen >= 0", reslen
>= 0);
3761 assertEquals("uloc_getBaseName() 4", empty_script
, tmp
);
3763 uprv_memset(tmp
, '!', sizeof tmp
);
3764 reslen
= uloc_getBaseName(empty_region
, tmp
, sizeof tmp
, status
);
3765 status
.errIfFailureAndReset("\"%s\"", empty_region
);
3766 assertTrue("reslen >= 0", reslen
>= 0);
3767 assertEquals("uloc_getBaseName() 5", empty_region
, tmp
);
3769 uprv_memset(tmp
, '!', sizeof tmp
);
3770 reslen
= uloc_getBaseName(und_script
, tmp
, sizeof tmp
, status
);
3771 status
.errIfFailureAndReset("\"%s\"", und_script
);
3772 assertTrue("reslen >= 0", reslen
>= 0);
3773 assertEquals("uloc_getBaseName() 6", und_script
, tmp
); // change from open ICU
3775 uprv_memset(tmp
, '!', sizeof tmp
);
3776 reslen
= uloc_getBaseName(und_region
, tmp
, sizeof tmp
, status
);
3777 status
.errIfFailureAndReset("\"%s\"", und_region
);
3778 assertTrue("reslen >= 0", reslen
>= 0);
3779 assertEquals("uloc_getBaseName() 7", und_region
, tmp
); // change from open ICU
3783 uprv_memset(tmp
, '!', sizeof tmp
);
3784 reslen
= uloc_getParent(empty
, tmp
, sizeof tmp
, status
);
3785 status
.errIfFailureAndReset("\"%s\"", empty
);
3786 assertTrue("reslen >= 0", reslen
>= 0);
3787 assertEquals("uloc_getParent() 1", empty
, tmp
);
3789 uprv_memset(tmp
, '!', sizeof tmp
);
3790 reslen
= uloc_getParent(root
, tmp
, sizeof tmp
, status
);
3791 status
.errIfFailureAndReset("\"%s\"", root
);
3792 assertTrue("reslen >= 0", reslen
>= 0);
3793 assertEquals("uloc_getParent() 2", empty
, tmp
);
3795 uprv_memset(tmp
, '!', sizeof tmp
);
3796 reslen
= uloc_getParent(und
, tmp
, sizeof tmp
, status
);
3797 status
.errIfFailureAndReset("\"%s\"", und
);
3798 assertTrue("reslen >= 0", reslen
>= 0);
3799 assertEquals("uloc_getParent() 3", empty
, tmp
);
3801 uprv_memset(tmp
, '!', sizeof tmp
);
3802 reslen
= uloc_getParent(empty_script
, tmp
, sizeof tmp
, status
);
3803 status
.errIfFailureAndReset("\"%s\"", empty_script
);
3804 assertTrue("reslen >= 0", reslen
>= 0);
3805 assertEquals("uloc_getParent() 4", empty
, tmp
);
3807 uprv_memset(tmp
, '!', sizeof tmp
);
3808 reslen
= uloc_getParent(empty_region
, tmp
, sizeof tmp
, status
);
3809 status
.errIfFailureAndReset("\"%s\"", empty_region
);
3810 assertTrue("reslen >= 0", reslen
>= 0);
3811 assertEquals("uloc_getParent() 5", empty
, tmp
);
3813 uprv_memset(tmp
, '!', sizeof tmp
);
3814 reslen
= uloc_getParent(und_script
, tmp
, sizeof tmp
, status
);
3815 status
.errIfFailureAndReset("\"%s\"", und_script
);
3816 assertTrue("reslen >= 0", reslen
>= 0);
3817 assertEquals("uloc_getParent() 6", und
, tmp
); // change from open ICU
3819 uprv_memset(tmp
, '!', sizeof tmp
);
3820 reslen
= uloc_getParent(und_region
, tmp
, sizeof tmp
, status
);
3821 status
.errIfFailureAndReset("\"%s\"", und_region
);
3822 assertTrue("reslen >= 0", reslen
>= 0);
3823 assertEquals("uloc_getParent() 7", und
, tmp
); // change from open ICU
3825 // uloc_getLanguage()
3827 uprv_memset(tmp
, '!', sizeof tmp
);
3828 reslen
= uloc_getLanguage(empty
, tmp
, sizeof tmp
, status
);
3829 status
.errIfFailureAndReset("\"%s\"", empty
);
3830 assertTrue("reslen >= 0", reslen
>= 0);
3831 assertEquals("uloc_getLanguage() 1", empty
, tmp
);
3833 uprv_memset(tmp
, '!', sizeof tmp
);
3834 reslen
= uloc_getLanguage(root
, tmp
, sizeof tmp
, status
);
3835 status
.errIfFailureAndReset("\"%s\"", root
);
3836 assertTrue("reslen >= 0", reslen
>= 0);
3837 assertEquals("uloc_getLanguage() 2", root
, tmp
); // change from open ICU
3839 uprv_memset(tmp
, '!', sizeof tmp
);
3840 reslen
= uloc_getLanguage(und
, tmp
, sizeof tmp
, status
);
3841 status
.errIfFailureAndReset("\"%s\"", und
);
3842 assertTrue("reslen >= 0", reslen
>= 0);
3843 assertEquals("uloc_getLanguage() 3", und
, tmp
); // change from open ICU
3845 uprv_memset(tmp
, '!', sizeof tmp
);
3846 reslen
= uloc_getLanguage(empty_script
, tmp
, sizeof tmp
, status
);
3847 status
.errIfFailureAndReset("\"%s\"", empty_script
);
3848 assertTrue("reslen >= 0", reslen
>= 0);
3849 assertEquals("uloc_getLanguage() 4", empty
, tmp
);
3851 uprv_memset(tmp
, '!', sizeof tmp
);
3852 reslen
= uloc_getLanguage(empty_region
, tmp
, sizeof tmp
, status
);
3853 status
.errIfFailureAndReset("\"%s\"", empty_region
);
3854 assertTrue("reslen >= 0", reslen
>= 0);
3855 assertEquals("uloc_getLanguage() 5", empty
, tmp
);
3857 uprv_memset(tmp
, '!', sizeof tmp
);
3858 reslen
= uloc_getLanguage(und_script
, tmp
, sizeof tmp
, status
);
3859 status
.errIfFailureAndReset("\"%s\"", und_script
);
3860 assertTrue("reslen >= 0", reslen
>= 0);
3861 assertEquals("uloc_getLanguage() 6", und
, tmp
); // change from open ICU
3863 uprv_memset(tmp
, '!', sizeof tmp
);
3864 reslen
= uloc_getLanguage(und_region
, tmp
, sizeof tmp
, status
);
3865 status
.errIfFailureAndReset("\"%s\"", und_region
);
3866 assertTrue("reslen >= 0", reslen
>= 0);
3867 assertEquals("uloc_getLanguage() 7", und
, tmp
); // change from open ICU
3870 #define ARRAY_RANGE(array) (array), ((array) + UPRV_LENGTHOF(array))
3872 void LocaleTest::TestRangeIterator() {
3873 IcuTestErrorCode
status(*this, "TestRangeIterator");
3874 Locale locales
[] = { "fr", "en_GB", "en" };
3875 Locale::RangeIterator
<Locale
*> iter(ARRAY_RANGE(locales
));
3877 assertTrue("0.hasNext()", iter
.hasNext());
3878 const Locale
&l0
= iter
.next();
3879 assertEquals("0.next()", "fr", l0
.getName());
3880 assertTrue("&0.next()", &l0
== &locales
[0]);
3882 assertTrue("1.hasNext()", iter
.hasNext());
3883 const Locale
&l1
= iter
.next();
3884 assertEquals("1.next()", "en_GB", l1
.getName());
3885 assertTrue("&1.next()", &l1
== &locales
[1]);
3887 assertTrue("2.hasNext()", iter
.hasNext());
3888 const Locale
&l2
= iter
.next();
3889 assertEquals("2.next()", "en", l2
.getName());
3890 assertTrue("&2.next()", &l2
== &locales
[2]);
3892 assertFalse("3.hasNext()", iter
.hasNext());
3895 void LocaleTest::TestPointerConvertingIterator() {
3896 IcuTestErrorCode
status(*this, "TestPointerConvertingIterator");
3897 Locale locales
[] = { "fr", "en_GB", "en" };
3898 Locale
*pointers
[] = { locales
, locales
+ 1, locales
+ 2 };
3899 // Lambda with explicit reference return type to prevent copy-constructing a temporary
3900 // which would be destructed right away.
3901 Locale::ConvertingIterator
<Locale
**, std::function
<const Locale
&(const Locale
*)>> iter(
3902 ARRAY_RANGE(pointers
), [](const Locale
*p
) -> const Locale
& { return *p
; });
3904 assertTrue("0.hasNext()", iter
.hasNext());
3905 const Locale
&l0
= iter
.next();
3906 assertEquals("0.next()", "fr", l0
.getName());
3907 assertTrue("&0.next()", &l0
== pointers
[0]);
3909 assertTrue("1.hasNext()", iter
.hasNext());
3910 const Locale
&l1
= iter
.next();
3911 assertEquals("1.next()", "en_GB", l1
.getName());
3912 assertTrue("&1.next()", &l1
== pointers
[1]);
3914 assertTrue("2.hasNext()", iter
.hasNext());
3915 const Locale
&l2
= iter
.next();
3916 assertEquals("2.next()", "en", l2
.getName());
3917 assertTrue("&2.next()", &l2
== pointers
[2]);
3919 assertFalse("3.hasNext()", iter
.hasNext());
3924 class LocaleFromTag
{
3926 LocaleFromTag() : locale(Locale::getRoot()) {}
3927 const Locale
&operator()(const char *tag
) { return locale
= Locale(tag
); }
3930 // Store the locale in the converter, rather than return a reference to a temporary,
3931 // or a value which could go out of scope with the caller's reference to it.
3937 void LocaleTest::TestTagConvertingIterator() {
3938 IcuTestErrorCode
status(*this, "TestTagConvertingIterator");
3939 const char *tags
[] = { "fr", "en_GB", "en" };
3940 LocaleFromTag converter
;
3941 Locale::ConvertingIterator
<const char **, LocaleFromTag
> iter(ARRAY_RANGE(tags
), converter
);
3943 assertTrue("0.hasNext()", iter
.hasNext());
3944 const Locale
&l0
= iter
.next();
3945 assertEquals("0.next()", "fr", l0
.getName());
3947 assertTrue("1.hasNext()", iter
.hasNext());
3948 const Locale
&l1
= iter
.next();
3949 assertEquals("1.next()", "en_GB", l1
.getName());
3951 assertTrue("2.hasNext()", iter
.hasNext());
3952 const Locale
&l2
= iter
.next();
3953 assertEquals("2.next()", "en", l2
.getName());
3955 assertFalse("3.hasNext()", iter
.hasNext());
3958 void LocaleTest::TestCapturingTagConvertingIterator() {
3959 IcuTestErrorCode
status(*this, "TestCapturingTagConvertingIterator");
3960 const char *tags
[] = { "fr", "en_GB", "en" };
3961 // Store the converted locale in a locale variable,
3962 // rather than return a reference to a temporary,
3963 // or a value which could go out of scope with the caller's reference to it.
3965 // Lambda with explicit reference return type to prevent copy-constructing a temporary
3966 // which would be destructed right away.
3967 Locale::ConvertingIterator
<const char **, std::function
<const Locale
&(const char *)>> iter(
3968 ARRAY_RANGE(tags
), [&](const char *tag
) -> const Locale
& { return locale
= Locale(tag
); });
3970 assertTrue("0.hasNext()", iter
.hasNext());
3971 const Locale
&l0
= iter
.next();
3972 assertEquals("0.next()", "fr", l0
.getName());
3974 assertTrue("1.hasNext()", iter
.hasNext());
3975 const Locale
&l1
= iter
.next();
3976 assertEquals("1.next()", "en_GB", l1
.getName());
3978 assertTrue("2.hasNext()", iter
.hasNext());
3979 const Locale
&l2
= iter
.next();
3980 assertEquals("2.next()", "en", l2
.getName());
3982 assertFalse("3.hasNext()", iter
.hasNext());
3985 void LocaleTest::TestSetUnicodeKeywordValueInLongLocale() {
3986 IcuTestErrorCode
status(*this, "TestSetUnicodeKeywordValueInLongLocale");
3987 const char* value
= "efghijkl";
3988 icu::Locale
l("de");
3990 CharString
expected("de-u", status
);
3992 for (char i
= 'a'; i
< 's'; i
++) {
3993 keyword
[0] = keyword
[1] = i
;
3994 expected
.append("-", status
);
3995 expected
.append(keyword
, status
);
3996 expected
.append("-", status
);
3997 expected
.append(value
, status
);
3998 l
.setUnicodeKeywordValue(keyword
, value
, status
);
3999 if (status
.errIfFailureAndReset(
4000 "setUnicodeKeywordValue(\"%s\", \"%s\") fail while locale is \"%s\"",
4001 keyword
, value
, l
.getName())) {
4004 std::string tag
= l
.toLanguageTag
<std::string
>(status
);
4005 if (status
.errIfFailureAndReset(
4006 "toLanguageTag fail on \"%s\"", l
.getName())) {
4009 if (tag
!= expected
.data()) {
4010 errln("Expected to get \"%s\" bug got \"%s\"", tag
.c_str(),
4017 void LocaleTest::TestSetUnicodeKeywordValueNullInLongLocale() {
4018 IcuTestErrorCode
status(*this, "TestSetUnicodeKeywordValueNullInLongLocale");
4019 const char *exts
[] = {"cf", "cu", "em", "kk", "kr", "ks", "kv", "lb", "lw",
4020 "ms", "nu", "rg", "sd", "ss", "tz"};
4021 for (int32_t i
= 0; i
< UPRV_LENGTHOF(exts
); i
++) {
4022 CharString
tag("de-u", status
);
4023 for (int32_t j
= 0; j
<= i
; j
++) {
4024 tag
.append("-", status
).append(exts
[j
], status
);
4026 if (status
.errIfFailureAndReset(
4027 "Cannot create tag \"%s\"", tag
.data())) {
4030 Locale l
= Locale::forLanguageTag(tag
.data(), status
);
4031 if (status
.errIfFailureAndReset(
4032 "Locale::forLanguageTag(\"%s\") failed", tag
.data())) {
4035 for (int32_t j
= 0; j
<= i
; j
++) {
4036 l
.setUnicodeKeywordValue(exts
[j
], nullptr, status
);
4037 if (status
.errIfFailureAndReset(
4038 "Locale(\"%s\").setUnicodeKeywordValue(\"%s\", nullptr) failed",
4039 tag
.data(), exts
[j
])) {
4043 if (strcmp("de", l
.getName()) != 0) {
4044 errln("setUnicodeKeywordValue should remove all extensions from "
4045 "\"%s\" and only have \"de\", but is \"%s\" instead.",
4046 tag
.data(), l
.getName());