]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/loctest.cpp
ICU-64232.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / loctest.cpp
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4 * COPYRIGHT:
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8
9 #include <iterator>
10 #include <set>
11 #include <utility>
12
13 #include "loctest.h"
14 #include "unicode/localebuilder.h"
15 #include "unicode/localpointer.h"
16 #include "unicode/decimfmt.h"
17 #include "unicode/ucurr.h"
18 #include "unicode/smpdtfmt.h"
19 #include "unicode/strenum.h"
20 #include "unicode/dtfmtsym.h"
21 #include "unicode/brkiter.h"
22 #include "unicode/coll.h"
23 #include "unicode/ustring.h"
24 #include "unicode/std_string.h"
25 #include "charstr.h"
26 #include "cmemory.h"
27 #include "cstring.h"
28 #include <stdio.h>
29 #include <string.h>
30 #include "putilimp.h"
31 #include "hash.h"
32 #include "locmap.h"
33
34 static const char* const rawData[33][8] = {
35
36 // language code
37 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" },
38 // script code
39 { "", "", "", "", "", "", "", "Hans" },
40 // country code
41 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" },
42 // variant code
43 { "", "", "", "", "NY", "", "", "" },
44 // full name
45 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" },
46 // ISO-3 language
47 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" },
48 // ISO-3 country
49 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" },
50 // LCID
51 { "409", "40c", "403", "408", "814", "10", "0", "804" },
52
53 // display language (English)
54 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" },
55 // display script (English)
56 { "", "", "", "", "", "", "", "Simplified Han" },
57 // display country (English)
58 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China mainland" },
59 // display variant (English)
60 { "", "", "", "", "NY", "", "", ""},
61 // display name (English)
62 // Updated no_NO_NY English display name for new pattern-based algorithm
63 // (part of Euro support).
64 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese, Simplified (China mainland)" },
65
66 // display language (French)
67 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" },
68 // display script (French)
69 { "", "", "", "", "", "", "", "sinogrammes simplifi\\u00E9s" },
70 // display country (French)
71 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine continentale" },
72 // display variant (French)
73 { "", "", "", "", "NY", "", "", "" },
74 // display name (French)
75 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" },
76 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien", "xx (YY)", "chinois simplifi\\u00E9 (Chine continentale)" },
77
78
79 /* display language (Catalan) */
80 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E8s" },
81 /* display script (Catalan) */
82 { "", "", "", "", "", "", "", "han simplificat" },
83 /* display country (Catalan) */
84 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina continental" },
85 /* display variant (Catalan) */
86 { "", "", "", "", "NY", "", "" },
87 /* display name (Catalan) */
88 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E0", "", "xin\\u00E8s simplificat (Xina continental)" },
89
90 // display language (Greek)[actual values listed below]
91 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac",
92 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac",
93 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac",
94 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac",
95 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac",
96 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
97 "",
98 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC"
99 },
100 // display script (Greek)
101 { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd" },
102 // display country (Greek)[actual values listed below]
103 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2",
104 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1",
105 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1",
106 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1",
107 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1",
108 "",
109 "",
110 "\\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE"
111 },
112 // display variant (Greek)
113 { "", "", "", "", "NY", "", "" },
114 // display name (Greek)[actual values listed below]
115 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2)",
116 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)",
117 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)",
118 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)",
119 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)",
120 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac",
121 "",
122 "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03b1 \\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u039A\\u03AF\\u03BD\\u03B1 \\u03B7\\u03C0\\u03B5\\u03B9\\u03C1\\u03C9\\u03C4\\u03B9\\u03BA\\u03AE)"
123 },
124
125 // display language (<root>)
126 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" },
127 // display script (<root>)
128 { "", "", "", "", "", "", "", ""},
129 // display country (<root>)
130 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" },
131 // display variant (<root>)
132 { "", "", "", "", "Nynorsk", "", "", ""},
133 // display name (<root>)
134 //{ "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" },
135 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" }
136 };
137
138
139 /*
140 Usage:
141 test_assert( Test (should be TRUE) )
142
143 Example:
144 test_assert(i==3);
145
146 the macro is ugly but makes the tests pretty.
147 */
148
149 #define test_assert(test) \
150 { \
151 if(!(test)) \
152 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \
153 else \
154 logln("PASS: asserted " #test); \
155 }
156
157 /*
158 Usage:
159 test_assert_print( Test (should be TRUE), printable )
160
161 Example:
162 test_assert(i==3, toString(i));
163
164 the macro is ugly but makes the tests pretty.
165 */
166
167 #define test_assert_print(test,print) \
168 { \
169 if(!(test)) \
170 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \
171 else \
172 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \
173 }
174
175
176 #define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); }
177
178 LocaleTest::LocaleTest()
179 : dataTable(NULL)
180 {
181 setUpDataTable();
182 }
183
184 LocaleTest::~LocaleTest()
185 {
186 if (dataTable != 0) {
187 for (int32_t i = 0; i < 33; i++) {
188 delete []dataTable[i];
189 }
190 delete []dataTable;
191 dataTable = 0;
192 }
193 }
194
195 void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
196 {
197 TESTCASE_AUTO_BEGIN;
198 TESTCASE_AUTO(TestBug11421); // Must run early in list to trigger failure.
199 TESTCASE_AUTO(TestBasicGetters);
200 TESTCASE_AUTO(TestSimpleResourceInfo);
201 TESTCASE_AUTO(TestDisplayNames);
202 TESTCASE_AUTO(TestSimpleObjectStuff);
203 TESTCASE_AUTO(TestPOSIXParsing);
204 TESTCASE_AUTO(TestGetAvailableLocales);
205 TESTCASE_AUTO(TestDataDirectory);
206 TESTCASE_AUTO(TestISO3Fallback);
207 TESTCASE_AUTO(TestGetLangsAndCountries);
208 TESTCASE_AUTO(TestSimpleDisplayNames);
209 TESTCASE_AUTO(TestUninstalledISO3Names);
210 TESTCASE_AUTO(TestAtypicalLocales);
211 #if !UCONFIG_NO_FORMATTING
212 TESTCASE_AUTO(TestThaiCurrencyFormat);
213 TESTCASE_AUTO(TestEuroSupport);
214 #endif
215 TESTCASE_AUTO(TestToString);
216 #if !UCONFIG_NO_FORMATTING
217 TESTCASE_AUTO(Test4139940);
218 TESTCASE_AUTO(Test4143951);
219 #endif
220 TESTCASE_AUTO(Test4147315);
221 TESTCASE_AUTO(Test4147317);
222 TESTCASE_AUTO(Test4147552);
223 TESTCASE_AUTO(TestVariantParsing);
224 #if !UCONFIG_NO_FORMATTING
225 TESTCASE_AUTO(Test4105828);
226 #endif
227 TESTCASE_AUTO(TestSetIsBogus);
228 TESTCASE_AUTO(TestParallelAPIValues);
229 TESTCASE_AUTO(TestAddLikelySubtags);
230 TESTCASE_AUTO(TestMinimizeSubtags);
231 TESTCASE_AUTO(TestAddLikelyAndMinimizeSubtags);
232 TESTCASE_AUTO(TestKeywordVariants);
233 TESTCASE_AUTO(TestCreateUnicodeKeywords);
234 TESTCASE_AUTO(TestKeywordVariantParsing);
235 TESTCASE_AUTO(TestCreateKeywordSet);
236 TESTCASE_AUTO(TestCreateUnicodeKeywordSet);
237 TESTCASE_AUTO(TestGetKeywordValueStdString);
238 TESTCASE_AUTO(TestGetUnicodeKeywordValueStdString);
239 TESTCASE_AUTO(TestSetKeywordValue);
240 TESTCASE_AUTO(TestSetKeywordValueStringPiece);
241 TESTCASE_AUTO(TestSetUnicodeKeywordValueStringPiece);
242 TESTCASE_AUTO(TestGetBaseName);
243 #if !UCONFIG_NO_FILE_IO
244 TESTCASE_AUTO(TestGetLocale);
245 #endif
246 TESTCASE_AUTO(TestVariantWithOutCountry);
247 TESTCASE_AUTO(TestCanonicalization);
248 TESTCASE_AUTO(TestCurrencyByDate);
249 TESTCASE_AUTO(TestGetVariantWithKeywords);
250 TESTCASE_AUTO(TestIsRightToLeft);
251 TESTCASE_AUTO(TestBug13277);
252 TESTCASE_AUTO(TestBug13554);
253 TESTCASE_AUTO(TestBug20410);
254 TESTCASE_AUTO(TestForLanguageTag);
255 TESTCASE_AUTO(TestToLanguageTag);
256 TESTCASE_AUTO(TestMoveAssign);
257 TESTCASE_AUTO(TestMoveCtor);
258 TESTCASE_AUTO(TestBug20407iVariantPreferredValue);
259 TESTCASE_AUTO(TestBug13417VeryLongLanguageTag);
260 TESTCASE_AUTO(TestBug11053UnderlineTimeZone);
261 TESTCASE_AUTO(TestUnd);
262 TESTCASE_AUTO(TestUndScript);
263 TESTCASE_AUTO(TestUndRegion);
264 TESTCASE_AUTO(TestUndCAPI);
265 TESTCASE_AUTO_END;
266 }
267
268 void LocaleTest::TestBasicGetters() {
269 UnicodeString temp;
270
271 int32_t i;
272 for (i = 0; i <= MAX_LOCALES; i++) {
273 Locale testLocale("");
274 if (rawData[SCRIPT][i] && rawData[SCRIPT][i][0] != 0) {
275 testLocale = Locale(rawData[LANG][i], rawData[SCRIPT][i], rawData[CTRY][i], rawData[VAR][i]);
276 }
277 else {
278 testLocale = Locale(rawData[LANG][i], rawData[CTRY][i], rawData[VAR][i]);
279 }
280 logln("Testing " + (UnicodeString)testLocale.getName() + "...");
281
282 if ( (temp=testLocale.getLanguage()) != (dataTable[LANG][i]))
283 errln(" Language code mismatch: " + temp + " versus "
284 + dataTable[LANG][i]);
285 if ( (temp=testLocale.getScript()) != (dataTable[SCRIPT][i]))
286 errln(" Script code mismatch: " + temp + " versus "
287 + dataTable[SCRIPT][i]);
288 if ( (temp=testLocale.getCountry()) != (dataTable[CTRY][i]))
289 errln(" Country code mismatch: " + temp + " versus "
290 + dataTable[CTRY][i]);
291 if ( (temp=testLocale.getVariant()) != (dataTable[VAR][i]))
292 errln(" Variant code mismatch: " + temp + " versus "
293 + dataTable[VAR][i]);
294 if ( (temp=testLocale.getName()) != (dataTable[NAME][i]))
295 errln(" Locale name mismatch: " + temp + " versus "
296 + dataTable[NAME][i]);
297 }
298
299 logln("Same thing without variant codes...");
300 for (i = 0; i <= MAX_LOCALES; i++) {
301 Locale testLocale("");
302 if (rawData[SCRIPT][i] && rawData[SCRIPT][i][0] != 0) {
303 testLocale = Locale(rawData[LANG][i], rawData[SCRIPT][i], rawData[CTRY][i]);
304 }
305 else {
306 testLocale = Locale(rawData[LANG][i], rawData[CTRY][i]);
307 }
308 logln("Testing " + (temp=testLocale.getName()) + "...");
309
310 if ( (temp=testLocale.getLanguage()) != (dataTable[LANG][i]))
311 errln("Language code mismatch: " + temp + " versus "
312 + dataTable[LANG][i]);
313 if ( (temp=testLocale.getScript()) != (dataTable[SCRIPT][i]))
314 errln("Script code mismatch: " + temp + " versus "
315 + dataTable[SCRIPT][i]);
316 if ( (temp=testLocale.getCountry()) != (dataTable[CTRY][i]))
317 errln("Country code mismatch: " + temp + " versus "
318 + dataTable[CTRY][i]);
319 if (testLocale.getVariant()[0] != 0)
320 errln("Variant code mismatch: something versus \"\"");
321 }
322
323 logln("Testing long language names and getters");
324 Locale test8 = Locale::createFromName("x-klingon-latn-zx.utf32be@special");
325
326 temp = test8.getLanguage();
327 if (temp != UnicodeString("x-klingon") )
328 errln("Language code mismatch: " + temp + " versus \"x-klingon\"");
329
330 temp = test8.getScript();
331 if (temp != UnicodeString("Latn") )
332 errln("Script code mismatch: " + temp + " versus \"Latn\"");
333
334 temp = test8.getCountry();
335 if (temp != UnicodeString("ZX") )
336 errln("Country code mismatch: " + temp + " versus \"ZX\"");
337
338 temp = test8.getVariant();
339 //if (temp != UnicodeString("SPECIAL") )
340 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\"");
341 // As of 3.0, the "@special" will *not* be parsed by uloc_getName()
342 if (temp != UnicodeString("") )
343 errln("Variant code mismatch: " + temp + " versus \"\"");
344
345 if (Locale::getDefault() != Locale::createFromName(NULL))
346 errln("Locale::getDefault() == Locale::createFromName(NULL)");
347
348 /*----------*/
349 // NOTE: There used to be a special test for locale names that had language or
350 // country codes that were longer than two letters. The new version of Locale
351 // doesn't support anything that isn't an officially recognized language or
352 // country code, so we no longer support this feature.
353
354 Locale bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code too long
355 if(!bogusLang.isBogus()) {
356 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE");
357 }
358
359 bogusLang=Locale("eo");
360 if( bogusLang.isBogus() ||
361 strcmp(bogusLang.getLanguage(), "eo")!=0 ||
362 *bogusLang.getCountry()!=0 ||
363 *bogusLang.getVariant()!=0 ||
364 strcmp(bogusLang.getName(), "eo")!=0
365 ) {
366 errln("assignment to bogus Locale does not unbogus it or sets bad data");
367 }
368
369 Locale a("eo_DE@currency=DEM");
370 Locale *pb=a.clone();
371 if(pb==&a || *pb!=a) {
372 errln("Locale.clone() failed");
373 }
374 delete pb;
375 }
376
377 void LocaleTest::TestParallelAPIValues() {
378 logln("Test synchronization between C and C++ API");
379 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE) != 0) {
380 errln("Differences for ULOC_CHINESE Locale");
381 }
382 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH) != 0) {
383 errln("Differences for ULOC_ENGLISH Locale");
384 }
385 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH) != 0) {
386 errln("Differences for ULOC_FRENCH Locale");
387 }
388 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN) != 0) {
389 errln("Differences for ULOC_GERMAN Locale");
390 }
391 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN) != 0) {
392 errln("Differences for ULOC_ITALIAN Locale");
393 }
394 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE) != 0) {
395 errln("Differences for ULOC_JAPANESE Locale");
396 }
397 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN) != 0) {
398 errln("Differences for ULOC_KOREAN Locale");
399 }
400 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE) != 0) {
401 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale");
402 }
403 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINESE) != 0) {
404 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale");
405 }
406
407
408 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA) != 0) {
409 errln("Differences for ULOC_CANADA Locale");
410 }
411 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH) != 0) {
412 errln("Differences for ULOC_CANADA_FRENCH Locale");
413 }
414 if (strcmp(Locale::getChina().getName(), ULOC_CHINA) != 0) {
415 errln("Differences for ULOC_CHINA Locale");
416 }
417 if (strcmp(Locale::getPRC().getName(), ULOC_PRC) != 0) {
418 errln("Differences for ULOC_PRC Locale");
419 }
420 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE) != 0) {
421 errln("Differences for ULOC_FRANCE Locale");
422 }
423 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY) != 0) {
424 errln("Differences for ULOC_GERMANY Locale");
425 }
426 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY) != 0) {
427 errln("Differences for ULOC_ITALY Locale");
428 }
429 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN) != 0) {
430 errln("Differences for ULOC_JAPAN Locale");
431 }
432 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA) != 0) {
433 errln("Differences for ULOC_KOREA Locale");
434 }
435 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN) != 0) {
436 errln("Differences for ULOC_TAIWAN Locale");
437 }
438 if (strcmp(Locale::getUK().getName(), ULOC_UK) != 0) {
439 errln("Differences for ULOC_UK Locale");
440 }
441 if (strcmp(Locale::getUS().getName(), ULOC_US) != 0) {
442 errln("Differences for ULOC_US Locale");
443 }
444 }
445
446
447 void LocaleTest::TestSimpleResourceInfo() {
448 UnicodeString temp;
449 char temp2[20];
450 UErrorCode err = U_ZERO_ERROR;
451 int32_t i = 0;
452
453 for (i = 0; i <= MAX_LOCALES; i++) {
454 Locale testLocale(rawData[LANG][i], rawData[CTRY][i], rawData[VAR][i]);
455 logln("Testing " + (temp=testLocale.getName()) + "...");
456
457 if ( (temp=testLocale.getISO3Language()) != (dataTable[LANG3][i]))
458 errln(" ISO-3 language code mismatch: " + temp
459 + " versus " + dataTable[LANG3][i]);
460 if ( (temp=testLocale.getISO3Country()) != (dataTable[CTRY3][i]))
461 errln(" ISO-3 country code mismatch: " + temp
462 + " versus " + dataTable[CTRY3][i]);
463
464 sprintf(temp2, "%x", (int)testLocale.getLCID());
465 if (UnicodeString(temp2) != dataTable[LCID][i])
466 errln((UnicodeString)" LCID mismatch: " + temp2 + " versus "
467 + dataTable[LCID][i]);
468
469 if(U_FAILURE(err))
470 {
471 errln((UnicodeString)"Some error on number " + i + u_errorName(err));
472 }
473 err = U_ZERO_ERROR;
474 }
475
476 Locale locale("en");
477 if(strcmp(locale.getName(), "en") != 0||
478 strcmp(locale.getLanguage(), "en") != 0) {
479 errln("construction of Locale(en) failed\n");
480 }
481 /*-----*/
482
483 }
484
485 /*
486 * Jitterbug 2439 -- markus 20030425
487 *
488 * The lookup of display names must not fall back through the default
489 * locale because that yields useless results.
490 */
491 void
492 LocaleTest::TestDisplayNames()
493 {
494 Locale english("en", "US");
495 Locale french("fr", "FR");
496 Locale croatian("ca", "ES");
497 Locale greek("el", "GR");
498
499 logln(" In locale = en_US...");
500 doTestDisplayNames(english, DLANG_EN);
501 logln(" In locale = fr_FR...");
502 doTestDisplayNames(french, DLANG_FR);
503 logln(" In locale = ca_ES...");
504 doTestDisplayNames(croatian, DLANG_CA);
505 logln(" In locale = el_GR...");
506 doTestDisplayNames(greek, DLANG_EL);
507
508 UnicodeString s;
509 UErrorCode status = U_ZERO_ERROR;
510
511 #if !UCONFIG_NO_FORMATTING
512 DecimalFormatSymbols symb(status);
513 /* Check to see if ICU supports this locale */
514 if (symb.getLocale(ULOC_VALID_LOCALE, status) != Locale("root")) {
515 /* test that the default locale has a display name for its own language */
516 /* Currently, there is no language information in the "tl" data file so this test will fail if default locale is "tl" */
517 if (uprv_strcmp(Locale().getLanguage(), "tl") != 0) {
518 Locale().getDisplayLanguage(Locale(), s);
519 if(s.length()<=3 && s.charAt(0)<=0x7f) {
520 /* check <=3 to reject getting the language code as a display name */
521 dataerrln("unable to get a display string for the language of the default locale: " + s);
522 }
523
524 /*
525 * API coverage improvements: call
526 * Locale::getDisplayLanguage(UnicodeString &) and
527 * Locale::getDisplayCountry(UnicodeString &)
528 */
529 s.remove();
530 Locale().getDisplayLanguage(s);
531 if(s.length()<=3 && s.charAt(0)<=0x7f) {
532 dataerrln("unable to get a display string for the language of the default locale [2]: " + s);
533 }
534 }
535 }
536 else {
537 logln("Default locale %s is unsupported by ICU\n", Locale().getName());
538 }
539 s.remove();
540 #endif
541
542 french.getDisplayCountry(s);
543 if(s.isEmpty()) {
544 errln("unable to get any default-locale display string for the country of fr_FR\n");
545 }
546 s.remove();
547 Locale("zh", "Hant").getDisplayScript(s);
548 if(s.isEmpty()) {
549 errln("unable to get any default-locale display string for the country of zh_Hant\n");
550 }
551 }
552
553 void LocaleTest::TestSimpleObjectStuff() {
554 Locale test1("aa", "AA");
555 Locale test2("aa", "AA");
556 Locale test3(test1);
557 Locale test4("zz", "ZZ");
558 Locale test5("aa", "AA", "");
559 Locale test6("aa", "AA", "ANTARES");
560 Locale test7("aa", "AA", "JUPITER");
561 Locale test8 = Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that
562
563 // now list them all for debugging usage.
564 test_dumpLocale(test1);
565 test_dumpLocale(test2);
566 test_dumpLocale(test3);
567 test_dumpLocale(test4);
568 test_dumpLocale(test5);
569 test_dumpLocale(test6);
570 test_dumpLocale(test7);
571 test_dumpLocale(test8);
572
573 // Make sure things compare to themselves!
574 test_assert(test1 == test1);
575 test_assert(test2 == test2);
576 test_assert(test3 == test3);
577 test_assert(test4 == test4);
578 test_assert(test5 == test5);
579 test_assert(test6 == test6);
580 test_assert(test7 == test7);
581 test_assert(test8 == test8);
582
583 // make sure things are not equal to themselves.
584 test_assert(!(test1 != test1));
585 test_assert(!(test2 != test2));
586 test_assert(!(test3 != test3));
587 test_assert(!(test4 != test4));
588 test_assert(!(test5 != test5));
589 test_assert(!(test6 != test6));
590 test_assert(!(test7 != test7));
591 test_assert(!(test8 != test8));
592
593 // make sure things that are equal to each other don't show up as unequal.
594 test_assert(!(test1 != test2));
595 test_assert(!(test2 != test1));
596 test_assert(!(test1 != test3));
597 test_assert(!(test2 != test3));
598 test_assert(test5 == test1);
599 test_assert(test6 != test2);
600 test_assert(test6 != test5);
601
602 test_assert(test6 != test7);
603
604 // test for things that shouldn't compare equal.
605 test_assert(!(test1 == test4));
606 test_assert(!(test2 == test4));
607 test_assert(!(test3 == test4));
608
609 test_assert(test7 == test8);
610
611 // test for hash codes to be the same.
612 int32_t hash1 = test1.hashCode();
613 int32_t hash2 = test2.hashCode();
614 int32_t hash3 = test3.hashCode();
615
616 test_assert(hash1 == hash2);
617 test_assert(hash1 == hash3);
618 test_assert(hash2 == hash3);
619
620 // test that the assignment operator works.
621 test4 = test1;
622 logln("test4=test1;");
623 test_dumpLocale(test4);
624 test_assert(test4 == test4);
625
626 test_assert(!(test1 != test4));
627 test_assert(!(test2 != test4));
628 test_assert(!(test3 != test4));
629 test_assert(test1 == test4);
630 test_assert(test4 == test1);
631
632 // test assignments with a variant
633 logln("test7 = test6");
634 test7 = test6;
635 test_dumpLocale(test7);
636 test_assert(test7 == test7);
637 test_assert(test7 == test6);
638 test_assert(test7 != test5);
639
640 logln("test6 = test1");
641 test6=test1;
642 test_dumpLocale(test6);
643 test_assert(test6 != test7);
644 test_assert(test6 == test1);
645 test_assert(test6 == test6);
646 }
647
648 // A class which exposes constructors that are implemented in terms of the POSIX parsing code.
649 class POSIXLocale : public Locale
650 {
651 public:
652 POSIXLocale(const UnicodeString& l)
653 :Locale()
654 {
655 char *ch;
656 ch = new char[l.length() + 1];
657 ch[l.extract(0, 0x7fffffff, ch, "")] = 0;
658 setFromPOSIXID(ch);
659 delete [] ch;
660 }
661 POSIXLocale(const char *l)
662 :Locale()
663 {
664 setFromPOSIXID(l);
665 }
666 };
667
668 void LocaleTest::TestPOSIXParsing()
669 {
670 POSIXLocale test1("ab_AB");
671 POSIXLocale test2(UnicodeString("ab_AB"));
672 Locale test3("ab","AB");
673
674 POSIXLocale test4("ab_AB_Antares");
675 POSIXLocale test5(UnicodeString("ab_AB_Antares"));
676 Locale test6("ab", "AB", "Antares");
677
678 test_dumpLocale(test1);
679 test_dumpLocale(test2);
680 test_dumpLocale(test3);
681 test_dumpLocale(test4);
682 test_dumpLocale(test5);
683 test_dumpLocale(test6);
684
685 test_assert(test1 == test1);
686
687 test_assert(test1 == test2);
688 test_assert(test2 == test3);
689 test_assert(test3 == test1);
690
691 test_assert(test4 == test5);
692 test_assert(test5 == test6);
693 test_assert(test6 == test4);
694
695 test_assert(test1 != test4);
696 test_assert(test5 != test3);
697 test_assert(test5 != test2);
698
699 int32_t hash1 = test1.hashCode();
700 int32_t hash2 = test2.hashCode();
701 int32_t hash3 = test3.hashCode();
702
703 test_assert(hash1 == hash2);
704 test_assert(hash2 == hash3);
705 test_assert(hash3 == hash1);
706 }
707
708 void LocaleTest::TestGetAvailableLocales()
709 {
710 int32_t locCount = 0;
711 const Locale* locList = Locale::getAvailableLocales(locCount);
712
713 if (locCount == 0)
714 dataerrln("getAvailableLocales() returned an empty list!");
715 else {
716 logln(UnicodeString("Number of locales returned = ") + locCount);
717 UnicodeString temp;
718 for(int32_t i = 0; i < locCount; ++i)
719 logln(locList[i].getName());
720 }
721 // I have no idea how to test this function...
722 }
723
724 // This test isn't applicable anymore - getISO3Language is
725 // independent of the data directory
726 void LocaleTest::TestDataDirectory()
727 {
728 /*
729 char oldDirectory[80];
730 const char* temp;
731 UErrorCode err = U_ZERO_ERROR;
732 UnicodeString testValue;
733
734 temp = Locale::getDataDirectory();
735 strcpy(oldDirectory, temp);
736 logln(UnicodeString("oldDirectory = ") + oldDirectory);
737
738 Locale test(Locale::US);
739 test.getISO3Language(testValue);
740 logln("first fetch of language retrieved " + testValue);
741 if (testValue != "eng")
742 errln("Initial check of ISO3 language failed: expected \"eng\", got \"" + testValue + "\"");
743
744 {
745 char *path;
746 path=IntlTest::getTestDirectory();
747 Locale::setDataDirectory( path );
748 }
749
750 test.getISO3Language(testValue);
751 logln("second fetch of language retrieved " + testValue);
752 if (testValue != "xxx")
753 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue + "\"");
754
755 Locale::setDataDirectory(oldDirectory);
756 test.getISO3Language(testValue);
757 logln("third fetch of language retrieved " + testValue);
758 if (testValue != "eng")
759 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testValue + "\"");
760 */
761 }
762
763 //===========================================================
764
765 void LocaleTest::doTestDisplayNames(Locale& displayLocale, int32_t compareIndex) {
766 UnicodeString temp;
767
768 for (int32_t i = 0; i <= MAX_LOCALES; i++) {
769 Locale testLocale("");
770 if (rawData[SCRIPT][i] && rawData[SCRIPT][i][0] != 0) {
771 testLocale = Locale(rawData[LANG][i], rawData[SCRIPT][i], rawData[CTRY][i], rawData[VAR][i]);
772 }
773 else {
774 testLocale = Locale(rawData[LANG][i], rawData[CTRY][i], rawData[VAR][i]);
775 }
776 logln(" Testing " + (temp=testLocale.getName()) + "...");
777
778 UnicodeString testLang;
779 UnicodeString testScript;
780 UnicodeString testCtry;
781 UnicodeString testVar;
782 UnicodeString testName;
783
784 testLocale.getDisplayLanguage(displayLocale, testLang);
785 testLocale.getDisplayScript(displayLocale, testScript);
786 testLocale.getDisplayCountry(displayLocale, testCtry);
787 testLocale.getDisplayVariant(displayLocale, testVar);
788 testLocale.getDisplayName(displayLocale, testName);
789
790 UnicodeString expectedLang;
791 UnicodeString expectedScript;
792 UnicodeString expectedCtry;
793 UnicodeString expectedVar;
794 UnicodeString expectedName;
795
796 expectedLang = dataTable[compareIndex][i];
797 if (expectedLang.length() == 0)
798 expectedLang = dataTable[DLANG_EN][i];
799
800 expectedScript = dataTable[compareIndex + 1][i];
801 if (expectedScript.length() == 0)
802 expectedScript = dataTable[DSCRIPT_EN][i];
803
804 expectedCtry = dataTable[compareIndex + 2][i];
805 if (expectedCtry.length() == 0)
806 expectedCtry = dataTable[DCTRY_EN][i];
807
808 expectedVar = dataTable[compareIndex + 3][i];
809 if (expectedVar.length() == 0)
810 expectedVar = dataTable[DVAR_EN][i];
811
812 expectedName = dataTable[compareIndex + 4][i];
813 if (expectedName.length() == 0)
814 expectedName = dataTable[DNAME_EN][i];
815
816 if (testLang != expectedLang)
817 dataerrln("Display language (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testLang + " expected " + expectedLang);
818 if (testScript != expectedScript)
819 dataerrln("Display script (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testScript + " expected " + expectedScript);
820 if (testCtry != expectedCtry)
821 dataerrln("Display country (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testCtry + " expected " + expectedCtry);
822 if (testVar != expectedVar)
823 dataerrln("Display variant (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testVar + " expected " + expectedVar);
824 if (testName != expectedName)
825 dataerrln("Display name (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testName + " expected " + expectedName);
826 }
827 }
828
829 //---------------------------------------------------
830 // table of valid data
831 //---------------------------------------------------
832
833
834
835 void LocaleTest::setUpDataTable()
836 {
837 if (dataTable == 0) {
838 dataTable = new UnicodeString*[33];
839
840 for (int32_t i = 0; i < 33; i++) {
841 dataTable[i] = new UnicodeString[8];
842 for (int32_t j = 0; j < 8; j++) {
843 dataTable[i][j] = CharsToUnicodeString(rawData[i][j]);
844 }
845 }
846 }
847 }
848
849 // ====================
850
851
852 /**
853 * @bug 4011756 4011380
854 */
855 void
856 LocaleTest::TestISO3Fallback()
857 {
858 Locale test("xx", "YY");
859
860 const char * result;
861
862 result = test.getISO3Language();
863
864 // Conform to C API usage
865
866 if (!result || (result[0] != 0))
867 errln("getISO3Language() on xx_YY returned " + UnicodeString(result) + " instead of \"\"");
868
869 result = test.getISO3Country();
870
871 if (!result || (result[0] != 0))
872 errln("getISO3Country() on xx_YY returned " + UnicodeString(result) + " instead of \"\"");
873 }
874
875 /**
876 * @bug 4106155 4118587
877 */
878 void
879 LocaleTest::TestGetLangsAndCountries()
880 {
881 // It didn't seem right to just do an exhaustive test of everything here, so I check
882 // for the following things:
883 // 1) Does each list have the right total number of entries?
884 // 2) Does each list contain certain language and country codes we think are important
885 // (the G7 countries, plus a couple others)?
886 // 3) Does each list have every entry formatted correctly? (i.e., two characters,
887 // all lower case for the language codes, all upper case for the country codes)
888 // 4) Is each list in sorted order?
889 int32_t testCount = 0;
890 const char * const * test = Locale::getISOLanguages();
891 const char spotCheck1[ ][4] = { "en", "es", "fr", "de", "it",
892 "ja", "ko", "zh", "th", "he",
893 "id", "iu", "ug", "yi", "za" };
894
895 int32_t i;
896
897 for(testCount = 0;test[testCount];testCount++)
898 ;
899
900 /* TODO: Change this test to be more like the cloctst version? */
901 if (testCount != 595)
902 errln("Expected getISOLanguages() to return 595 languages; it returned %d", testCount);
903 else {
904 for (i = 0; i < 15; i++) {
905 int32_t j;
906 for (j = 0; j < testCount; j++)
907 if (uprv_strcmp(test[j],spotCheck1[i])== 0)
908 break;
909 if (j == testCount || (uprv_strcmp(test[j],spotCheck1[i])!=0))
910 errln("Couldn't find " + (UnicodeString)spotCheck1[i] + " in language list.");
911 }
912 }
913 for (i = 0; i < testCount; i++) {
914 UnicodeString testee(test[i],"");
915 UnicodeString lc(test[i],"");
916 if (testee != lc.toLower())
917 errln(lc + " is not all lower case.");
918 if ( (testee.length() != 2) && (testee.length() != 3))
919 errln(testee + " is not two or three characters long.");
920 if (i > 0 && testee.compare(test[i - 1]) <= 0)
921 errln(testee + " appears in an out-of-order position in the list.");
922 }
923
924 test = Locale::getISOCountries();
925 UnicodeString spotCheck2 [] = { "US", "CA", "GB", "FR", "DE",
926 "IT", "JP", "KR", "CN", "TW",
927 "TH" };
928 int32_t spot2Len = 11;
929 for(testCount=0;test[testCount];testCount++)
930 ;
931
932 if (testCount != 256){
933 errln("Expected getISOCountries to return 256 countries; it returned %d", testCount);
934 }else {
935 for (i = 0; i < spot2Len; i++) {
936 int32_t j;
937 for (j = 0; j < testCount; j++)
938 {
939 UnicodeString testee(test[j],"");
940
941 if (testee == spotCheck2[i])
942 break;
943 }
944 UnicodeString testee(test[j],"");
945 if (j == testCount || testee != spotCheck2[i])
946 errln("Couldn't find " + spotCheck2[i] + " in country list.");
947 }
948 }
949 for (i = 0; i < testCount; i++) {
950 UnicodeString testee(test[i],"");
951 UnicodeString uc(test[i],"");
952 if (testee != uc.toUpper())
953 errln(testee + " is not all upper case.");
954 if (testee.length() != 2)
955 errln(testee + " is not two characters long.");
956 if (i > 0 && testee.compare(test[i - 1]) <= 0)
957 errln(testee + " appears in an out-of-order position in the list.");
958 }
959
960 // This getAvailableLocales and getISO3Language
961 {
962 int32_t numOfLocales;
963 Locale enLoc ("en");
964 const Locale *pLocales = Locale::getAvailableLocales(numOfLocales);
965
966 for (int i = 0; i < numOfLocales; i++) {
967 const Locale &loc(pLocales[i]);
968 UnicodeString name;
969 char szName[200];
970
971 loc.getDisplayName (enLoc, name);
972 name.extract (0, 200, szName, sizeof(szName));
973
974 if (strlen(loc.getISO3Language()) == 0) {
975 errln("getISO3Language() returned an empty string for: " + name);
976 }
977 }
978 }
979 }
980
981 /**
982 * @bug 4118587
983 */
984 void
985 LocaleTest::TestSimpleDisplayNames()
986 {
987 // This test is different from TestDisplayNames because TestDisplayNames checks
988 // fallback behavior, combination of language and country names to form locale
989 // names, and other stuff like that. This test just checks specific language
990 // and country codes to make sure we have the correct names for them.
991 char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za" };
992 UnicodeString languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uyghur", "Yiddish",
993 "Zhuang" };
994
995 for (int32_t i = 0; i < 6; i++) {
996 UnicodeString test;
997 Locale l(languageCodes[i], "", "");
998 l.getDisplayLanguage(Locale::getUS(), test);
999 if (test != languageNames[i])
1000 dataerrln("Got wrong display name for " + UnicodeString(languageCodes[i]) + ": Expected \"" +
1001 languageNames[i] + "\", got \"" + test + "\".");
1002 }
1003 }
1004
1005 /**
1006 * @bug 4118595
1007 */
1008 void
1009 LocaleTest::TestUninstalledISO3Names()
1010 {
1011 // This test checks to make sure getISO3Language and getISO3Country work right
1012 // even for locales that are not installed.
1013 const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn",
1014 "ss", "tw", "zu" };
1015 const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run",
1016 "ssw", "twi", "zul" };
1017
1018 int32_t i;
1019
1020 for (i = 0; i < 8; i++) {
1021 UErrorCode err = U_ZERO_ERROR;
1022
1023 UnicodeString test;
1024 Locale l(iso2Languages[i], "", "");
1025 test = l.getISO3Language();
1026 if((test != iso3Languages[i]) || U_FAILURE(err))
1027 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages[i]) + ": Expected \"" +
1028 iso3Languages[i] + "\", got \"" + test + "\"." + UnicodeString(u_errorName(err)));
1029 }
1030
1031 char iso2Countries [][4] = { "AF", "BW", "KZ", "MO", "MN",
1032 "SB", "TC", "ZW" };
1033 char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG",
1034 "SLB", "TCA", "ZWE" };
1035
1036 for (i = 0; i < 8; i++) {
1037 UErrorCode err = U_ZERO_ERROR;
1038 Locale l("", iso2Countries[i], "");
1039 UnicodeString test(l.getISO3Country(), "");
1040 if (test != iso3Countries[i])
1041 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries[i]) + ": Expected \"" +
1042 UnicodeString(iso3Countries[i]) + "\", got \"" + test + "\"." + u_errorName(err));
1043 }
1044 }
1045
1046 /**
1047 * @bug 4092475
1048 * I could not reproduce this bug. I'm pretty convinced it was fixed with the
1049 * big locale-data reorg of 10/28/97. The lookup logic for language and country
1050 * display names was also changed at that time in that check-in. --rtg 3/20/98
1051 */
1052 void
1053 LocaleTest::TestAtypicalLocales()
1054 {
1055 Locale localesToTest [] = { Locale("de", "CA"),
1056 Locale("ja", "ZA"),
1057 Locale("ru", "MX"),
1058 Locale("en", "FR"),
1059 Locale("es", "DE"),
1060 Locale("", "HR"),
1061 Locale("", "SE"),
1062 Locale("", "DO"),
1063 Locale("", "BE") };
1064
1065 UnicodeString englishDisplayNames [] = { "German (Canada)",
1066 "Japanese (South Africa)",
1067 "Russian (Mexico)",
1068 "English (France)",
1069 "Spanish (Germany)",
1070 "Croatia",
1071 "Sweden",
1072 "Dominican Republic",
1073 "Belgium" };
1074 UnicodeString frenchDisplayNames []= { "allemand (Canada)",
1075 "japonais (Afrique du Sud)",
1076 "russe (Mexique)",
1077 "anglais (France)",
1078 "espagnol (Allemagne)",
1079 u"Croatie",
1080 u"Suède",
1081 u"République dominicaine",
1082 u"Belgique" };
1083 UnicodeString spanishDisplayNames [] = {
1084 u"alemán (Canadá)",
1085 u"japonés (Sudáfrica)",
1086 u"ruso (México)",
1087 u"inglés (Francia)",
1088 u"español (Alemania)",
1089 "Croacia",
1090 "Suecia",
1091 u"República Dominicana",
1092 u"Bélgica" };
1093 // De-Anglicizing root required the change from
1094 // English display names to ISO Codes - ram 2003/09/26
1095 UnicodeString invDisplayNames [] = { "German (Canada)",
1096 "Japanese (South Africa)",
1097 "Russian (Mexico)",
1098 "English (France)",
1099 "Spanish (Germany)",
1100 "Croatia",
1101 "Sweden",
1102 "Dominican Republic",
1103 "Belgium" };
1104
1105 int32_t i;
1106 UErrorCode status = U_ZERO_ERROR;
1107 Locale saveLocale;
1108 Locale::setDefault(Locale::getUS(), status);
1109 for (i = 0; i < 9; ++i) {
1110 UnicodeString name;
1111 localesToTest[i].getDisplayName(Locale::getUS(), name);
1112 logln(name);
1113 if (name != englishDisplayNames[i])
1114 {
1115 dataerrln("Lookup in English failed: expected \"" + englishDisplayNames[i]
1116 + "\", got \"" + name + "\"");
1117 logln("Locale name was-> " + (name=localesToTest[i].getName()));
1118 }
1119 }
1120
1121 for (i = 0; i < 9; i++) {
1122 UnicodeString name;
1123 localesToTest[i].getDisplayName(Locale("es", "ES"), name);
1124 logln(name);
1125 if (name != spanishDisplayNames[i])
1126 dataerrln("Lookup in Spanish failed: expected \"" + spanishDisplayNames[i]
1127 + "\", got \"" + name + "\"");
1128 }
1129
1130 for (i = 0; i < 9; i++) {
1131 UnicodeString name;
1132 localesToTest[i].getDisplayName(Locale::getFrance(), name);
1133 logln(name);
1134 if (name != frenchDisplayNames[i])
1135 dataerrln("Lookup in French failed: expected \"" + frenchDisplayNames[i]
1136 + "\", got \"" + name + "\"");
1137 }
1138
1139 for (i = 0; i < 9; i++) {
1140 UnicodeString name;
1141 localesToTest[i].getDisplayName(Locale("inv", "IN"), name);
1142 logln(name + " Locale fallback to be, and data fallback to root");
1143 if (name != invDisplayNames[i])
1144 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames[i])
1145 + "\", got \"" + prettify(name) + "\"");
1146 localesToTest[i].getDisplayName(Locale("inv", "BD"), name);
1147 logln(name + " Data fallback to root");
1148 if (name != invDisplayNames[i])
1149 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames[i])
1150 + "\", got \"" + prettify(name )+ "\"");
1151 }
1152 Locale::setDefault(saveLocale, status);
1153 }
1154
1155 #if !UCONFIG_NO_FORMATTING
1156
1157 /**
1158 * @bug 4135752
1159 * This would be better tested by the LocaleDataTest. Will move it when I
1160 * get the LocaleDataTest working again.
1161 */
1162 void
1163 LocaleTest::TestThaiCurrencyFormat()
1164 {
1165 UErrorCode status = U_ZERO_ERROR;
1166 DecimalFormat *thaiCurrency = (DecimalFormat*)NumberFormat::createCurrencyInstance(
1167 Locale("th", "TH"), status);
1168 UnicodeString posPrefix(u"\u0E3F");
1169 UnicodeString temp;
1170
1171 if(U_FAILURE(status) || !thaiCurrency)
1172 {
1173 dataerrln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(status)));
1174 return;
1175 }
1176 if (thaiCurrency->getPositivePrefix(temp) != posPrefix)
1177 errln("Thai currency prefix wrong: expected Baht sign, got \"" +
1178 thaiCurrency->getPositivePrefix(temp) + "\"");
1179 if (thaiCurrency->getPositiveSuffix(temp) != "")
1180 errln("Thai currency suffix wrong: expected \"\", got \"" +
1181 thaiCurrency->getPositiveSuffix(temp) + "\"");
1182
1183 delete thaiCurrency;
1184 }
1185
1186 /**
1187 * @bug 4122371
1188 * Confirm that Euro support works. This test is pretty rudimentary; all it does
1189 * is check that any locales with the EURO variant format a number using the
1190 * Euro currency symbol.
1191 *
1192 * ASSUME: All locales encode the Euro character "\u20AC".
1193 * If this is changed to use the single-character Euro symbol, this
1194 * test must be updated.
1195 *
1196 */
1197 void
1198 LocaleTest::TestEuroSupport()
1199 {
1200 UChar euro = 0x20ac;
1201 const UnicodeString EURO_CURRENCY(&euro, 1, 1); // Look for this UnicodeString in formatted Euro currency
1202 const char* localeArr[] = {
1203 "ca_ES",
1204 "de_AT",
1205 "de_DE",
1206 "de_LU",
1207 "el_GR",
1208 "en_BE",
1209 "en_IE",
1210 "en_GB@currency=EUR",
1211 "en_US@currency=EUR",
1212 "es_ES",
1213 "eu_ES",
1214 "fi_FI",
1215 "fr_BE",
1216 "fr_FR",
1217 "fr_LU",
1218 "ga_IE",
1219 "gl_ES",
1220 "it_IT",
1221 "nl_BE",
1222 "nl_NL",
1223 "pt_PT",
1224 NULL
1225 };
1226 const char** locales = localeArr;
1227
1228 UErrorCode status = U_ZERO_ERROR;
1229
1230 UnicodeString temp;
1231
1232 for (;*locales!=NULL;locales++) {
1233 Locale loc (*locales);
1234 UnicodeString temp;
1235 NumberFormat *nf = NumberFormat::createCurrencyInstance(loc, status);
1236 UnicodeString pos;
1237
1238 if (U_FAILURE(status)) {
1239 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales);
1240 continue;
1241 }
1242
1243 nf->format(271828.182845, pos);
1244 UnicodeString neg;
1245 nf->format(-271828.182845, neg);
1246 if (pos.indexOf(EURO_CURRENCY) >= 0 &&
1247 neg.indexOf(EURO_CURRENCY) >= 0) {
1248 logln("Ok: " + (temp=loc.getName()) +
1249 ": " + pos + " / " + neg);
1250 }
1251 else {
1252 errln("Fail: " + (temp=loc.getName()) +
1253 " formats without " + EURO_CURRENCY +
1254 ": " + pos + " / " + neg +
1255 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***");
1256 }
1257
1258 delete nf;
1259 }
1260
1261 UnicodeString dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar)0x00a4), resultStr;
1262 UChar tmp[4];
1263 status = U_ZERO_ERROR;
1264
1265 ucurr_forLocale("en_US", tmp, 4, &status);
1266 resultStr.setTo(tmp);
1267 if (dollarStr != resultStr) {
1268 errcheckln(status, "Fail: en_US didn't return USD - %s", u_errorName(status));
1269 }
1270 ucurr_forLocale("en_US@currency=EUR", tmp, 4, &status);
1271 resultStr.setTo(tmp);
1272 if (euroStr != resultStr) {
1273 errcheckln(status, "Fail: en_US@currency=EUR didn't return EUR - %s", u_errorName(status));
1274 }
1275 ucurr_forLocale("en_GB@currency=EUR", tmp, 4, &status);
1276 resultStr.setTo(tmp);
1277 if (euroStr != resultStr) {
1278 errcheckln(status, "Fail: en_GB@currency=EUR didn't return EUR - %s", u_errorName(status));
1279 }
1280 ucurr_forLocale("en_US_Q", tmp, 4, &status);
1281 resultStr.setTo(tmp);
1282 if (dollarStr != resultStr) {
1283 errcheckln(status, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status));
1284 }
1285 int32_t invalidLen = ucurr_forLocale("en_QQ", tmp, 4, &status);
1286 if (invalidLen || U_SUCCESS(status)) {
1287 errln("Fail: en_QQ didn't return NULL");
1288 }
1289
1290 // The currency keyword value is as long as the destination buffer.
1291 // It should detect the overflow internally, and default to the locale's currency.
1292 tmp[0] = u'¤';
1293 status = U_ZERO_ERROR;
1294 int32_t length = ucurr_forLocale("en_US@currency=euro", tmp, 4, &status);
1295 if (U_FAILURE(status) || dollarStr != UnicodeString(tmp, length)) {
1296 if (U_SUCCESS(status) && tmp[0] == u'¤') {
1297 errln("Fail: ucurr_forLocale(en_US@currency=euro) succeeded without writing output");
1298 } else {
1299 errln("Fail: ucurr_forLocale(en_US@currency=euro) != USD - %s", u_errorName(status));
1300 }
1301 }
1302 }
1303
1304 #endif
1305
1306 /**
1307 * @bug 4139504
1308 * toString() doesn't work with language_VARIANT.
1309 */
1310 void
1311 LocaleTest::TestToString() {
1312 Locale DATA [] = {
1313 Locale("xx", "", ""),
1314 Locale("", "YY", ""),
1315 Locale("", "", "ZZ"),
1316 Locale("xx", "YY", ""),
1317 Locale("xx", "", "ZZ"),
1318 Locale("", "YY", "ZZ"),
1319 Locale("xx", "YY", "ZZ"),
1320 };
1321
1322 const char DATA_S [][20] = {
1323 "xx",
1324 "_YY",
1325 "__ZZ",
1326 "xx_YY",
1327 "xx__ZZ",
1328 "_YY_ZZ",
1329 "xx_YY_ZZ",
1330 };
1331
1332 for (int32_t i=0; i < 7; ++i) {
1333 const char *name;
1334 name = DATA[i].getName();
1335
1336 if (strcmp(name, DATA_S[i]) != 0)
1337 {
1338 errln("Fail: Locale.getName(), got:" + UnicodeString(name) + ", expected: " + DATA_S[i]);
1339 }
1340 else
1341 logln("Pass: Locale.getName(), got:" + UnicodeString(name) );
1342 }
1343 }
1344
1345 #if !UCONFIG_NO_FORMATTING
1346
1347 /**
1348 * @bug 4139940
1349 * Couldn't reproduce this bug -- probably was fixed earlier.
1350 *
1351 * ORIGINAL BUG REPORT:
1352 * -- basically, hungarian for monday shouldn't have an \u00f4
1353 * (o circumflex)in it instead it should be an o with 2 inclined
1354 * (right) lines over it..
1355 *
1356 * You may wonder -- why do all this -- why not just add a line to
1357 * LocaleData? Well, I could see by inspection that the locale file had the
1358 * right character in it, so I wanted to check the rest of the pipeline -- a
1359 * very remote possibility, but I wanted to be sure. The other possibility
1360 * is that something is wrong with the font mapping subsystem, but we can't
1361 * test that here.
1362 */
1363 void
1364 LocaleTest::Test4139940()
1365 {
1366 Locale mylocale("hu", "", "");
1367 UDate mydate = date(98,3,13); // A Monday
1368 UErrorCode status = U_ZERO_ERROR;
1369 SimpleDateFormat df_full("EEEE", mylocale, status);
1370 if(U_FAILURE(status)){
1371 dataerrln(UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: ") + UnicodeString(u_errorName(status)));
1372 return;
1373 }
1374 UnicodeString str;
1375 FieldPosition pos(FieldPosition::DONT_CARE);
1376 df_full.format(mydate, str, pos);
1377 // Make sure that o circumflex (\u00F4) is NOT there, and
1378 // o double acute (\u0151) IS.
1379 UChar ocf = 0x00f4;
1380 UChar oda = 0x0151;
1381 if (str.indexOf(oda) < 0 || str.indexOf(ocf) >= 0) {
1382 /* If the default locale is "th" this test will fail because of the buddhist calendar. */
1383 if (strcmp(Locale::getDefault().getLanguage(), "th") != 0) {
1384 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's is %d",
1385 str.indexOf(oda), str.indexOf(ocf));
1386 } else {
1387 logln(UnicodeString("An error is produce in buddhist calendar."));
1388 }
1389 logln(UnicodeString("String is: ") + str );
1390 }
1391 }
1392
1393 UDate
1394 LocaleTest::date(int32_t y, int32_t m, int32_t d, int32_t hr, int32_t min, int32_t sec)
1395 {
1396 UErrorCode status = U_ZERO_ERROR;
1397 Calendar *cal = Calendar::createInstance(status);
1398 if (cal == 0)
1399 return 0.0;
1400 cal->clear();
1401 cal->set(1900 + y, m, d, hr, min, sec); // Add 1900 to follow java.util.Date protocol
1402 UDate dt = cal->getTime(status);
1403 if (U_FAILURE(status))
1404 return 0.0;
1405
1406 delete cal;
1407 return dt;
1408 }
1409
1410 /**
1411 * @bug 4143951
1412 * Russian first day of week should be Monday. Confirmed.
1413 */
1414 void
1415 LocaleTest::Test4143951()
1416 {
1417 UErrorCode status = U_ZERO_ERROR;
1418 Calendar *cal = Calendar::createInstance(Locale("ru", "", ""), status);
1419 if(U_SUCCESS(status)) {
1420 if (cal->getFirstDayOfWeek(status) != UCAL_MONDAY) {
1421 dataerrln("Fail: First day of week in Russia should be Monday");
1422 }
1423 }
1424 delete cal;
1425 }
1426
1427 #endif
1428
1429 /**
1430 * @bug 4147315
1431 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes.
1432 * Should throw an exception for unknown locales
1433 */
1434 void
1435 LocaleTest::Test4147315()
1436 {
1437 UnicodeString temp;
1438 // Try with codes that are the wrong length but happen to match text
1439 // at a valid offset in the mapping table
1440 Locale locale("xxx", "CCC");
1441
1442 const char *result = locale.getISO3Country();
1443
1444 // Change to conform to C api usage
1445 if((result==NULL)||(result[0] != 0))
1446 errln("ERROR: getISO3Country() returns: " + UnicodeString(result,"") +
1447 " for locale '" + (temp=locale.getName()) + "' rather than exception" );
1448 }
1449
1450 /**
1451 * @bug 4147317
1452 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes.
1453 * Should throw an exception for unknown locales
1454 */
1455 void
1456 LocaleTest::Test4147317()
1457 {
1458 UnicodeString temp;
1459 // Try with codes that are the wrong length but happen to match text
1460 // at a valid offset in the mapping table
1461 Locale locale("xxx", "CCC");
1462
1463 const char *result = locale.getISO3Language();
1464
1465 // Change to conform to C api usage
1466 if((result==NULL)||(result[0] != 0))
1467 errln("ERROR: getISO3Language() returns: " + UnicodeString(result,"") +
1468 " for locale '" + (temp=locale.getName()) + "' rather than exception" );
1469 }
1470
1471 /*
1472 * @bug 4147552
1473 */
1474 void
1475 LocaleTest::Test4147552()
1476 {
1477 Locale locales [] = { Locale("no", "NO"),
1478 Locale("no", "NO", "B"),
1479 Locale("no", "NO", "NY")
1480 };
1481
1482 UnicodeString edn("Norwegian (Norway, B)");
1483 UnicodeString englishDisplayNames [] = {
1484 "Norwegian (Norway)",
1485 edn,
1486 // "Norwegian (Norway,B)",
1487 //"Norwegian (Norway,NY)"
1488 "Norwegian (Norway, NY)"
1489 };
1490 UnicodeString ndn("norsk (Norge, B");
1491 UnicodeString norwegianDisplayNames [] = {
1492 "norsk (Norge)",
1493 "norsk (Norge, B)",
1494 //ndn,
1495 "norsk (Noreg, NY)"
1496 //"Norsk (Noreg, Nynorsk)"
1497 };
1498 UErrorCode status = U_ZERO_ERROR;
1499
1500 Locale saveLocale;
1501 Locale::setDefault(Locale::getEnglish(), status);
1502 for (int32_t i = 0; i < 3; ++i) {
1503 Locale loc = locales[i];
1504 UnicodeString temp;
1505 if (loc.getDisplayName(temp) != englishDisplayNames[i])
1506 dataerrln("English display-name mismatch: expected " +
1507 englishDisplayNames[i] + ", got " + loc.getDisplayName(temp));
1508 if (loc.getDisplayName(loc, temp) != norwegianDisplayNames[i])
1509 dataerrln("Norwegian display-name mismatch: expected " +
1510 norwegianDisplayNames[i] + ", got " +
1511 loc.getDisplayName(loc, temp));
1512 }
1513 Locale::setDefault(saveLocale, status);
1514 }
1515
1516 void
1517 LocaleTest::TestVariantParsing()
1518 {
1519 Locale en_US_custom("en", "US", "De Anza_Cupertino_California_United States_Earth");
1520
1521 UnicodeString dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH)");
1522 UnicodeString dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH");
1523
1524 UnicodeString got;
1525
1526 en_US_custom.getDisplayVariant(Locale::getUS(), got);
1527 if(got != dispVar) {
1528 errln("FAIL: getDisplayVariant()");
1529 errln("Wanted: " + dispVar);
1530 errln("Got : " + got);
1531 }
1532
1533 en_US_custom.getDisplayName(Locale::getUS(), got);
1534 if(got != dispName) {
1535 dataerrln("FAIL: getDisplayName()");
1536 dataerrln("Wanted: " + dispName);
1537 dataerrln("Got : " + got);
1538 }
1539
1540 Locale shortVariant("fr", "FR", "foo");
1541 shortVariant.getDisplayVariant(got);
1542
1543 if(got != "FOO") {
1544 errln("FAIL: getDisplayVariant()");
1545 errln("Wanted: foo");
1546 errln("Got : " + got);
1547 }
1548
1549 Locale bogusVariant("fr", "FR", "_foo");
1550 bogusVariant.getDisplayVariant(got);
1551
1552 if(got != "FOO") {
1553 errln("FAIL: getDisplayVariant()");
1554 errln("Wanted: foo");
1555 errln("Got : " + got);
1556 }
1557
1558 Locale bogusVariant2("fr", "FR", "foo_");
1559 bogusVariant2.getDisplayVariant(got);
1560
1561 if(got != "FOO") {
1562 errln("FAIL: getDisplayVariant()");
1563 errln("Wanted: foo");
1564 errln("Got : " + got);
1565 }
1566
1567 Locale bogusVariant3("fr", "FR", "_foo_");
1568 bogusVariant3.getDisplayVariant(got);
1569
1570 if(got != "FOO") {
1571 errln("FAIL: getDisplayVariant()");
1572 errln("Wanted: foo");
1573 errln("Got : " + got);
1574 }
1575 }
1576
1577 #if !UCONFIG_NO_FORMATTING
1578
1579 /**
1580 * @bug 4105828
1581 * Currency symbol in zh is wrong. We will test this at the NumberFormat
1582 * end to test the whole pipe.
1583 */
1584 void
1585 LocaleTest::Test4105828()
1586 {
1587 Locale LOC [] = { Locale::getChinese(), Locale("zh", "CN", ""),
1588 Locale("zh", "TW", ""), Locale("zh", "HK", "") };
1589 UErrorCode status = U_ZERO_ERROR;
1590 for (int32_t i = 0; i < 4; ++i) {
1591 NumberFormat *fmt = NumberFormat::createPercentInstance(LOC[i], status);
1592 if(U_FAILURE(status)) {
1593 dataerrln("Couldn't create NumberFormat - %s", u_errorName(status));
1594 return;
1595 }
1596 UnicodeString result;
1597 FieldPosition pos(FieldPosition::DONT_CARE);
1598 fmt->format((int32_t)1, result, pos);
1599 UnicodeString temp;
1600 if(result != "100%") {
1601 errln(UnicodeString("Percent for ") + LOC[i].getDisplayName(temp) + " should be 100%, got " + result);
1602 }
1603 delete fmt;
1604 }
1605 }
1606
1607 #endif
1608
1609 // Tests setBogus and isBogus APIs for Locale
1610 // Jitterbug 1735
1611 void
1612 LocaleTest::TestSetIsBogus() {
1613 Locale l("en_US");
1614 l.setToBogus();
1615 if(l.isBogus() != TRUE) {
1616 errln("After setting bogus, didn't return TRUE");
1617 }
1618 l = "en_US"; // This should reset bogus
1619 if(l.isBogus() != FALSE) {
1620 errln("After resetting bogus, didn't return FALSE");
1621 }
1622 }
1623
1624
1625 void
1626 LocaleTest::TestAddLikelySubtags() {
1627 IcuTestErrorCode status(*this, "TestAddLikelySubtags()");
1628
1629 static const Locale min("sv");
1630 static const Locale max("sv_Latn_SE");
1631
1632 Locale result(min);
1633 result.addLikelySubtags(status);
1634 status.errIfFailureAndReset("\"%s\"", min.getName());
1635 assertEquals("addLikelySubtags", max.getName(), result.getName());
1636 }
1637
1638
1639 void
1640 LocaleTest::TestMinimizeSubtags() {
1641 IcuTestErrorCode status(*this, "TestMinimizeSubtags()");
1642
1643 static const Locale max("zh_Hant_TW");
1644 static const Locale min("zh_TW");
1645
1646 Locale result(max);
1647 result.minimizeSubtags(status);
1648 status.errIfFailureAndReset("\"%s\"", max.getName());
1649 assertEquals("minimizeSubtags", min.getName(), result.getName());
1650 }
1651
1652
1653 void
1654 LocaleTest::TestAddLikelyAndMinimizeSubtags() {
1655 IcuTestErrorCode status(*this, "TestAddLikelyAndMinimizeSubtags()");
1656
1657 static const struct {
1658 const char* const from;
1659 const char* const add;
1660 const char* const remove;
1661 } full_data[] = {
1662 {
1663 "und_AQ",
1664 "und_Latn_AQ",
1665 "und_AQ"
1666 }, {
1667 "und_Zzzz_AQ",
1668 "und_Latn_AQ",
1669 "und_AQ"
1670 }, {
1671 "und_Latn_AQ",
1672 "und_Latn_AQ",
1673 "und_AQ"
1674 }, {
1675 "und_Moon_AQ",
1676 "und_Moon_AQ",
1677 "und_Moon_AQ"
1678 },
1679 };
1680
1681 for (const auto& item : full_data) {
1682 const char* const org = item.from;
1683 const char* const exp = item.add;
1684 Locale res(org);
1685 res.addLikelySubtags(status);
1686 status.errIfFailureAndReset("\"%s\"", org);
1687 assertEquals("addLikelySubtags", exp, res.getName());
1688 }
1689
1690 for (const auto& item : full_data) {
1691 const char* const org = item.from;
1692 const char* const exp = item.remove;
1693 Locale res(org);
1694 res.minimizeSubtags(status);
1695 status.errIfFailureAndReset("\"%s\"", org);
1696 assertEquals("minimizeSubtags", exp, res.getName());
1697 }
1698 }
1699
1700
1701 void
1702 LocaleTest::TestKeywordVariants(void) {
1703 static const struct {
1704 const char *localeID;
1705 const char *expectedLocaleID;
1706 //const char *expectedLocaleIDNoKeywords;
1707 //const char *expectedCanonicalID;
1708 const char *expectedKeywords[10];
1709 int32_t numKeywords;
1710 UErrorCode expectedStatus;
1711 } testCases[] = {
1712 {
1713 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen dar = buddhist ",
1714 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1715 //"de_DE",
1716 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro",
1717 {"calendar", "collation", "currency"},
1718 3,
1719 U_ZERO_ERROR
1720 },
1721 {
1722 "de_DE@euro",
1723 "de_DE@euro",
1724 //"de_DE",
1725 //"de_DE@currency=EUR",
1726 {"","","","","","",""},
1727 0,
1728 U_INVALID_FORMAT_ERROR /* must have '=' after '@' */
1729 }
1730 };
1731 UErrorCode status = U_ZERO_ERROR;
1732
1733 int32_t i = 0, j = 0;
1734 const char *result = NULL;
1735 StringEnumeration *keywords;
1736 int32_t keyCount = 0;
1737 const char *keyword = NULL;
1738 const UnicodeString *keywordString;
1739 int32_t keywordLen = 0;
1740
1741 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
1742 status = U_ZERO_ERROR;
1743 Locale l(testCases[i].localeID);
1744 keywords = l.createKeywords(status);
1745
1746 if(status != testCases[i].expectedStatus) {
1747 err("Expected to get status %s. Got %s instead\n",
1748 u_errorName(testCases[i].expectedStatus), u_errorName(status));
1749 }
1750 status = U_ZERO_ERROR;
1751 if(keywords) {
1752 if((keyCount = keywords->count(status)) != testCases[i].numKeywords) {
1753 err("Expected to get %i keywords, got %i\n", testCases[i].numKeywords, keyCount);
1754 }
1755 if(keyCount) {
1756 for(j = 0;;) {
1757 if((j&1)==0) {
1758 if((keyword = keywords->next(&keywordLen, status)) == NULL) {
1759 break;
1760 }
1761 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1762 err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1763 }
1764 } else {
1765 if((keywordString = keywords->snext(status)) == NULL) {
1766 break;
1767 }
1768 if(*keywordString != UnicodeString(testCases[i].expectedKeywords[j], "")) {
1769 err("Expected to get keyword UnicodeString %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1770 }
1771 }
1772 j++;
1773
1774 if(j == keyCount / 2) {
1775 // replace keywords with a clone of itself
1776 StringEnumeration *k2 = keywords->clone();
1777 if(k2 == NULL || keyCount != k2->count(status)) {
1778 errln("KeywordEnumeration.clone() failed");
1779 } else {
1780 delete keywords;
1781 keywords = k2;
1782 }
1783 }
1784 }
1785 keywords->reset(status); // Make sure that reset works.
1786 for(j = 0;;) {
1787 if((keyword = keywords->next(&keywordLen, status)) == NULL) {
1788 break;
1789 }
1790 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) {
1791 err("Expected to get keyword value %s, got %s\n", testCases[i].expectedKeywords[j], keyword);
1792 }
1793 j++;
1794 }
1795 }
1796 delete keywords;
1797 }
1798 result = l.getName();
1799 if(uprv_strcmp(testCases[i].expectedLocaleID, result) != 0) {
1800 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n",
1801 testCases[i].expectedLocaleID, testCases[i].localeID, result);
1802 }
1803
1804 }
1805
1806 }
1807
1808
1809 void
1810 LocaleTest::TestCreateUnicodeKeywords(void) {
1811 IcuTestErrorCode status(*this, "TestCreateUnicodeKeywords()");
1812
1813 static const Locale l("de@calendar=buddhist;collation=phonebook");
1814
1815 LocalPointer<StringEnumeration> keys(l.createUnicodeKeywords(status));
1816 status.errIfFailureAndReset("\"%s\"", l.getName());
1817
1818 const char* key;
1819 int32_t resultLength;
1820
1821 key = keys->next(&resultLength, status);
1822 status.errIfFailureAndReset("key #1");
1823 assertEquals("resultLength", 2, resultLength);
1824 assertTrue("key != nullptr", key != nullptr);
1825 if (key != nullptr) {
1826 assertEquals("calendar", "ca", key);
1827 }
1828
1829 key = keys->next(&resultLength, status);
1830 status.errIfFailureAndReset("key #2");
1831 assertEquals("resultLength", 2, resultLength);
1832 assertTrue("key != nullptr", key != nullptr);
1833 if (key != nullptr) {
1834 assertEquals("collation", "co", key);
1835 }
1836
1837 key = keys->next(&resultLength, status);
1838 status.errIfFailureAndReset("end of keys");
1839 assertEquals("resultLength", 0, resultLength);
1840 assertTrue("key == nullptr", key == nullptr);
1841
1842 const UnicodeString* skey;
1843 keys->reset(status); // KeywordEnumeration::reset() never touches status.
1844
1845 skey = keys->snext(status);
1846 status.errIfFailureAndReset("skey #1");
1847 assertTrue("skey != nullptr", skey != nullptr);
1848 if (skey != nullptr) {
1849 assertEquals("calendar", "ca", *skey);
1850 }
1851
1852 skey = keys->snext(status);
1853 status.errIfFailureAndReset("skey #2");
1854 assertTrue("skey != nullptr", skey != nullptr);
1855 if (skey != nullptr) {
1856 assertEquals("collation", "co", *skey);
1857 }
1858
1859 skey = keys->snext(status);
1860 status.errIfFailureAndReset("end of keys");
1861 assertTrue("skey == nullptr", skey == nullptr);
1862 }
1863
1864
1865 void
1866 LocaleTest::TestKeywordVariantParsing(void) {
1867 static const struct {
1868 const char *localeID;
1869 const char *keyword;
1870 const char *expectedValue;
1871 } testCases[] = {
1872 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook" },
1873 { "de_DE", "collation", ""},
1874 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" },
1875 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation", "PHONEBOOk" },
1876 };
1877
1878 UErrorCode status = U_ZERO_ERROR;
1879
1880 int32_t i = 0;
1881 int32_t resultLen = 0;
1882 char buffer[256];
1883
1884 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
1885 *buffer = 0;
1886 Locale l(testCases[i].localeID);
1887 resultLen = l.getKeywordValue(testCases[i].keyword, buffer, 256, status);
1888 (void)resultLen; // Suppress unused variable warning.
1889 if(uprv_strcmp(testCases[i].expectedValue, buffer) != 0) {
1890 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1891 testCases[i].expectedValue, testCases[i].localeID, testCases[i].keyword, buffer);
1892 }
1893 }
1894 }
1895
1896 void
1897 LocaleTest::TestCreateKeywordSet(void) {
1898 IcuTestErrorCode status(*this, "TestCreateKeywordSet()");
1899
1900 static const Locale l("de@calendar=buddhist;collation=phonebook");
1901
1902 std::set<std::string> result;
1903 l.getKeywords<std::string>(
1904 std::insert_iterator<decltype(result)>(result, result.begin()),
1905 status);
1906 status.errIfFailureAndReset("\"%s\"", l.getName());
1907
1908 assertEquals("set::size()", 2, static_cast<int32_t>(result.size()));
1909 assertTrue("set::find(\"calendar\")",
1910 result.find("calendar") != result.end());
1911 assertTrue("set::find(\"collation\")",
1912 result.find("collation") != result.end());
1913 }
1914
1915 void
1916 LocaleTest::TestCreateUnicodeKeywordSet(void) {
1917 IcuTestErrorCode status(*this, "TestCreateUnicodeKeywordSet()");
1918
1919 static const Locale l("de@calendar=buddhist;collation=phonebook");
1920
1921 std::set<std::string> result;
1922 l.getUnicodeKeywords<std::string>(
1923 std::insert_iterator<decltype(result)>(result, result.begin()),
1924 status);
1925 status.errIfFailureAndReset("\"%s\"", l.getName());
1926
1927 assertEquals("set::size()", 2, static_cast<int32_t>(result.size()));
1928 assertTrue("set::find(\"ca\")",
1929 result.find("ca") != result.end());
1930 assertTrue("set::find(\"co\")",
1931 result.find("co") != result.end());
1932 }
1933
1934 void
1935 LocaleTest::TestGetKeywordValueStdString(void) {
1936 IcuTestErrorCode status(*this, "TestGetKeywordValueStdString()");
1937
1938 static const char tag[] = "fa-u-nu-latn";
1939 static const char keyword[] = "numbers";
1940 static const char expected[] = "latn";
1941
1942 Locale l = Locale::forLanguageTag(tag, status);
1943 status.errIfFailureAndReset("\"%s\"", tag);
1944
1945 std::string result = l.getKeywordValue<std::string>(keyword, status);
1946 status.errIfFailureAndReset("\"%s\"", keyword);
1947 assertEquals(keyword, expected, result.c_str());
1948 }
1949
1950 void
1951 LocaleTest::TestGetUnicodeKeywordValueStdString(void) {
1952 IcuTestErrorCode status(*this, "TestGetUnicodeKeywordValueStdString()");
1953
1954 static const char keyword[] = "co";
1955 static const char expected[] = "phonebk";
1956
1957 static const Locale l("de@calendar=buddhist;collation=phonebook");
1958
1959 std::string result = l.getUnicodeKeywordValue<std::string>(keyword, status);
1960 status.errIfFailureAndReset("\"%s\"", keyword);
1961 assertEquals(keyword, expected, result.c_str());
1962 }
1963
1964 void
1965 LocaleTest::TestSetKeywordValue(void) {
1966 static const struct {
1967 const char *keyword;
1968 const char *value;
1969 } testCases[] = {
1970 { "collation", "phonebook" },
1971 { "currency", "euro" },
1972 { "calendar", "buddhist" }
1973 };
1974
1975 UErrorCode status = U_ZERO_ERROR;
1976
1977 int32_t i = 0;
1978 int32_t resultLen = 0;
1979 char buffer[256];
1980
1981 Locale l(Locale::getGerman());
1982
1983 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
1984 l.setKeywordValue(testCases[i].keyword, testCases[i].value, status);
1985 if(U_FAILURE(status)) {
1986 err("FAIL: Locale::setKeywordValue failed - %s\n", u_errorName(status));
1987 }
1988
1989 *buffer = 0;
1990 resultLen = l.getKeywordValue(testCases[i].keyword, buffer, 256, status);
1991 (void)resultLen; // Suppress unused variable warning.
1992 if(uprv_strcmp(testCases[i].value, buffer) != 0) {
1993 err("Expected to extract \"%s\" for keyword \"%s\". Got \"%s\" instead\n",
1994 testCases[i].value, testCases[i].keyword, buffer);
1995 }
1996 }
1997 }
1998
1999 void
2000 LocaleTest::TestSetKeywordValueStringPiece(void) {
2001 IcuTestErrorCode status(*this, "TestSetKeywordValueStringPiece()");
2002 Locale l(Locale::getGerman());
2003
2004 l.setKeywordValue(StringPiece("collation"), StringPiece("phonebook"), status);
2005 l.setKeywordValue(StringPiece("calendarxxx", 8), StringPiece("buddhistxxx", 8), status);
2006
2007 static const char expected[] = "de@calendar=buddhist;collation=phonebook";
2008 assertEquals("", expected, l.getName());
2009 }
2010
2011 void
2012 LocaleTest::TestSetUnicodeKeywordValueStringPiece(void) {
2013 IcuTestErrorCode status(*this, "TestSetUnicodeKeywordValueStringPiece()");
2014 Locale l(Locale::getGerman());
2015
2016 l.setUnicodeKeywordValue(StringPiece("co"), StringPiece("phonebk"), status);
2017 status.errIfFailureAndReset();
2018
2019 l.setUnicodeKeywordValue(StringPiece("caxxx", 2), StringPiece("buddhistxxx", 8), status);
2020 status.errIfFailureAndReset();
2021
2022 static const char expected[] = "de@calendar=buddhist;collation=phonebook";
2023 assertEquals("", expected, l.getName());
2024
2025 l.setUnicodeKeywordValue("cu", nullptr, status);
2026 status.errIfFailureAndReset();
2027 assertEquals("", expected, l.getName());
2028
2029 l.setUnicodeKeywordValue("!!", nullptr, status);
2030 assertEquals("status", U_ILLEGAL_ARGUMENT_ERROR, status.reset());
2031 assertEquals("", expected, l.getName());
2032
2033 l.setUnicodeKeywordValue("co", "!!", status);
2034 assertEquals("status", U_ILLEGAL_ARGUMENT_ERROR, status.reset());
2035 assertEquals("", expected, l.getName());
2036
2037 l.setUnicodeKeywordValue("co", nullptr, status);
2038 status.errIfFailureAndReset();
2039
2040 l.setUnicodeKeywordValue("ca", "", status);
2041 status.errIfFailureAndReset();
2042
2043 assertEquals("", Locale::getGerman().getName(), l.getName());
2044 }
2045
2046 void
2047 LocaleTest::TestGetBaseName(void) {
2048 static const struct {
2049 const char *localeID;
2050 const char *baseName;
2051 } testCases[] = {
2052 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" },
2053 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" },
2054 { "ja@calendar = buddhist", "ja" },
2055 { "de-u-co-phonebk", "de"}
2056 };
2057
2058 int32_t i = 0;
2059
2060 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) {
2061 Locale loc(testCases[i].localeID);
2062 if(strcmp(testCases[i].baseName, loc.getBaseName())) {
2063 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"",
2064 testCases[i].localeID, testCases[i].baseName, loc.getBaseName());
2065 return;
2066 }
2067 }
2068
2069 // Verify that adding a keyword to an existing Locale doesn't change the base name.
2070 UErrorCode status = U_ZERO_ERROR;
2071 Locale loc2("en-US");
2072 if (strcmp("en_US", loc2.getBaseName())) {
2073 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__, __LINE__, loc2.getBaseName());
2074 }
2075 loc2.setKeywordValue("key", "value", status);
2076 if (strcmp("en_US@key=value", loc2.getName())) {
2077 errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__, __LINE__, loc2.getName());
2078 }
2079 if (strcmp("en_US", loc2.getBaseName())) {
2080 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__, __LINE__, loc2.getBaseName());
2081 }
2082 }
2083
2084 /**
2085 * Compare two locale IDs. If they are equal, return 0. If `string'
2086 * starts with `prefix' plus an additional element, that is, string ==
2087 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
2088 */
2089 static UBool _loccmp(const char* string, const char* prefix) {
2090 int32_t slen = (int32_t)strlen(string),
2091 plen = (int32_t)strlen(prefix);
2092 int32_t c = uprv_strncmp(string, prefix, plen);
2093 /* 'root' is "less than" everything */
2094 if (prefix[0] == '\0') {
2095 return string[0] != '\0';
2096 }
2097 if (c) return -1; /* mismatch */
2098 if (slen == plen) return 0;
2099 if (string[plen] == '_') return 1;
2100 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
2101 }
2102
2103 /**
2104 * Check the relationship between requested locales, and report problems.
2105 * The caller specifies the expected relationships between requested
2106 * and valid (expReqValid) and between valid and actual (expValidActual).
2107 * Possible values are:
2108 * "gt" strictly greater than, e.g., en_US > en
2109 * "ge" greater or equal, e.g., en >= en
2110 * "eq" equal, e.g., en == en
2111 */
2112 void LocaleTest::_checklocs(const char* label,
2113 const char* req,
2114 const Locale& validLoc,
2115 const Locale& actualLoc,
2116 const char* expReqValid,
2117 const char* expValidActual) {
2118 const char* valid = validLoc.getName();
2119 const char* actual = actualLoc.getName();
2120 int32_t reqValid = _loccmp(req, valid);
2121 int32_t validActual = _loccmp(valid, actual);
2122 if (((0 == uprv_strcmp(expReqValid, "gt") && reqValid > 0) ||
2123 (0 == uprv_strcmp(expReqValid, "ge") && reqValid >= 0) ||
2124 (0 == uprv_strcmp(expReqValid, "eq") && reqValid == 0)) &&
2125 ((0 == uprv_strcmp(expValidActual, "gt") && validActual > 0) ||
2126 (0 == uprv_strcmp(expValidActual, "ge") && validActual >= 0) ||
2127 (0 == uprv_strcmp(expValidActual, "eq") && validActual == 0))) {
2128 logln("%s; req=%s, valid=%s, actual=%s",
2129 label, req, valid, actual);
2130 } else {
2131 dataerrln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and (V %s A)",
2132 label, req, valid, actual,
2133 expReqValid, expValidActual);
2134 }
2135 }
2136
2137 void LocaleTest::TestGetLocale(void) {
2138 #if !UCONFIG_NO_SERVICE
2139 const char *req;
2140 Locale valid, actual, reqLoc;
2141
2142 // Calendar
2143 #if !UCONFIG_NO_FORMATTING
2144 {
2145 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
2146 req = "en_US_BROOKLYN";
2147 Calendar* cal = Calendar::createInstance(Locale::createFromName(req), ec);
2148 if (U_FAILURE(ec)) {
2149 dataerrln("FAIL: Calendar::createInstance failed - %s", u_errorName(ec));
2150 } else {
2151 valid = cal->getLocale(ULOC_VALID_LOCALE, ec);
2152 actual = cal->getLocale(ULOC_ACTUAL_LOCALE, ec);
2153 if (U_FAILURE(ec)) {
2154 errln("FAIL: Calendar::getLocale() failed");
2155 } else {
2156 _checklocs("Calendar", req, valid, actual);
2157 }
2158 /* Make sure that it fails correctly */
2159 ec = U_FILE_ACCESS_ERROR;
2160 if (cal->getLocale(ULOC_VALID_LOCALE, ec).getName()[0] != 0) {
2161 errln("FAIL: Calendar::getLocale() failed to fail correctly. It should have returned \"\"");
2162 }
2163 ec = U_ZERO_ERROR;
2164 }
2165 delete cal;
2166 }
2167 #endif
2168
2169 // DecimalFormat, DecimalFormatSymbols
2170 #if !UCONFIG_NO_FORMATTING
2171 {
2172 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
2173 req = "fr_FR_NICE";
2174 NumberFormat* nf = NumberFormat::createInstance(Locale::createFromName(req), ec);
2175 if (U_FAILURE(ec)) {
2176 dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec));
2177 } else {
2178 DecimalFormat* dec = dynamic_cast<DecimalFormat*>(nf);
2179 if (dec == NULL) {
2180 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat");
2181 return;
2182 }
2183 valid = dec->getLocale(ULOC_VALID_LOCALE, ec);
2184 actual = dec->getLocale(ULOC_ACTUAL_LOCALE, ec);
2185 if (U_FAILURE(ec)) {
2186 errln("FAIL: DecimalFormat::getLocale() failed");
2187 } else {
2188 _checklocs("DecimalFormat", req, valid, actual);
2189 }
2190
2191 const DecimalFormatSymbols* sym = dec->getDecimalFormatSymbols();
2192 if (sym == NULL) {
2193 errln("FAIL: getDecimalFormatSymbols returned NULL");
2194 return;
2195 }
2196 valid = sym->getLocale(ULOC_VALID_LOCALE, ec);
2197 actual = sym->getLocale(ULOC_ACTUAL_LOCALE, ec);
2198 if (U_FAILURE(ec)) {
2199 errln("FAIL: DecimalFormatSymbols::getLocale() failed");
2200 } else {
2201 _checklocs("DecimalFormatSymbols", req, valid, actual);
2202 }
2203 }
2204 delete nf;
2205 }
2206 #endif
2207
2208 // DateFormat, DateFormatSymbols
2209 #if !UCONFIG_NO_FORMATTING
2210 {
2211 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
2212 req = "de_CH_LUCERNE";
2213 DateFormat* df =
2214 DateFormat::createDateInstance(DateFormat::kDefault,
2215 Locale::createFromName(req));
2216 if (df == 0){
2217 dataerrln("Error calling DateFormat::createDateInstance()");
2218 } else {
2219 SimpleDateFormat* dat = dynamic_cast<SimpleDateFormat*>(df);
2220 if (dat == NULL) {
2221 errln("FAIL: DateFormat::createInstance does not return a SimpleDateFormat");
2222 return;
2223 }
2224 valid = dat->getLocale(ULOC_VALID_LOCALE, ec);
2225 actual = dat->getLocale(ULOC_ACTUAL_LOCALE, ec);
2226 if (U_FAILURE(ec)) {
2227 errln("FAIL: SimpleDateFormat::getLocale() failed");
2228 } else {
2229 _checklocs("SimpleDateFormat", req, valid, actual);
2230 }
2231
2232 const DateFormatSymbols* sym = dat->getDateFormatSymbols();
2233 if (sym == NULL) {
2234 errln("FAIL: getDateFormatSymbols returned NULL");
2235 return;
2236 }
2237 valid = sym->getLocale(ULOC_VALID_LOCALE, ec);
2238 actual = sym->getLocale(ULOC_ACTUAL_LOCALE, ec);
2239 if (U_FAILURE(ec)) {
2240 errln("FAIL: DateFormatSymbols::getLocale() failed");
2241 } else {
2242 _checklocs("DateFormatSymbols", req, valid, actual);
2243 }
2244 }
2245 delete df;
2246 }
2247 #endif
2248
2249 // BreakIterator
2250 #if !UCONFIG_NO_BREAK_ITERATION
2251 {
2252 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
2253 req = "es_ES_BARCELONA";
2254 reqLoc = Locale::createFromName(req);
2255 BreakIterator* brk = BreakIterator::createWordInstance(reqLoc, ec);
2256 if (U_FAILURE(ec)) {
2257 dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_errorName(ec));
2258 } else {
2259 valid = brk->getLocale(ULOC_VALID_LOCALE, ec);
2260 actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec);
2261 if (U_FAILURE(ec)) {
2262 errln("FAIL: BreakIterator::getLocale() failed");
2263 } else {
2264 _checklocs("BreakIterator", req, valid, actual);
2265 }
2266
2267 // After registering something, the behavior should be different
2268 URegistryKey key = BreakIterator::registerInstance(brk, reqLoc, UBRK_WORD, ec);
2269 brk = 0; // registerInstance adopts
2270 if (U_FAILURE(ec)) {
2271 errln("FAIL: BreakIterator::registerInstance() failed");
2272 } else {
2273 brk = BreakIterator::createWordInstance(reqLoc, ec);
2274 if (U_FAILURE(ec)) {
2275 errln("FAIL: BreakIterator::createWordInstance failed");
2276 } else {
2277 valid = brk->getLocale(ULOC_VALID_LOCALE, ec);
2278 actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec);
2279 if (U_FAILURE(ec)) {
2280 errln("FAIL: BreakIterator::getLocale() failed");
2281 } else {
2282 // N.B.: now expect valid==actual==req
2283 _checklocs("BreakIterator(registered)",
2284 req, valid, actual, "eq", "eq");
2285 }
2286 }
2287 // No matter what, unregister
2288 BreakIterator::unregister(key, ec);
2289 if (U_FAILURE(ec)) {
2290 errln("FAIL: BreakIterator::unregister() failed");
2291 }
2292 delete brk;
2293 brk = 0;
2294 }
2295
2296 // After unregistering, should behave normally again
2297 brk = BreakIterator::createWordInstance(reqLoc, ec);
2298 if (U_FAILURE(ec)) {
2299 errln("FAIL: BreakIterator::createWordInstance failed");
2300 } else {
2301 valid = brk->getLocale(ULOC_VALID_LOCALE, ec);
2302 actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec);
2303 if (U_FAILURE(ec)) {
2304 errln("FAIL: BreakIterator::getLocale() failed");
2305 } else {
2306 _checklocs("BreakIterator(unregistered)", req, valid, actual);
2307 }
2308 }
2309 }
2310 delete brk;
2311 }
2312 #endif
2313
2314 // Collator
2315 #if !UCONFIG_NO_COLLATION
2316 {
2317 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error code
2318
2319 checkRegisteredCollators(NULL); // Don't expect any extras
2320
2321 req = "hi_IN_BHOPAL";
2322 reqLoc = Locale::createFromName(req);
2323 Collator* coll = Collator::createInstance(reqLoc, ec);
2324 if (U_FAILURE(ec)) {
2325 dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(ec));
2326 } else {
2327 valid = coll->getLocale(ULOC_VALID_LOCALE, ec);
2328 actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec);
2329 if (U_FAILURE(ec)) {
2330 errln("FAIL: Collator::getLocale() failed");
2331 } else {
2332 _checklocs("Collator", req, valid, actual);
2333 }
2334
2335 // After registering something, the behavior should be different
2336 URegistryKey key = Collator::registerInstance(coll, reqLoc, ec);
2337 coll = 0; // registerInstance adopts
2338 if (U_FAILURE(ec)) {
2339 errln("FAIL: Collator::registerInstance() failed");
2340 } else {
2341 coll = Collator::createInstance(reqLoc, ec);
2342 if (U_FAILURE(ec)) {
2343 errln("FAIL: Collator::createWordInstance failed");
2344 } else {
2345 valid = coll->getLocale(ULOC_VALID_LOCALE, ec);
2346 actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec);
2347 if (U_FAILURE(ec)) {
2348 errln("FAIL: Collator::getLocale() failed");
2349 } else {
2350 // N.B.: now expect valid==actual==req
2351 _checklocs("Collator(registered)",
2352 req, valid, actual, "eq", "eq");
2353 }
2354 }
2355 checkRegisteredCollators(req); // include hi_IN_BHOPAL
2356
2357 // No matter what, unregister
2358 Collator::unregister(key, ec);
2359 if (U_FAILURE(ec)) {
2360 errln("FAIL: Collator::unregister() failed");
2361 }
2362 delete coll;
2363 coll = 0;
2364 }
2365
2366 // After unregistering, should behave normally again
2367 coll = Collator::createInstance(reqLoc, ec);
2368 if (U_FAILURE(ec)) {
2369 errln("FAIL: Collator::createInstance failed");
2370 } else {
2371 valid = coll->getLocale(ULOC_VALID_LOCALE, ec);
2372 actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec);
2373 if (U_FAILURE(ec)) {
2374 errln("FAIL: Collator::getLocale() failed");
2375 } else {
2376 _checklocs("Collator(unregistered)", req, valid, actual);
2377 }
2378 }
2379 }
2380 delete coll;
2381
2382 checkRegisteredCollators(NULL); // extra should be gone again
2383 }
2384 #endif
2385 #endif
2386 }
2387
2388 #if !UCONFIG_NO_COLLATION
2389 /**
2390 * Compare Collator::getAvailableLocales(int) [ "old", returning an array ]
2391 * with Collator::getAvailableLocales() [ "new", returning a StringEnumeration ]
2392 * These should be identical (check their API docs) EXCEPT that
2393 * if expectExtra is non-NULL, it will be in the "new" array but not "old".
2394 * Does not return any status but calls errln on error.
2395 * @param expectExtra an extra locale, will be in "new" but not "old". Or NULL.
2396 */
2397 void LocaleTest::checkRegisteredCollators(const char *expectExtra) {
2398 UErrorCode status = U_ZERO_ERROR;
2399 int32_t count1=0,count2=0;
2400 Hashtable oldHash(status);
2401 Hashtable newHash(status);
2402 assertSuccess(WHERE, status);
2403
2404 UnicodeString expectStr(expectExtra?expectExtra:"n/a", "");
2405
2406 // the 'old' list (non enumeration)
2407 const Locale* oldList = Collator::getAvailableLocales(count1);
2408 if(oldList == NULL) {
2409 dataerrln("Error: Collator::getAvailableLocales(count) returned NULL");
2410 return;
2411 }
2412
2413 // the 'new' list (enumeration)
2414 LocalPointer<StringEnumeration> newEnum(Collator::getAvailableLocales());
2415 if(newEnum.isNull()) {
2416 errln("Error: collator::getAvailableLocales() returned NULL");
2417 return;
2418 }
2419
2420 // OK. Let's add all of the OLD
2421 // then check for any in the NEW not in OLD
2422 // then check for any in OLD not in NEW.
2423
2424 // 1. add all of OLD
2425 for(int32_t i=0;i<count1;i++) {
2426 const UnicodeString key(oldList[i].getName(), "");
2427 int32_t oldI = oldHash.puti(key, 1, status);
2428 if( oldI == 1 ){
2429 errln("Error: duplicate key %s in Collator::getAvailableLocales(count) list.\n",
2430 oldList[i].getName());
2431 return;
2432 }
2433 if(expectExtra != NULL && !strcmp(expectExtra, oldList[i].getName())) {
2434 errln("Inexplicably, Collator::getAvailableCollators(count) had registered collator %s. This shouldn't happen, so I am going to consider it an error.\n", expectExtra);
2435 }
2436 }
2437
2438 // 2. add all of NEW
2439 const UnicodeString *locStr;
2440 UBool foundExpected = FALSE;
2441 while((locStr = newEnum->snext(status)) && U_SUCCESS(status)) {
2442 count2++;
2443
2444 if(expectExtra != NULL && expectStr == *locStr) {
2445 foundExpected = TRUE;
2446 logln(UnicodeString("Found expected registered collator: ","") + expectStr);
2447 }
2448 (void)foundExpected; // Hush unused variable compiler warning.
2449
2450 if( oldHash.geti(*locStr) == 0 ) {
2451 if(expectExtra != NULL && expectStr==*locStr) {
2452 logln(UnicodeString("As expected, Collator::getAvailableLocales(count) is missing registered collator ") + expectStr);
2453 } else {
2454 errln(UnicodeString("Error: Collator::getAvailableLocales(count) is missing: ","")
2455 + *locStr);
2456 }
2457 }
2458 newHash.puti(*locStr, 1, status);
2459 }
2460
2461 // 3. check all of OLD again
2462 for(int32_t i=0;i<count1;i++) {
2463 const UnicodeString key(oldList[i].getName(), "");
2464 int32_t newI = newHash.geti(key);
2465 if(newI == 0) {
2466 errln(UnicodeString("Error: Collator::getAvailableLocales() is missing: ","")
2467 + key);
2468 }
2469 }
2470
2471 int32_t expectCount2 = count1;
2472 if(expectExtra != NULL) {
2473 expectCount2 ++; // if an extra item registered, bump the expect count
2474 }
2475
2476 assertEquals("Collator::getAvail() count", expectCount2, count2);
2477 }
2478 #endif
2479
2480
2481
2482 void LocaleTest::TestVariantWithOutCountry(void) {
2483 Locale loc("en","","POSIX");
2484 if (0 != strcmp(loc.getVariant(), "POSIX")) {
2485 errln("FAIL: en__POSIX didn't get parsed correctly - name is %s - expected %s got %s", loc.getName(), "POSIX", loc.getVariant());
2486 }
2487 Locale loc2("en","","FOUR");
2488 if (0 != strcmp(loc2.getVariant(), "FOUR")) {
2489 errln("FAIL: en__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc2.getName(), "FOUR", loc2.getVariant());
2490 }
2491 Locale loc3("en","Latn","","FOUR");
2492 if (0 != strcmp(loc3.getVariant(), "FOUR")) {
2493 errln("FAIL: en_Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc3.getName(), "FOUR", loc3.getVariant());
2494 }
2495 Locale loc4("","Latn","","FOUR");
2496 if (0 != strcmp(loc4.getVariant(), "FOUR")) {
2497 errln("FAIL: _Latn__FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc4.getName(), "FOUR", loc4.getVariant());
2498 }
2499 Locale loc5("","Latn","US","FOUR");
2500 if (0 != strcmp(loc5.getVariant(), "FOUR")) {
2501 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly - name is %s - expected %s got %s", loc5.getName(), "FOUR", loc5.getVariant());
2502 }
2503 Locale loc6("de-1901");
2504 if (0 != strcmp(loc6.getVariant(), "1901")) {
2505 errln("FAIL: de-1901 didn't get parsed correctly - name is %s - expected %s got %s", loc6.getName(), "1901", loc6.getVariant());
2506 }
2507 }
2508
2509 static Locale _canonicalize(int32_t selector, /* 0==createFromName, 1==createCanonical, 2==Locale ct */
2510 const char* localeID) {
2511 switch (selector) {
2512 case 0:
2513 return Locale::createFromName(localeID);
2514 case 1:
2515 return Locale::createCanonical(localeID);
2516 case 2:
2517 return Locale(localeID);
2518 default:
2519 return Locale("");
2520 }
2521 }
2522
2523 void LocaleTest::TestCanonicalization(void)
2524 {
2525 static const struct {
2526 const char *localeID; /* input */
2527 const char *getNameID; /* expected getName() result */
2528 const char *canonicalID; /* expected canonicalize() result */
2529 } testCases[] = {
2530 { "ca_ES-with-extra-stuff-that really doesn't make any sense-unless-you're trying to increase code coverage",
2531 "ca_ES_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE",
2532 "ca_ES_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNLESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"},
2533 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" },
2534 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=pinyin" },
2535 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin" },
2536 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" },
2537 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" },
2538 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ },
2539 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX ID */
2540 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan ICU3.0] */ }, /* POSIX ID */
2541 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ_EURO" }, /* qz-qz uses private use iso codes */
2542 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers it BOGUS
2543 // TODO: unify this behavior
2544 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */
2545 { "de-1901", "de__1901", "de__1901" }, /* registered name */
2546 { "de-1906", "de__1906", "de__1906" }, /* registered name */
2547
2548 /* posix behavior that used to be performed by getName */
2549 { "mr.utf8", "mr.utf8", "mr" },
2550 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" },
2551 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" },
2552 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" },
2553 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA" },
2554 { "no-no-ny.utf8@B", "no_NO_NY.utf8@B", "no_NO_NY_B" /* not: "nn_NO" [alan ICU3.0] */ }, /* @ ignored unless variant is empty */
2555
2556 /* fleshing out canonicalization */
2557 /* trim space and sort keywords, ';' is separator so not present at end in canonical form */
2558 { "en_Hant_IL_VALLEY_GIRL@ currency = EUR; calendar = Japanese ;", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
2559 /* already-canonical ids are not changed */
2560 { "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR" },
2561 /* norwegian is just too weird, if we handle things in their full generality */
2562 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ },
2563
2564 /* test cases reflecting internal resource bundle usage */
2565 { "root@kw=foo", "root@kw=foo", "root@kw=foo" },
2566 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" },
2567 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese" },
2568
2569 // Before ICU 64, ICU locale canonicalization had some additional mappings.
2570 // They were removed for ICU-20187 "drop support for long-obsolete locale ID variants".
2571 // The following now use standard canonicalization.
2572 // Apple ICU restores these first 3 mappings deleted in open ICU 64
2573 { "", "", "en_US_POSIX" },
2574 { "C", "c", "en_US_POSIX" },
2575 { "POSIX", "posix", "en_US_POSIX" },
2576 //
2577 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES_PREEURO" },
2578 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT_PREEURO" },
2579 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE_PREEURO" },
2580 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU_PREEURO" },
2581 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR_PREEURO" },
2582 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE_PREEURO" },
2583 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE_PREEURO" },
2584 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES_PREEURO" },
2585 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES_PREEURO" },
2586 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI_PREEURO" },
2587 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE_PREEURO" },
2588 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR_PREEURO" },
2589 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU_PREEURO" },
2590 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE_PREEURO" },
2591 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES_PREEURO" },
2592 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT_PREEURO" },
2593 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE_PREEURO" },
2594 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL_PREEURO" },
2595 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT_PREEURO" },
2596 { "de__PHONEBOOK", "de__PHONEBOOK", "de__PHONEBOOK" },
2597 { "en_GB_EURO", "en_GB_EURO", "en_GB_EURO" },
2598 { "en_GB@EURO", "en_GB@EURO", "en_GB_EURO" }, /* POSIX ID */
2599 { "es__TRADITIONAL", "es__TRADITIONAL", "es__TRADITIONAL" },
2600 { "hi__DIRECT", "hi__DIRECT", "hi__DIRECT" },
2601 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL" },
2602 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH_TRADITIONAL" },
2603 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW_STROKE" },
2604 { "zh__PINYIN", "zh__PINYIN", "zh__PINYIN" },
2605 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_SP_CYRL" }, /* .NET name */
2606 { "sr-SP-Latn", "sr_SP_LATN", "sr_SP_LATN" }, /* .NET name */
2607 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_YU_CYRILLIC" }, /* Linux name */
2608 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_UZ_CYRL" }, /* .NET name */
2609 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_UZ_LATN" }, /* .NET name */
2610 { "zh-CHS", "zh_CHS", "zh_CHS" }, /* .NET name */
2611 { "zh-CHT", "zh_CHT", "zh_CHT" }, /* .NET name This may change back to zh_Hant */
2612 /* PRE_EURO and EURO conversions don't affect other keywords */
2613 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese", "es_ES_PREEURO@calendar=Japanese" },
2614 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah" },
2615 /* currency keyword overrides PRE_EURO and EURO currency */
2616 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR" },
2617 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP" },
2618 };
2619
2620 static const char* label[] = { "createFromName", "createCanonical", "Locale" };
2621
2622 int32_t i, j;
2623
2624 for (i=0; i < UPRV_LENGTHOF(testCases); i++) {
2625 for (j=0; j<3; ++j) {
2626 const char* expected = (j==1) ? testCases[i].canonicalID : testCases[i].getNameID;
2627 Locale loc = _canonicalize(j, testCases[i].localeID);
2628 const char* getName = loc.isBogus() ? "BOGUS" : loc.getName();
2629 if(uprv_strcmp(expected, getName) != 0) {
2630 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"",
2631 label[j], testCases[i].localeID, getName, expected);
2632 } else {
2633 logln("Ok: %s(%s) => \"%s\"",
2634 label[j], testCases[i].localeID, getName);
2635 }
2636 }
2637 }
2638 }
2639
2640 void LocaleTest::TestCurrencyByDate(void)
2641 {
2642 #if !UCONFIG_NO_FORMATTING
2643 UErrorCode status = U_ZERO_ERROR;
2644 UDate date = uprv_getUTCtime();
2645 UChar TMP[4];
2646 int32_t index = 0;
2647 int32_t resLen = 0;
2648 UnicodeString tempStr, resultStr;
2649
2650 // Cycle through historical currencies
2651 date = (UDate)-630720000000.0; // pre 1961 - no currency defined
2652 index = ucurr_countCurrencies("eo_AM", date, &status);
2653 if (index != 0)
2654 {
2655 errcheckln(status, "FAIL: didn't return 0 for eo_AM - %s", u_errorName(status));
2656 }
2657 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status);
2658 if (resLen != 0) {
2659 errcheckln(status, "FAIL: eo_AM didn't return NULL - %s", u_errorName(status));
2660 }
2661 status = U_ZERO_ERROR;
2662
2663 date = (UDate)0.0; // 1970 - one currency defined
2664 index = ucurr_countCurrencies("eo_AM", date, &status);
2665 if (index != 1)
2666 {
2667 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status));
2668 }
2669 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status);
2670 tempStr.setTo(TMP);
2671 resultStr.setTo("SUR");
2672 if (resultStr != tempStr) {
2673 errcheckln(status, "FAIL: didn't return SUR for eo_AM - %s", u_errorName(status));
2674 }
2675
2676 date = (UDate)693792000000.0; // 1992 - one currency defined
2677 index = ucurr_countCurrencies("eo_AM", date, &status);
2678 if (index != 1)
2679 {
2680 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status));
2681 }
2682 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status);
2683 tempStr.setTo(TMP);
2684 resultStr.setTo("RUR");
2685 if (resultStr != tempStr) {
2686 errcheckln(status, "FAIL: didn't return RUR for eo_AM - %s", u_errorName(status));
2687 }
2688
2689 date = (UDate)977616000000.0; // post 1993 - one currency defined
2690 index = ucurr_countCurrencies("eo_AM", date, &status);
2691 if (index != 1)
2692 {
2693 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status));
2694 }
2695 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status);
2696 tempStr.setTo(TMP);
2697 resultStr.setTo("AMD");
2698 if (resultStr != tempStr) {
2699 errcheckln(status, "FAIL: didn't return AMD for eo_AM - %s", u_errorName(status));
2700 }
2701
2702 // Locale AD has multiple currencies at once
2703 date = (UDate)977616000000.0; // year 2001
2704 index = ucurr_countCurrencies("eo_AD", date, &status);
2705 if (index != 4)
2706 {
2707 errcheckln(status, "FAIL: didn't return 4 for eo_AD - %s", u_errorName(status));
2708 }
2709 resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status);
2710 tempStr.setTo(TMP);
2711 resultStr.setTo("EUR");
2712 if (resultStr != tempStr) {
2713 errcheckln(status, "FAIL: didn't return EUR for eo_AD - %s", u_errorName(status));
2714 }
2715 resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status);
2716 tempStr.setTo(TMP);
2717 resultStr.setTo("ESP");
2718 if (resultStr != tempStr) {
2719 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status));
2720 }
2721 resLen = ucurr_forLocaleAndDate("eo_AD", date, 3, TMP, 4, &status);
2722 tempStr.setTo(TMP);
2723 resultStr.setTo("FRF");
2724 if (resultStr != tempStr) {
2725 errcheckln(status, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status));
2726 }
2727 resLen = ucurr_forLocaleAndDate("eo_AD", date, 4, TMP, 4, &status);
2728 tempStr.setTo(TMP);
2729 resultStr.setTo("ADP");
2730 if (resultStr != tempStr) {
2731 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status));
2732 }
2733
2734 date = (UDate)0.0; // year 1970
2735 index = ucurr_countCurrencies("eo_AD", date, &status);
2736 if (index != 3)
2737 {
2738 errcheckln(status, "FAIL: didn't return 3 for eo_AD - %s", u_errorName(status));
2739 }
2740 resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status);
2741 tempStr.setTo(TMP);
2742 resultStr.setTo("ESP");
2743 if (resultStr != tempStr) {
2744 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status));
2745 }
2746 resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status);
2747 tempStr.setTo(TMP);
2748 resultStr.setTo("FRF");
2749 if (resultStr != tempStr) {
2750 errcheckln(status, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status));
2751 }
2752 resLen = ucurr_forLocaleAndDate("eo_AD", date, 3, TMP, 4, &status);
2753 tempStr.setTo(TMP);
2754 resultStr.setTo("ADP");
2755 if (resultStr != tempStr) {
2756 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status));
2757 }
2758
2759 date = (UDate)-630720000000.0; // year 1950
2760 index = ucurr_countCurrencies("eo_AD", date, &status);
2761 if (index != 2)
2762 {
2763 errcheckln(status, "FAIL: didn't return 2 for eo_AD - %s", u_errorName(status));
2764 }
2765 resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status);
2766 tempStr.setTo(TMP);
2767 resultStr.setTo("ESP");
2768 if (resultStr != tempStr) {
2769 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status));
2770 }
2771 resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status);
2772 tempStr.setTo(TMP);
2773 resultStr.setTo("ADP");
2774 if (resultStr != tempStr) {
2775 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status));
2776 }
2777
2778 date = (UDate)-2207520000000.0; // year 1900
2779 index = ucurr_countCurrencies("eo_AD", date, &status);
2780 if (index != 1)
2781 {
2782 errcheckln(status, "FAIL: didn't return 1 for eo_AD - %s", u_errorName(status));
2783 }
2784 resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status);
2785 tempStr.setTo(TMP);
2786 resultStr.setTo("ESP");
2787 if (resultStr != tempStr) {
2788 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status));
2789 }
2790
2791 // Locale UA has gap between years 1994 - 1996
2792 date = (UDate)788400000000.0;
2793 index = ucurr_countCurrencies("eo_UA", date, &status);
2794 if (index != 0)
2795 {
2796 errcheckln(status, "FAIL: didn't return 0 for eo_UA - %s", u_errorName(status));
2797 }
2798 resLen = ucurr_forLocaleAndDate("eo_UA", date, index, TMP, 4, &status);
2799 if (resLen != 0) {
2800 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status));
2801 }
2802 status = U_ZERO_ERROR;
2803
2804 // Test index bounds
2805 resLen = ucurr_forLocaleAndDate("eo_UA", date, 100, TMP, 4, &status);
2806 if (resLen != 0) {
2807 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status));
2808 }
2809 status = U_ZERO_ERROR;
2810
2811 resLen = ucurr_forLocaleAndDate("eo_UA", date, 0, TMP, 4, &status);
2812 if (resLen != 0) {
2813 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status));
2814 }
2815 status = U_ZERO_ERROR;
2816
2817 // Test for bogus locale
2818 index = ucurr_countCurrencies("eo_QQ", date, &status);
2819 if (index != 0)
2820 {
2821 errcheckln(status, "FAIL: didn't return 0 for eo_QQ - %s", u_errorName(status));
2822 }
2823 status = U_ZERO_ERROR;
2824 resLen = ucurr_forLocaleAndDate("eo_QQ", date, 1, TMP, 4, &status);
2825 if (resLen != 0) {
2826 errcheckln(status, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status));
2827 }
2828 status = U_ZERO_ERROR;
2829 resLen = ucurr_forLocaleAndDate("eo_QQ", date, 0, TMP, 4, &status);
2830 if (resLen != 0) {
2831 errcheckln(status, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status));
2832 }
2833 status = U_ZERO_ERROR;
2834
2835 // Cycle through histrocial currencies
2836 date = (UDate)977616000000.0; // 2001 - one currency
2837 index = ucurr_countCurrencies("eo_AO", date, &status);
2838 if (index != 1)
2839 {
2840 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
2841 }
2842 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
2843 tempStr.setTo(TMP);
2844 resultStr.setTo("AOA");
2845 if (resultStr != tempStr) {
2846 errcheckln(status, "FAIL: didn't return AOA for eo_AO - %s", u_errorName(status));
2847 }
2848
2849 date = (UDate)819936000000.0; // 1996 - 2 currencies
2850 index = ucurr_countCurrencies("eo_AO", date, &status);
2851 if (index != 2)
2852 {
2853 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
2854 }
2855 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
2856 tempStr.setTo(TMP);
2857 resultStr.setTo("AOR");
2858 if (resultStr != tempStr) {
2859 errcheckln(status, "FAIL: didn't return AOR for eo_AO - %s", u_errorName(status));
2860 }
2861 resLen = ucurr_forLocaleAndDate("eo_AO", date, 2, TMP, 4, &status);
2862 tempStr.setTo(TMP);
2863 resultStr.setTo("AON");
2864 if (resultStr != tempStr) {
2865 errcheckln(status, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status));
2866 }
2867
2868 date = (UDate)662256000000.0; // 1991 - 2 currencies
2869 index = ucurr_countCurrencies("eo_AO", date, &status);
2870 if (index != 2)
2871 {
2872 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
2873 }
2874 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
2875 tempStr.setTo(TMP);
2876 resultStr.setTo("AON");
2877 if (resultStr != tempStr) {
2878 errcheckln(status, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status));
2879 }
2880 resLen = ucurr_forLocaleAndDate("eo_AO", date, 2, TMP, 4, &status);
2881 tempStr.setTo(TMP);
2882 resultStr.setTo("AOK");
2883 if (resultStr != tempStr) {
2884 errcheckln(status, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status));
2885 }
2886
2887 date = (UDate)315360000000.0; // 1980 - one currency
2888 index = ucurr_countCurrencies("eo_AO", date, &status);
2889 if (index != 1)
2890 {
2891 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
2892 }
2893 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
2894 tempStr.setTo(TMP);
2895 resultStr.setTo("AOK");
2896 if (resultStr != tempStr) {
2897 errcheckln(status, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status));
2898 }
2899
2900 date = (UDate)0.0; // 1970 - no currencies
2901 index = ucurr_countCurrencies("eo_AO", date, &status);
2902 if (index != 0)
2903 {
2904 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status));
2905 }
2906 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status);
2907 if (resLen != 0) {
2908 errcheckln(status, "FAIL: eo_AO didn't return NULL - %s", u_errorName(status));
2909 }
2910 status = U_ZERO_ERROR;
2911
2912 // Test with currency keyword override
2913 date = (UDate)977616000000.0; // 2001 - two currencies
2914 index = ucurr_countCurrencies("eo_DE@currency=DEM", date, &status);
2915 if (index != 2)
2916 {
2917 errcheckln(status, "FAIL: didn't return 2 for eo_DE@currency=DEM - %s", u_errorName(status));
2918 }
2919 resLen = ucurr_forLocaleAndDate("eo_DE@currency=DEM", date, 1, TMP, 4, &status);
2920 tempStr.setTo(TMP);
2921 resultStr.setTo("EUR");
2922 if (resultStr != tempStr) {
2923 errcheckln(status, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s", u_errorName(status));
2924 }
2925 resLen = ucurr_forLocaleAndDate("eo_DE@currency=DEM", date, 2, TMP, 4, &status);
2926 tempStr.setTo(TMP);
2927 resultStr.setTo("DEM");
2928 if (resultStr != tempStr) {
2929 errcheckln(status, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s", u_errorName(status));
2930 }
2931
2932 // Test Euro Support
2933 status = U_ZERO_ERROR; // reset
2934 date = uprv_getUTCtime();
2935
2936 UChar USD[4];
2937 ucurr_forLocaleAndDate("en_US", date, 1, USD, 4, &status);
2938
2939 UChar YEN[4];
2940 ucurr_forLocaleAndDate("ja_JP", date, 1, YEN, 4, &status);
2941
2942 ucurr_forLocaleAndDate("en_US", date, 1, TMP, 4, &status);
2943 if (u_strcmp(USD, TMP) != 0) {
2944 errcheckln(status, "Fail: en_US didn't return USD - %s", u_errorName(status));
2945 }
2946 ucurr_forLocaleAndDate("en_US_Q", date, 1, TMP, 4, &status);
2947 if (u_strcmp(USD, TMP) != 0) {
2948 errcheckln(status, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status));
2949 }
2950 status = U_ZERO_ERROR; // reset
2951 #endif
2952 }
2953
2954 void LocaleTest::TestGetVariantWithKeywords(void)
2955 {
2956 Locale l("en_US_VALLEY@foo=value");
2957 const char *variant = l.getVariant();
2958 logln(variant);
2959 test_assert(strcmp("VALLEY", variant) == 0);
2960
2961 UErrorCode status = U_ZERO_ERROR;
2962 char buffer[50];
2963 int32_t len = l.getKeywordValue("foo", buffer, 50, status);
2964 buffer[len] = '\0';
2965 test_assert(strcmp("value", buffer) == 0);
2966 }
2967
2968 void LocaleTest::TestIsRightToLeft() {
2969 assertFalse("root LTR", Locale::getRoot().isRightToLeft());
2970 assertFalse("zh LTR", Locale::getChinese().isRightToLeft());
2971 assertTrue("ar RTL", Locale("ar").isRightToLeft());
2972 assertTrue("und-EG RTL", Locale("und-EG").isRightToLeft(), FALSE, TRUE);
2973 assertFalse("fa-Cyrl LTR", Locale("fa-Cyrl").isRightToLeft());
2974 assertTrue("en-Hebr RTL", Locale("en-Hebr").isRightToLeft());
2975 assertTrue("ckb RTL", Locale("ckb").isRightToLeft(), FALSE, TRUE); // Sorani Kurdish
2976 assertFalse("fil LTR", Locale("fil").isRightToLeft());
2977 assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft());
2978 // Additional Apple tests for rdar://51447187
2979 assertTrue("sd RTL", Locale("sd").isRightToLeft());
2980 assertTrue("sd_Arab RTL", Locale("sd_Arab").isRightToLeft());
2981 assertFalse("sd_Deva LTR", Locale("sd_Deva").isRightToLeft());
2982 assertFalse("mni_Beng LTR", Locale("mni_Beng").isRightToLeft());
2983 assertFalse("mni_Mtei LTR", Locale("mni_Mtei").isRightToLeft());
2984 assertFalse("sat_Deva LTR", Locale("sat_Deva").isRightToLeft());
2985 assertFalse("sat_Olck LTR", Locale("sat_Olck").isRightToLeft());
2986 assertTrue("ks RTL", Locale("ks").isRightToLeft());
2987 assertTrue("ks_Arab RTL", Locale("ks_Arab").isRightToLeft());
2988 assertTrue("ks_Aran RTL", Locale("ks_Aran").isRightToLeft());
2989 assertFalse("ks_Deva LTR", Locale("ks_Deva").isRightToLeft());
2990 assertFalse("pa LTR", Locale("pa").isRightToLeft());
2991 assertFalse("pa_Guru LTR", Locale("pa_Guru").isRightToLeft());
2992 assertTrue("pa_Arab RTL", Locale("pa_Arab").isRightToLeft());
2993 assertTrue("pa_Aran RTL", Locale("pa_Aran").isRightToLeft());
2994 assertTrue("ur RTL", Locale("ur").isRightToLeft());
2995 assertTrue("ur_Arab RTL", Locale("ur_Arab").isRightToLeft());
2996 assertTrue("ur_Aran RTL", Locale("ur_Aran").isRightToLeft());
2997 }
2998
2999 void LocaleTest::TestBug11421() {
3000 Locale::getDefault().getBaseName();
3001 int32_t numLocales;
3002 const Locale *localeList = Locale::getAvailableLocales(numLocales);
3003 for (int localeIndex = 0; localeIndex < numLocales; localeIndex++) {
3004 const Locale &loc = localeList[localeIndex];
3005 if (strncmp(loc.getName(), loc.getBaseName(), strlen(loc.getBaseName()))) {
3006 errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"",
3007 __FILE__, __LINE__, loc.getName(), loc.getBaseName());
3008 break;
3009 }
3010 }
3011 }
3012
3013 // TestBug13277. The failure manifests as valgrind errors.
3014 // See the trac ticket for details.
3015 //
3016
3017 void LocaleTest::TestBug13277() {
3018 UErrorCode status = U_ZERO_ERROR;
3019 CharString name("en-us-x-foo", -1, status);
3020 while (name.length() < 152) {
3021 name.append("-x-foo", -1, status);
3022 }
3023
3024 while (name.length() < 160) {
3025 name.append('z', status);
3026 Locale loc(name.data(), nullptr, nullptr, nullptr);
3027 }
3028 }
3029
3030 // TestBug13554 Check for read past end of array in getPosixID().
3031 // The bug shows as an Address Sanitizer failure.
3032
3033 void LocaleTest::TestBug13554() {
3034 UErrorCode status = U_ZERO_ERROR;
3035 const int BUFFER_SIZE = 100;
3036 char posixID[BUFFER_SIZE];
3037
3038 for (uint32_t hostid = 0; hostid < 0x500; ++hostid) {
3039 status = U_ZERO_ERROR;
3040 uprv_convertToPosix(hostid, posixID, BUFFER_SIZE, &status);
3041 }
3042 }
3043
3044 void LocaleTest::TestBug20410() {
3045 IcuTestErrorCode status(*this, "TestBug20410()");
3046
3047 static const char tag1[] = "art-lojban-x-0";
3048 static const Locale expected1("jbo@x=0");
3049 Locale result1 = Locale::forLanguageTag(tag1, status);
3050 status.errIfFailureAndReset("\"%s\"", tag1);
3051 assertEquals(tag1, expected1.getName(), result1.getName());
3052
3053 static const char tag2[] = "zh-xiang-u-nu-thai-x-0";
3054 static const Locale expected2("hsn@numbers=thai;x=0");
3055 Locale result2 = Locale::forLanguageTag(tag2, status);
3056 status.errIfFailureAndReset("\"%s\"", tag2);
3057 assertEquals(tag2, expected2.getName(), result2.getName());
3058
3059 static const char locid3[] = "art__lojban@x=0";
3060 Locale result3 = Locale::createCanonical(locid3);
3061 static const Locale expected3("art__LOJBAN@x=0");
3062 assertEquals(locid3, expected3.getName(), result3.getName());
3063
3064 static const char locid4[] = "art-lojban-x-0";
3065 Locale result4 = Locale::createCanonical(locid4);
3066 static const Locale expected4("jbo@x=0");
3067 assertEquals(locid4, expected4.getName(), result4.getName());
3068 }
3069
3070 void LocaleTest::TestForLanguageTag() {
3071 IcuTestErrorCode status(*this, "TestForLanguageTag()");
3072
3073 static const char tag_en[] = "en-US";
3074 static const char tag_oed[] = "en-GB-oed";
3075 static const char tag_af[] = "af-t-ar-i0-handwrit-u-ca-coptic-x-foo";
3076 static const char tag_ill[] = "!";
3077 static const char tag_no_nul[] = { 'e', 'n', '-', 'G', 'B' };
3078 static const char tag_ext[] = "en-GB-1-abc-efg-a-xyz";
3079
3080 static const Locale loc_en("en_US");
3081 static const Locale loc_oed("en_GB_OXENDICT");
3082 static const Locale loc_af("af@calendar=coptic;t=ar-i0-handwrit;x=foo");
3083 static const Locale loc_null("");
3084 static const Locale loc_gb("en_GB");
3085 static const Locale loc_ext("en_GB@1=abc-efg;a=xyz");
3086
3087 Locale result_en = Locale::forLanguageTag(tag_en, status);
3088 status.errIfFailureAndReset("\"%s\"", tag_en);
3089 assertEquals(tag_en, loc_en.getName(), result_en.getName());
3090
3091 Locale result_oed = Locale::forLanguageTag(tag_oed, status);
3092 status.errIfFailureAndReset("\"%s\"", tag_oed);
3093 assertEquals(tag_oed, loc_oed.getName(), result_oed.getName());
3094
3095 Locale result_af = Locale::forLanguageTag(tag_af, status);
3096 status.errIfFailureAndReset("\"%s\"", tag_af);
3097 assertEquals(tag_af, loc_af.getName(), result_af.getName());
3098
3099 Locale result_ill = Locale::forLanguageTag(tag_ill, status);
3100 assertEquals(tag_ill, U_ILLEGAL_ARGUMENT_ERROR, status.reset());
3101 assertTrue(result_ill.getName(), result_ill.isBogus());
3102
3103 Locale result_null = Locale::forLanguageTag(nullptr, status);
3104 status.errIfFailureAndReset("nullptr");
3105 assertEquals("nullptr", loc_null.getName(), result_null.getName());
3106
3107 StringPiece sp_substr(tag_oed, 5); // "en-GB", no NUL.
3108 Locale result_substr = Locale::forLanguageTag(sp_substr, status);
3109 status.errIfFailureAndReset("\"%.*s\"", sp_substr.size(), sp_substr.data());
3110 assertEquals(CharString(sp_substr, status).data(),
3111 loc_gb.getName(), result_substr.getName());
3112
3113 StringPiece sp_no_nul(tag_no_nul, sizeof tag_no_nul); // "en-GB", no NUL.
3114 Locale result_no_nul = Locale::forLanguageTag(sp_no_nul, status);
3115 status.errIfFailureAndReset("\"%.*s\"", sp_no_nul.size(), sp_no_nul.data());
3116 assertEquals(CharString(sp_no_nul, status).data(),
3117 loc_gb.getName(), result_no_nul.getName());
3118
3119 Locale result_ext = Locale::forLanguageTag(tag_ext, status);
3120 status.errIfFailureAndReset("\"%s\"", tag_ext);
3121 assertEquals(tag_ext, loc_ext.getName(), result_ext.getName());
3122 }
3123
3124 void LocaleTest::TestToLanguageTag() {
3125 IcuTestErrorCode status(*this, "TestToLanguageTag()");
3126
3127 static const Locale loc_c("en_US_POSIX");
3128 static const Locale loc_en("en_US");
3129 static const Locale loc_af("af@calendar=coptic;t=ar-i0-handwrit;x=foo");
3130 static const Locale loc_ext("en@0=abc;a=xyz");
3131 static const Locale loc_empty("");
3132 static const Locale loc_ill("!");
3133
3134 static const char tag_c[] = "en-US-u-va-posix";
3135 static const char tag_en[] = "en-US";
3136 static const char tag_af[] = "af-t-ar-i0-handwrit-u-ca-coptic-x-foo";
3137 static const char tag_ext[] = "en-0-abc-a-xyz";
3138 static const char tag_und[] = "und";
3139
3140 std::string result;
3141 StringByteSink<std::string> sink(&result);
3142 loc_c.toLanguageTag(sink, status);
3143 status.errIfFailureAndReset("\"%s\"", loc_c.getName());
3144 assertEquals(loc_c.getName(), tag_c, result.c_str());
3145
3146 std::string result_c = loc_c.toLanguageTag<std::string>(status);
3147 status.errIfFailureAndReset("\"%s\"", loc_c.getName());
3148 assertEquals(loc_c.getName(), tag_c, result_c.c_str());
3149
3150 std::string result_en = loc_en.toLanguageTag<std::string>(status);
3151 status.errIfFailureAndReset("\"%s\"", loc_en.getName());
3152 assertEquals(loc_en.getName(), tag_en, result_en.c_str());
3153
3154 std::string result_af = loc_af.toLanguageTag<std::string>(status);
3155 status.errIfFailureAndReset("\"%s\"", loc_af.getName());
3156 assertEquals(loc_af.getName(), tag_af, result_af.c_str());
3157
3158 std::string result_ext = loc_ext.toLanguageTag<std::string>(status);
3159 status.errIfFailureAndReset("\"%s\"", loc_ext.getName());
3160 assertEquals(loc_ext.getName(), tag_ext, result_ext.c_str());
3161
3162 std::string result_empty = loc_empty.toLanguageTag<std::string>(status);
3163 status.errIfFailureAndReset("\"%s\"", loc_empty.getName());
3164 assertEquals(loc_empty.getName(), tag_und, result_empty.c_str());
3165
3166 std::string result_ill = loc_ill.toLanguageTag<std::string>(status);
3167 status.errIfFailureAndReset("\"%s\"", loc_ill.getName());
3168 assertEquals(loc_ill.getName(), tag_und, result_ill.c_str());
3169
3170 Locale loc_bogus;
3171 loc_bogus.setToBogus();
3172 std::string result_bogus = loc_bogus.toLanguageTag<std::string>(status);
3173 assertEquals("bogus", U_ILLEGAL_ARGUMENT_ERROR, status.reset());
3174 assertTrue(result_bogus.c_str(), result_bogus.empty());
3175 }
3176
3177 void LocaleTest::TestMoveAssign() {
3178 // ULOC_FULLNAME_CAPACITY == 157 (uloc.h)
3179 Locale l1("de@collation=phonebook;x="
3180 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3181 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3182 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3183 "aaaaabbbbbzz");
3184
3185 Locale l2;
3186 {
3187 Locale l3(l1);
3188 assertTrue("l1 == l3", l1 == l3);
3189 l2 = std::move(l3);
3190 assertTrue("l1 == l2", l1 == l2);
3191 assertTrue("l2 != l3", l2.getName() != l3.getName());
3192 }
3193
3194 // This should remain true also after l3 has been destructed.
3195 assertTrue("l1 == l2, again", l1 == l2);
3196
3197 Locale l4("de@collation=phonebook");
3198
3199 Locale l5;
3200 {
3201 Locale l6(l4);
3202 assertTrue("l4 == l6", l4 == l6);
3203 l5 = std::move(l6);
3204 assertTrue("l4 == l5", l4 == l5);
3205 assertTrue("l5 != l6", l5.getName() != l6.getName());
3206 }
3207
3208 // This should remain true also after l6 has been destructed.
3209 assertTrue("l4 == l5, again", l4 == l5);
3210
3211 Locale l7("vo_Cyrl_AQ_EURO");
3212
3213 Locale l8;
3214 {
3215 Locale l9(l7);
3216 assertTrue("l7 == l9", l7 == l9);
3217 l8 = std::move(l9);
3218 assertTrue("l7 == l8", l7 == l8);
3219 assertTrue("l8 != l9", l8.getName() != l9.getName());
3220 }
3221
3222 // This should remain true also after l9 has been destructed.
3223 assertTrue("l7 == l8, again", l7 == l8);
3224
3225 assertEquals("language", l7.getLanguage(), l8.getLanguage());
3226 assertEquals("script", l7.getScript(), l8.getScript());
3227 assertEquals("country", l7.getCountry(), l8.getCountry());
3228 assertEquals("variant", l7.getVariant(), l8.getVariant());
3229 assertEquals("bogus", l7.isBogus(), l8.isBogus());
3230 }
3231
3232 void LocaleTest::TestMoveCtor() {
3233 // ULOC_FULLNAME_CAPACITY == 157 (uloc.h)
3234 Locale l1("de@collation=phonebook;x="
3235 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3236 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3237 "aaaaabbbbbcccccdddddeeeeefffffggggghhhhh"
3238 "aaaaabbbbbzz");
3239
3240 Locale l3(l1);
3241 assertTrue("l1 == l3", l1 == l3);
3242 Locale l2(std::move(l3));
3243 assertTrue("l1 == l2", l1 == l2);
3244 assertTrue("l2 != l3", l2.getName() != l3.getName());
3245
3246 Locale l4("de@collation=phonebook");
3247
3248 Locale l6(l4);
3249 assertTrue("l4 == l6", l4 == l6);
3250 Locale l5(std::move(l6));
3251 assertTrue("l4 == l5", l4 == l5);
3252 assertTrue("l5 != l6", l5.getName() != l6.getName());
3253
3254 Locale l7("vo_Cyrl_AQ_EURO");
3255
3256 Locale l9(l7);
3257 assertTrue("l7 == l9", l7 == l9);
3258 Locale l8(std::move(l9));
3259 assertTrue("l7 == l8", l7 == l8);
3260 assertTrue("l8 != l9", l8.getName() != l9.getName());
3261
3262 assertEquals("language", l7.getLanguage(), l8.getLanguage());
3263 assertEquals("script", l7.getScript(), l8.getScript());
3264 assertEquals("country", l7.getCountry(), l8.getCountry());
3265 assertEquals("variant", l7.getVariant(), l8.getVariant());
3266 assertEquals("bogus", l7.isBogus(), l8.isBogus());
3267 }
3268
3269 void LocaleTest::TestBug20407iVariantPreferredValue() {
3270 IcuTestErrorCode status(*this, "TestBug20407iVariantPreferredValue()");
3271
3272 Locale l = Locale::forLanguageTag("hy-arevela", status);
3273 status.errIfFailureAndReset("hy-arevela fail");
3274 assertTrue("!l.isBogus()", !l.isBogus());
3275
3276 std::string result = l.toLanguageTag<std::string>(status);
3277 assertEquals(l.getName(), "hy", result.c_str());
3278
3279 l = Locale::forLanguageTag("hy-arevmda", status);
3280 status.errIfFailureAndReset("hy-arevmda");
3281 assertTrue("!l.isBogus()", !l.isBogus());
3282
3283 result = l.toLanguageTag<std::string>(status);
3284 assertEquals(l.getName(), "hyw", result.c_str());
3285 }
3286
3287 void LocaleTest::TestBug13417VeryLongLanguageTag() {
3288 IcuTestErrorCode status(*this, "TestBug13417VeryLongLanguageTag()");
3289
3290 static const char tag[] =
3291 "zh-x"
3292 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3293 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3294 "-foo-bar-baz-foo-bar-baz-foo-bar-baz-foo-bar-baz"
3295 "-foo-bar-baz-fxx"
3296 ;
3297
3298 Locale l = Locale::forLanguageTag(tag, status);
3299 status.errIfFailureAndReset("\"%s\"", tag);
3300 assertTrue("!l.isBogus()", !l.isBogus());
3301
3302 std::string result = l.toLanguageTag<std::string>(status);
3303 status.errIfFailureAndReset("\"%s\"", l.getName());
3304 assertEquals("equals", tag, result.c_str());
3305 }
3306
3307 void LocaleTest::TestBug11053UnderlineTimeZone() {
3308 static const char* const tz_in_ext[] = {
3309 "etadd",
3310 "tzdar",
3311 "eheai",
3312 "sttms",
3313 "arirj",
3314 "arrgl",
3315 "aruaq",
3316 "arluq",
3317 "mxpvr",
3318 "brbvb",
3319 "arbue",
3320 "caycb",
3321 "brcgr",
3322 "cayzs",
3323 "crsjo",
3324 "caydq",
3325 "svsal",
3326 "cafne",
3327 "caglb",
3328 "cagoo",
3329 "tcgdt",
3330 "ustel",
3331 "bolpb",
3332 "uslax",
3333 "sxphi",
3334 "mxmex",
3335 "usnyc",
3336 "usxul",
3337 "usndcnt",
3338 "usndnsl",
3339 "ttpos",
3340 "brpvh",
3341 "prsju",
3342 "clpuq",
3343 "caffs",
3344 "cayek",
3345 "brrbr",
3346 "mxstis",
3347 "dosdq",
3348 "brsao",
3349 "gpsbh",
3350 "casjf",
3351 "knbas",
3352 "lccas",
3353 "vistt",
3354 "vcsvd",
3355 "cayyn",
3356 "cathu",
3357 "hkhkg",
3358 "mykul",
3359 "khpnh",
3360 "cvrai",
3361 "gsgrv",
3362 "shshn",
3363 "aubhq",
3364 "auldh",
3365 "imdgs",
3366 "smsai",
3367 "asppg",
3368 "pgpom",
3369 };
3370 static const char* const tzname_with_underline[] = {
3371 "America/Buenos_Aires",
3372 "America/Coral_Harbour",
3373 "America/Los_Angeles",
3374 "America/Mexico_City",
3375 "America/New_York",
3376 "America/Rio_Branco",
3377 "America/Sao_Paulo",
3378 "America/St_Johns",
3379 "America/St_Thomas",
3380 "Australia/Broken_Hill",
3381 "Australia/Lord_Howe",
3382 "Pacific/Pago_Pago",
3383 };
3384 std::string locale_str;
3385 for (int32_t i = 0; i < UPRV_LENGTHOF(tz_in_ext); i++) {
3386 locale_str = "en-u-tz-";
3387 locale_str += tz_in_ext[i];
3388 Locale l(locale_str.c_str());
3389 assertTrue((locale_str + " !l.isBogus()").c_str(), !l.isBogus());
3390 }
3391 for (int32_t i = 0; i < UPRV_LENGTHOF(tzname_with_underline); i++) {
3392 locale_str = "en@timezone=";
3393 locale_str += tzname_with_underline[i];
3394 Locale l(locale_str.c_str());
3395 assertTrue((locale_str + " !l.isBogus()").c_str(), !l.isBogus());
3396 }
3397 locale_str = "en_US@timezone=America/Coral_Harbour";
3398 Locale l2(locale_str.c_str());
3399 assertTrue((locale_str + " !l2.isBogus()").c_str(), !l2.isBogus());
3400 locale_str = "en_Latn@timezone=America/New_York";
3401 Locale l3(locale_str.c_str());
3402 assertTrue((locale_str + " !l3.isBogus()").c_str(), !l3.isBogus());
3403 locale_str = "en_Latn_US@timezone=Australia/Broken_Hill";
3404 Locale l4(locale_str.c_str());
3405 assertTrue((locale_str + " !l4.isBogus()").c_str(), !l4.isBogus());
3406 locale_str = "en-u-tz-ciabj";
3407 Locale l5(locale_str.c_str());
3408 assertTrue((locale_str + " !l5.isBogus()").c_str(), !l5.isBogus());
3409 locale_str = "en-US-u-tz-asppg";
3410 Locale l6(locale_str.c_str());
3411 assertTrue((locale_str + " !l6.isBogus()").c_str(), !l6.isBogus());
3412 locale_str = "fil-Latn-u-tz-cvrai";
3413 Locale l7(locale_str.c_str());
3414 assertTrue((locale_str + " !l7.isBogus()").c_str(), !l7.isBogus());
3415 locale_str = "fil-Latn-PH-u-tz-gsgrv";
3416 Locale l8(locale_str.c_str());
3417 assertTrue((locale_str + " !l8.isBogus()").c_str(), !l8.isBogus());
3418 }
3419
3420 void LocaleTest::TestUnd() {
3421 IcuTestErrorCode status(*this, "TestUnd()");
3422
3423 static const char empty[] = "";
3424 static const char root[] = "root";
3425 static const char und[] = "und";
3426
3427 Locale empty_ctor(empty);
3428 Locale empty_tag = Locale::forLanguageTag(empty, status);
3429 status.errIfFailureAndReset("\"%s\"", empty);
3430
3431 Locale root_ctor(root);
3432 Locale root_tag = Locale::forLanguageTag(root, status);
3433 Locale root_build = LocaleBuilder().setLanguageTag(root).build(status);
3434 status.errIfFailureAndReset("\"%s\"", root);
3435
3436 Locale und_ctor(und);
3437 Locale und_tag = Locale::forLanguageTag(und, status);
3438 Locale und_build = LocaleBuilder().setLanguageTag(und).build(status);
3439 status.errIfFailureAndReset("\"%s\"", und);
3440
3441 assertEquals("getName() 1", empty, empty_ctor.getName());
3442 assertEquals("getName() 2", root, root_ctor.getName()); // open ICU expects empty
3443 assertEquals("getName() 3", und, und_ctor.getName()); // open ICU expects empty
3444
3445 assertEquals("getName() 4", empty, empty_tag.getName());
3446 assertEquals("getName() 5", root, root_tag.getName()); // open ICU expects empty
3447 assertEquals("getName() 6", empty, und_tag.getName());
3448
3449 assertEquals("getName() 7", root, root_build.getName()); // open ICU expects empty
3450 assertEquals("getName() 8", empty, und_build.getName());
3451
3452 assertEquals("toLanguageTag() 1", und, empty_ctor.toLanguageTag<std::string>(status).c_str());
3453 assertEquals("toLanguageTag() 2", root, root_ctor.toLanguageTag<std::string>(status).c_str()); // open ICU expects und
3454 assertEquals("toLanguageTag() 3", und, und_ctor.toLanguageTag<std::string>(status).c_str());
3455 status.errIfFailureAndReset();
3456
3457 assertEquals("toLanguageTag() 4", und, empty_tag.toLanguageTag<std::string>(status).c_str());
3458 assertEquals("toLanguageTag() 5", root, root_tag.toLanguageTag<std::string>(status).c_str()); // open ICU expects und
3459 assertEquals("toLanguageTag() 6", und, und_tag.toLanguageTag<std::string>(status).c_str());
3460 status.errIfFailureAndReset();
3461
3462 assertEquals("toLanguageTag() 7", root, root_build.toLanguageTag<std::string>(status).c_str()); // open ICU expects und
3463 assertEquals("toLanguageTag() 8", und, und_build.toLanguageTag<std::string>(status).c_str());
3464 status.errIfFailureAndReset();
3465
3466 assertTrue("empty_ctor == empty_tag", empty_ctor == empty_tag);
3467
3468 assertTrue("root_ctor == root_tag", root_ctor == root_tag);
3469 assertTrue("root_ctor == root_build", root_ctor == root_build);
3470 assertTrue("root_tag == root_build", root_tag == root_build);
3471
3472 //assertTrue("und_ctor == und_tag", und_ctor == und_tag); // change from open ICU
3473 //assertTrue("und_ctor == und_build", und_ctor == und_build); // change from open ICU
3474 assertTrue("und_tag == und_build", und_tag == und_build);
3475
3476 //assertTrue("empty_ctor == root_ctor", empty_ctor == root_ctor); // change from open ICU
3477 //assertTrue("empty_ctor == und_ctor", empty_ctor == und_ctor); // change from open ICU
3478 //assertTrue("root_ctor == und_ctor", root_ctor == und_ctor); // change from open ICU
3479
3480 //assertTrue("empty_tag == root_tag", empty_tag == root_tag); // change from open ICU
3481 assertTrue("empty_tag == und_tag", empty_tag == und_tag);
3482 //assertTrue("root_tag == und_tag", root_tag == und_tag); // change from open ICU
3483
3484 //assertTrue("root_build == und_build", root_build == und_build); // change from open ICU
3485
3486 static const Locale& displayLocale = Locale::getEnglish();
3487 static const UnicodeString displayName("Unknown language");
3488 static const UnicodeString displayRoot("Root");
3489 static const UnicodeString displayEmpty("");
3490 UnicodeString tmp;
3491
3492 assertEquals("getDisplayName() 1", displayEmpty, empty_ctor.getDisplayName(displayLocale, tmp)); // change from open ICU
3493 assertEquals("getDisplayName() 2", displayRoot, root_ctor.getDisplayName(displayLocale, tmp)); // change from open ICU
3494 assertEquals("getDisplayName() 3", displayName, und_ctor.getDisplayName(displayLocale, tmp));
3495
3496 assertEquals("getDisplayName() 4", displayEmpty, empty_tag.getDisplayName(displayLocale, tmp)); // change from open ICU
3497 assertEquals("getDisplayName() 5", displayRoot, root_tag.getDisplayName(displayLocale, tmp)); // change from open ICU
3498 assertEquals("getDisplayName() 6", displayEmpty, und_tag.getDisplayName(displayLocale, tmp)); // change from open ICU
3499
3500 assertEquals("getDisplayName() 7", displayRoot, root_build.getDisplayName(displayLocale, tmp)); // change from open ICU
3501 assertEquals("getDisplayName() 8", displayEmpty, und_build.getDisplayName(displayLocale, tmp)); // change from open ICU
3502 }
3503
3504 void LocaleTest::TestUndScript() {
3505 IcuTestErrorCode status(*this, "TestUndScript()");
3506
3507 static const char id[] = "_Cyrl";
3508 static const char tag[] = "und-Cyrl";
3509 static const char script[] = "Cyrl";
3510 static const char tag_[] = "und_Cyrl";
3511
3512 Locale locale_ctor(id);
3513 Locale locale_legacy(tag);
3514 Locale locale_tag = Locale::forLanguageTag(tag, status);
3515 Locale locale_build = LocaleBuilder().setScript(script).build(status);
3516 status.errIfFailureAndReset("\"%s\"", tag);
3517
3518 assertEquals("getName() 1", id, locale_ctor.getName());
3519 assertEquals("getName() 2", tag_, locale_legacy.getName()); // change from open ICU
3520 assertEquals("getName() 3", id, locale_tag.getName());
3521 assertEquals("getName() 4", id, locale_build.getName());
3522
3523 assertEquals("toLanguageTag()", tag, locale_ctor.toLanguageTag<std::string>(status).c_str());
3524 assertEquals("toLanguageTag()", tag, locale_legacy.toLanguageTag<std::string>(status).c_str());
3525 assertEquals("toLanguageTag()", tag, locale_tag.toLanguageTag<std::string>(status).c_str());
3526 assertEquals("toLanguageTag()", tag, locale_build.toLanguageTag<std::string>(status).c_str());
3527 status.errIfFailureAndReset();
3528
3529 static const Locale& displayLocale = Locale::getEnglish();
3530 static const UnicodeString displayName("Unknown language (Cyrillic)");
3531 static const UnicodeString displayScript("Cyrillic");
3532 UnicodeString tmp;
3533
3534 assertEquals("getDisplayName() 1", displayScript, locale_ctor.getDisplayName(displayLocale, tmp)); // change from open-source
3535 assertEquals("getDisplayName() 2", displayName, locale_legacy.getDisplayName(displayLocale, tmp));
3536 assertEquals("getDisplayName() 3", displayScript, locale_tag.getDisplayName(displayLocale, tmp)); // change from open-source
3537 assertEquals("getDisplayName() 4", displayScript, locale_build.getDisplayName(displayLocale, tmp)); // change from open-source
3538 }
3539
3540 void LocaleTest::TestUndRegion() {
3541 IcuTestErrorCode status(*this, "TestUndRegion()");
3542
3543 static const char id[] = "_AQ";
3544 static const char tag[] = "und-AQ";
3545 static const char region[] = "AQ";
3546 static const char tag_[] = "und_AQ";
3547
3548 Locale locale_ctor(id);
3549 Locale locale_legacy(tag);
3550 Locale locale_tag = Locale::forLanguageTag(tag, status);
3551 Locale locale_build = LocaleBuilder().setRegion(region).build(status);
3552 status.errIfFailureAndReset("\"%s\"", tag);
3553
3554 assertEquals("getName() 1", id, locale_ctor.getName());
3555 assertEquals("getName() 2", tag_, locale_legacy.getName()); // change from open ICU
3556 assertEquals("getName() 3", id, locale_tag.getName());
3557 assertEquals("getName() 4", id, locale_build.getName());
3558
3559 assertEquals("toLanguageTag()", tag, locale_ctor.toLanguageTag<std::string>(status).c_str());
3560 assertEquals("toLanguageTag()", tag, locale_legacy.toLanguageTag<std::string>(status).c_str());
3561 assertEquals("toLanguageTag()", tag, locale_tag.toLanguageTag<std::string>(status).c_str());
3562 assertEquals("toLanguageTag()", tag, locale_build.toLanguageTag<std::string>(status).c_str());
3563 status.errIfFailureAndReset();
3564
3565 static const Locale& displayLocale = Locale::getEnglish();
3566 static const UnicodeString displayName("Unknown language (Antarctica)");
3567 static const UnicodeString displayRegion("Antarctica");
3568 UnicodeString tmp;
3569
3570 assertEquals("getDisplayName() 1", displayRegion, locale_ctor.getDisplayName(displayLocale, tmp)); // change from open-source
3571 assertEquals("getDisplayName() 2", displayName, locale_legacy.getDisplayName(displayLocale, tmp));
3572 assertEquals("getDisplayName() 3", displayRegion, locale_tag.getDisplayName(displayLocale, tmp)); // change from open-source
3573 assertEquals("getDisplayName() 4", displayRegion, locale_build.getDisplayName(displayLocale, tmp)); // change from open-source
3574 }
3575
3576 void LocaleTest::TestUndCAPI() {
3577 IcuTestErrorCode status(*this, "TestUndCAPI()");
3578
3579 static const char empty[] = "";
3580 static const char root[] = "root";
3581 static const char und[] = "und";
3582
3583 static const char empty_script[] = "_Cyrl";
3584 static const char empty_region[] = "_AQ";
3585
3586 static const char und_script[] = "und_Cyrl";
3587 static const char und_region[] = "und_AQ";
3588
3589 char tmp[ULOC_FULLNAME_CAPACITY];
3590 int32_t reslen;
3591
3592 // uloc_getName()
3593
3594 uprv_memset(tmp, '!', sizeof tmp);
3595 reslen = uloc_getName(empty, tmp, sizeof tmp, status);
3596 status.errIfFailureAndReset("\"%s\"", empty);
3597 assertTrue("reslen >= 0", reslen >= 0);
3598 assertEquals("uloc_getName() 1", empty, tmp);
3599
3600 uprv_memset(tmp, '!', sizeof tmp);
3601 reslen = uloc_getName(root, tmp, sizeof tmp, status);
3602 status.errIfFailureAndReset("\"%s\"", root);
3603 assertTrue("reslen >= 0", reslen >= 0);
3604 assertEquals("uloc_getName() 2", root, tmp); // change from open ICU
3605
3606 uprv_memset(tmp, '!', sizeof tmp);
3607 reslen = uloc_getName(und, tmp, sizeof tmp, status);
3608 status.errIfFailureAndReset("\"%s\"", und);
3609 assertTrue("reslen >= 0", reslen >= 0);
3610 assertEquals("uloc_getName() 3", und, tmp); // change from open ICU
3611
3612 uprv_memset(tmp, '!', sizeof tmp);
3613 reslen = uloc_getName(empty_script, tmp, sizeof tmp, status);
3614 status.errIfFailureAndReset("\"%s\"", empty_script);
3615 assertTrue("reslen >= 0", reslen >= 0);
3616 assertEquals("uloc_getName() 4", empty_script, tmp);
3617
3618 uprv_memset(tmp, '!', sizeof tmp);
3619 reslen = uloc_getName(empty_region, tmp, sizeof tmp, status);
3620 status.errIfFailureAndReset("\"%s\"", empty_region);
3621 assertTrue("reslen >= 0", reslen >= 0);
3622 assertEquals("uloc_getName() 5", empty_region, tmp);
3623
3624 uprv_memset(tmp, '!', sizeof tmp);
3625 reslen = uloc_getName(und_script, tmp, sizeof tmp, status);
3626 status.errIfFailureAndReset("\"%s\"", und_script);
3627 assertTrue("reslen >= 0", reslen >= 0);
3628 assertEquals("uloc_getName() 6", und_script, tmp); // change from open ICU
3629
3630 uprv_memset(tmp, '!', sizeof tmp);
3631 reslen = uloc_getName(und_region, tmp, sizeof tmp, status);
3632 status.errIfFailureAndReset("\"%s\"", und_region);
3633 assertTrue("reslen >= 0", reslen >= 0);
3634 assertEquals("uloc_getName() 7", und_region, tmp); // change from open ICU
3635
3636 // uloc_getBaseName()
3637
3638 uprv_memset(tmp, '!', sizeof tmp);
3639 reslen = uloc_getBaseName(empty, tmp, sizeof tmp, status);
3640 status.errIfFailureAndReset("\"%s\"", empty);
3641 assertTrue("reslen >= 0", reslen >= 0);
3642 assertEquals("uloc_getBaseName() 1", empty, tmp);
3643
3644 uprv_memset(tmp, '!', sizeof tmp);
3645 reslen = uloc_getBaseName(root, tmp, sizeof tmp, status);
3646 status.errIfFailureAndReset("\"%s\"", root);
3647 assertTrue("reslen >= 0", reslen >= 0);
3648 assertEquals("uloc_getBaseName() 2", root, tmp); // change from open ICU
3649
3650 uprv_memset(tmp, '!', sizeof tmp);
3651 reslen = uloc_getBaseName(und, tmp, sizeof tmp, status);
3652 status.errIfFailureAndReset("\"%s\"", und);
3653 assertTrue("reslen >= 0", reslen >= 0);
3654 assertEquals("uloc_getBaseName() 3", und, tmp); // change from open ICU
3655
3656 uprv_memset(tmp, '!', sizeof tmp);
3657 reslen = uloc_getBaseName(empty_script, tmp, sizeof tmp, status);
3658 status.errIfFailureAndReset("\"%s\"", empty_script);
3659 assertTrue("reslen >= 0", reslen >= 0);
3660 assertEquals("uloc_getBaseName() 4", empty_script, tmp);
3661
3662 uprv_memset(tmp, '!', sizeof tmp);
3663 reslen = uloc_getBaseName(empty_region, tmp, sizeof tmp, status);
3664 status.errIfFailureAndReset("\"%s\"", empty_region);
3665 assertTrue("reslen >= 0", reslen >= 0);
3666 assertEquals("uloc_getBaseName() 5", empty_region, tmp);
3667
3668 uprv_memset(tmp, '!', sizeof tmp);
3669 reslen = uloc_getBaseName(und_script, tmp, sizeof tmp, status);
3670 status.errIfFailureAndReset("\"%s\"", und_script);
3671 assertTrue("reslen >= 0", reslen >= 0);
3672 assertEquals("uloc_getBaseName() 6", und_script, tmp); // change from open ICU
3673
3674 uprv_memset(tmp, '!', sizeof tmp);
3675 reslen = uloc_getBaseName(und_region, tmp, sizeof tmp, status);
3676 status.errIfFailureAndReset("\"%s\"", und_region);
3677 assertTrue("reslen >= 0", reslen >= 0);
3678 assertEquals("uloc_getBaseName() 7", und_region, tmp); // change from open ICU
3679
3680 // uloc_getParent()
3681
3682 uprv_memset(tmp, '!', sizeof tmp);
3683 reslen = uloc_getParent(empty, tmp, sizeof tmp, status);
3684 status.errIfFailureAndReset("\"%s\"", empty);
3685 assertTrue("reslen >= 0", reslen >= 0);
3686 assertEquals("uloc_getParent() 1", empty, tmp);
3687
3688 uprv_memset(tmp, '!', sizeof tmp);
3689 reslen = uloc_getParent(root, tmp, sizeof tmp, status);
3690 status.errIfFailureAndReset("\"%s\"", root);
3691 assertTrue("reslen >= 0", reslen >= 0);
3692 assertEquals("uloc_getParent() 2", empty, tmp);
3693
3694 uprv_memset(tmp, '!', sizeof tmp);
3695 reslen = uloc_getParent(und, tmp, sizeof tmp, status);
3696 status.errIfFailureAndReset("\"%s\"", und);
3697 assertTrue("reslen >= 0", reslen >= 0);
3698 assertEquals("uloc_getParent() 3", empty, tmp);
3699
3700 uprv_memset(tmp, '!', sizeof tmp);
3701 reslen = uloc_getParent(empty_script, tmp, sizeof tmp, status);
3702 status.errIfFailureAndReset("\"%s\"", empty_script);
3703 assertTrue("reslen >= 0", reslen >= 0);
3704 assertEquals("uloc_getParent() 4", empty, tmp);
3705
3706 uprv_memset(tmp, '!', sizeof tmp);
3707 reslen = uloc_getParent(empty_region, tmp, sizeof tmp, status);
3708 status.errIfFailureAndReset("\"%s\"", empty_region);
3709 assertTrue("reslen >= 0", reslen >= 0);
3710 assertEquals("uloc_getParent() 5", empty, tmp);
3711
3712 uprv_memset(tmp, '!', sizeof tmp);
3713 reslen = uloc_getParent(und_script, tmp, sizeof tmp, status);
3714 status.errIfFailureAndReset("\"%s\"", und_script);
3715 assertTrue("reslen >= 0", reslen >= 0);
3716 assertEquals("uloc_getParent() 6", und, tmp); // change from open ICU
3717
3718 uprv_memset(tmp, '!', sizeof tmp);
3719 reslen = uloc_getParent(und_region, tmp, sizeof tmp, status);
3720 status.errIfFailureAndReset("\"%s\"", und_region);
3721 assertTrue("reslen >= 0", reslen >= 0);
3722 assertEquals("uloc_getParent() 7", und, tmp); // change from open ICU
3723
3724 // uloc_getLanguage()
3725
3726 uprv_memset(tmp, '!', sizeof tmp);
3727 reslen = uloc_getLanguage(empty, tmp, sizeof tmp, status);
3728 status.errIfFailureAndReset("\"%s\"", empty);
3729 assertTrue("reslen >= 0", reslen >= 0);
3730 assertEquals("uloc_getLanguage() 1", empty, tmp);
3731
3732 uprv_memset(tmp, '!', sizeof tmp);
3733 reslen = uloc_getLanguage(root, tmp, sizeof tmp, status);
3734 status.errIfFailureAndReset("\"%s\"", root);
3735 assertTrue("reslen >= 0", reslen >= 0);
3736 assertEquals("uloc_getLanguage() 2", root, tmp); // change from open ICU
3737
3738 uprv_memset(tmp, '!', sizeof tmp);
3739 reslen = uloc_getLanguage(und, tmp, sizeof tmp, status);
3740 status.errIfFailureAndReset("\"%s\"", und);
3741 assertTrue("reslen >= 0", reslen >= 0);
3742 assertEquals("uloc_getLanguage() 3", und, tmp); // change from open ICU
3743
3744 uprv_memset(tmp, '!', sizeof tmp);
3745 reslen = uloc_getLanguage(empty_script, tmp, sizeof tmp, status);
3746 status.errIfFailureAndReset("\"%s\"", empty_script);
3747 assertTrue("reslen >= 0", reslen >= 0);
3748 assertEquals("uloc_getLanguage() 4", empty, tmp);
3749
3750 uprv_memset(tmp, '!', sizeof tmp);
3751 reslen = uloc_getLanguage(empty_region, tmp, sizeof tmp, status);
3752 status.errIfFailureAndReset("\"%s\"", empty_region);
3753 assertTrue("reslen >= 0", reslen >= 0);
3754 assertEquals("uloc_getLanguage() 5", empty, tmp);
3755
3756 uprv_memset(tmp, '!', sizeof tmp);
3757 reslen = uloc_getLanguage(und_script, tmp, sizeof tmp, status);
3758 status.errIfFailureAndReset("\"%s\"", und_script);
3759 assertTrue("reslen >= 0", reslen >= 0);
3760 assertEquals("uloc_getLanguage() 6", und, tmp); // change from open ICU
3761
3762 uprv_memset(tmp, '!', sizeof tmp);
3763 reslen = uloc_getLanguage(und_region, tmp, sizeof tmp, status);
3764 status.errIfFailureAndReset("\"%s\"", und_region);
3765 assertTrue("reslen >= 0", reslen >= 0);
3766 assertEquals("uloc_getLanguage() 7", und, tmp); // change from open ICU
3767 }