OLD | NEW |
| (Empty) |
1 /******************************************************************** | |
2 * COPYRIGHT: | |
3 * Copyright (c) 1997-2015, International Business Machines Corporation and | |
4 * others. All Rights Reserved. | |
5 ********************************************************************/ | |
6 | |
7 #include "loctest.h" | |
8 #include "unicode/decimfmt.h" | |
9 #include "unicode/ucurr.h" | |
10 #include "unicode/smpdtfmt.h" | |
11 #include "unicode/dtfmtsym.h" | |
12 #include "unicode/brkiter.h" | |
13 #include "unicode/coll.h" | |
14 #include "cstring.h" | |
15 #include <stdio.h> | |
16 #include <string.h> | |
17 #include "putilimp.h" | |
18 #include "unicode/ustring.h" | |
19 #include "hash.h" | |
20 | |
21 static const char* const rawData[33][8] = { | |
22 | |
23 // language code | |
24 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" }, | |
25 // script code | |
26 { "", "", "", "", "", "", "", "Hans" }, | |
27 // country code | |
28 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" }, | |
29 // variant code | |
30 { "", "", "", "", "NY", "", "", "" }, | |
31 // full name | |
32 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it",
"xx_YY", "zh_Hans_CN" }, | |
33 // ISO-3 language | |
34 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" }, | |
35 // ISO-3 country | |
36 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" }, | |
37 // LCID | |
38 { "409", "40c", "403", "408", "814", "10", "0", "804" }, | |
39 | |
40 // display langage (English) | |
41 { "English", "French", "Catalan", "Greek", "Norwegian", "Ital
ian", "xx", "Chinese" }, | |
42 // display script (English) | |
43 { "", "", "", "", "", "", "", "Simplified Han"
}, | |
44 // display country (English) | |
45 { "United States", "France", "Spain", "Greece", "Norway", ""
, "YY", "China" }, | |
46 // display variant (English) | |
47 { "", "", "", "", "NY", "", "", ""}, | |
48 // display name (English) | |
49 // Updated no_NO_NY English display name for new pattern-based algorithm | |
50 // (part of Euro support). | |
51 { "English (United States)", "French (France)", "Catalan (Spain)", "Gr
eek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplif
ied, China)" }, | |
52 | |
53 // display langage (French) | |
54 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gi
en", "italien", "xx", "chinois" }, | |
55 // display script (French) | |
56 { "", "", "", "", "", "", "", "sinogrammes s
implifi\\u00E9s" }, | |
57 // display country (French) | |
58 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Nor
v\\u00E8ge", "", "YY", "Chine" }, | |
59 // display variant (French) | |
60 { "", "", "", "", "NY", "", "", "" }, | |
61 // display name (French) | |
62 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)",
"grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" }, | |
63 { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (E
spagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "italien"
, "xx (YY)", "chinois (simplifi\\u00E9, Chine)" }, | |
64 | |
65 | |
66 /* display language (Catalan) */ | |
67 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec",
"itali\\u00E0", "", "xin\\u00E8s" }, | |
68 /* display script (Catalan) */ | |
69 { "", "", "", "", "", "", "", "han simplificat" }, | |
70 /* display country (Catalan) */ | |
71 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega
", "", "", "Xina" }, | |
72 /* display variant (Catalan) */ | |
73 { "", "", "", "", "NY", "", "" }, | |
74 /* display name (Catalan) */ | |
75 { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "cata
l\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "itali\\u00E
0", "", "xin\\u00E8s (simplificat, Xina)" }, | |
76 | |
77 // display langage (Greek)[actual values listed below] | |
78 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac", | |
79 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac", | |
80 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u0
3ac", | |
81 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac", | |
82 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac", | |
83 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac", | |
84 "", | |
85 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC" | |
86 }, | |
87 // display script (Greek) | |
88 { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u0
3bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u03a7\\u03b1\\u03bd" }, | |
89 // display country (Greek)[actual values listed below] | |
90 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u
03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2", | |
91 "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1", | |
92 "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1", | |
93 "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1", | |
94 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1", | |
95 "", | |
96 "", | |
97 "\\u039A\\u03AF\\u03BD\\u03B1" | |
98 }, | |
99 // display variant (Greek) | |
100 { "", "", "", "", "NY", "", "" }, | |
101 // display name (Greek)[actual values listed below] | |
102 { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03BD\\
u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u0
3B5\\u03AF\\u03B5\\u03C2)", | |
103 "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\
u03bb\\u03bb\\u03af\\u03b1)", | |
104 "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u0
3ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)", | |
105 "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\
u03bb\\u03bb\\u03ac\\u03b4\\u03b1)", | |
106 "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\
u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)", | |
107 "\\u0399\\u03c4\\u03b1\\u03bb\\u03b9\\u03ba\\u03ac", | |
108 "", | |
109 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\
u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf, \\u
039A\\u03AF\\u03BD\\u03B1)" | |
110 }, | |
111 | |
112 // display langage (<root>) | |
113 { "English", "French", "Catalan", "Greek", "Norwegian", "Ital
ian", "xx", "" }, | |
114 // display script (<root>) | |
115 { "", "", "", "", "", "", "", ""}, | |
116 // display country (<root>) | |
117 { "United States", "France", "Spain", "Greece", "Norway", ""
, "YY", "" }, | |
118 // display variant (<root>) | |
119 { "", "", "", "", "Nynorsk", "", "", ""}, | |
120 // display name (<root>) | |
121 //{ "English (United States)", "French (France)", "Catalan (Spain)", "
Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" }, | |
122 { "English (United States)", "French (France)", "Catalan (Spain)", "Gr
eek (Greece)", "Norwegian (Norway,NY)", "Italian", "xx (YY)", "" } | |
123 }; | |
124 | |
125 | |
126 /* | |
127 Usage: | |
128 test_assert( Test (should be TRUE) ) | |
129 | |
130 Example: | |
131 test_assert(i==3); | |
132 | |
133 the macro is ugly but makes the tests pretty. | |
134 */ | |
135 | |
136 #define test_assert(test) \ | |
137 { \ | |
138 if(!(test)) \ | |
139 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __
LINE__ ); \ | |
140 else \ | |
141 logln("PASS: asserted " #test); \ | |
142 } | |
143 | |
144 /* | |
145 Usage: | |
146 test_assert_print( Test (should be TRUE), printable ) | |
147 | |
148 Example: | |
149 test_assert(i==3, toString(i)); | |
150 | |
151 the macro is ugly but makes the tests pretty. | |
152 */ | |
153 | |
154 #define test_assert_print(test,print) \ | |
155 { \ | |
156 if(!(test)) \ | |
157 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \ | |
158 else \ | |
159 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \ | |
160 } | |
161 | |
162 | |
163 #define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); } | |
164 | |
165 LocaleTest::LocaleTest() | |
166 : dataTable(NULL) | |
167 { | |
168 setUpDataTable(); | |
169 } | |
170 | |
171 LocaleTest::~LocaleTest() | |
172 { | |
173 if (dataTable != 0) { | |
174 for (int32_t i = 0; i < 33; i++) { | |
175 delete []dataTable[i]; | |
176 } | |
177 delete []dataTable; | |
178 dataTable = 0; | |
179 } | |
180 } | |
181 | |
182 void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, c
har* /*par*/ ) | |
183 { | |
184 TESTCASE_AUTO_BEGIN; | |
185 TESTCASE_AUTO(TestBug11421); // Must run early in list to trigger fa
ilure. | |
186 TESTCASE_AUTO(TestBasicGetters); | |
187 TESTCASE_AUTO(TestSimpleResourceInfo); | |
188 TESTCASE_AUTO(TestDisplayNames); | |
189 TESTCASE_AUTO(TestSimpleObjectStuff); | |
190 TESTCASE_AUTO(TestPOSIXParsing); | |
191 TESTCASE_AUTO(TestGetAvailableLocales); | |
192 TESTCASE_AUTO(TestDataDirectory); | |
193 TESTCASE_AUTO(TestISO3Fallback); | |
194 TESTCASE_AUTO(TestGetLangsAndCountries); | |
195 TESTCASE_AUTO(TestSimpleDisplayNames); | |
196 TESTCASE_AUTO(TestUninstalledISO3Names); | |
197 TESTCASE_AUTO(TestAtypicalLocales); | |
198 #if !UCONFIG_NO_FORMATTING | |
199 TESTCASE_AUTO(TestThaiCurrencyFormat); | |
200 TESTCASE_AUTO(TestEuroSupport); | |
201 #endif | |
202 TESTCASE_AUTO(TestToString); | |
203 #if !UCONFIG_NO_FORMATTING | |
204 TESTCASE_AUTO(Test4139940); | |
205 TESTCASE_AUTO(Test4143951); | |
206 #endif | |
207 TESTCASE_AUTO(Test4147315); | |
208 TESTCASE_AUTO(Test4147317); | |
209 TESTCASE_AUTO(Test4147552); | |
210 TESTCASE_AUTO(TestVariantParsing); | |
211 #if !UCONFIG_NO_FORMATTING | |
212 TESTCASE_AUTO(Test4105828); | |
213 #endif | |
214 TESTCASE_AUTO(TestSetIsBogus); | |
215 TESTCASE_AUTO(TestParallelAPIValues); | |
216 TESTCASE_AUTO(TestKeywordVariants); | |
217 TESTCASE_AUTO(TestKeywordVariantParsing); | |
218 TESTCASE_AUTO(TestSetKeywordValue); | |
219 TESTCASE_AUTO(TestGetBaseName); | |
220 #if !UCONFIG_NO_FILE_IO | |
221 TESTCASE_AUTO(TestGetLocale); | |
222 #endif | |
223 TESTCASE_AUTO(TestVariantWithOutCountry); | |
224 TESTCASE_AUTO(TestCanonicalization); | |
225 TESTCASE_AUTO(TestCurrencyByDate); | |
226 TESTCASE_AUTO(TestGetVariantWithKeywords); | |
227 TESTCASE_AUTO(TestIsRightToLeft); | |
228 TESTCASE_AUTO_END; | |
229 } | |
230 | |
231 void LocaleTest::TestBasicGetters() { | |
232 UnicodeString temp; | |
233 | |
234 int32_t i; | |
235 for (i = 0; i <= MAX_LOCALES; i++) { | |
236 Locale testLocale(""); | |
237 if (rawData[SCRIPT][i] && rawData[SCRIPT][i][0] != 0) { | |
238 testLocale = Locale(rawData[LANG][i], rawData[SCRIPT][i], rawData[CT
RY][i], rawData[VAR][i]); | |
239 } | |
240 else { | |
241 testLocale = Locale(rawData[LANG][i], rawData[CTRY][i], rawData[VAR]
[i]); | |
242 } | |
243 logln("Testing " + (UnicodeString)testLocale.getName() + "..."); | |
244 | |
245 if ( (temp=testLocale.getLanguage()) != (dataTable[LANG][i])) | |
246 errln(" Language code mismatch: " + temp + " versus " | |
247 + dataTable[LANG][i]); | |
248 if ( (temp=testLocale.getScript()) != (dataTable[SCRIPT][i])) | |
249 errln(" Script code mismatch: " + temp + " versus " | |
250 + dataTable[SCRIPT][i]); | |
251 if ( (temp=testLocale.getCountry()) != (dataTable[CTRY][i])) | |
252 errln(" Country code mismatch: " + temp + " versus " | |
253 + dataTable[CTRY][i]); | |
254 if ( (temp=testLocale.getVariant()) != (dataTable[VAR][i])) | |
255 errln(" Variant code mismatch: " + temp + " versus " | |
256 + dataTable[VAR][i]); | |
257 if ( (temp=testLocale.getName()) != (dataTable[NAME][i])) | |
258 errln(" Locale name mismatch: " + temp + " versus " | |
259 + dataTable[NAME][i]); | |
260 } | |
261 | |
262 logln("Same thing without variant codes..."); | |
263 for (i = 0; i <= MAX_LOCALES; i++) { | |
264 Locale testLocale(""); | |
265 if (rawData[SCRIPT][i] && rawData[SCRIPT][i][0] != 0) { | |
266 testLocale = Locale(rawData[LANG][i], rawData[SCRIPT][i], rawData[CT
RY][i]); | |
267 } | |
268 else { | |
269 testLocale = Locale(rawData[LANG][i], rawData[CTRY][i]); | |
270 } | |
271 logln("Testing " + (temp=testLocale.getName()) + "..."); | |
272 | |
273 if ( (temp=testLocale.getLanguage()) != (dataTable[LANG][i])) | |
274 errln("Language code mismatch: " + temp + " versus " | |
275 + dataTable[LANG][i]); | |
276 if ( (temp=testLocale.getScript()) != (dataTable[SCRIPT][i])) | |
277 errln("Script code mismatch: " + temp + " versus " | |
278 + dataTable[SCRIPT][i]); | |
279 if ( (temp=testLocale.getCountry()) != (dataTable[CTRY][i])) | |
280 errln("Country code mismatch: " + temp + " versus " | |
281 + dataTable[CTRY][i]); | |
282 if (testLocale.getVariant()[0] != 0) | |
283 errln("Variant code mismatch: something versus \"\""); | |
284 } | |
285 | |
286 logln("Testing long language names and getters"); | |
287 Locale test8 = Locale::createFromName("x-klingon-latn-zx.utf32be@special"); | |
288 | |
289 temp = test8.getLanguage(); | |
290 if (temp != UnicodeString("x-klingon") ) | |
291 errln("Language code mismatch: " + temp + " versus \"x-klingon\""); | |
292 | |
293 temp = test8.getScript(); | |
294 if (temp != UnicodeString("Latn") ) | |
295 errln("Script code mismatch: " + temp + " versus \"Latn\""); | |
296 | |
297 temp = test8.getCountry(); | |
298 if (temp != UnicodeString("ZX") ) | |
299 errln("Country code mismatch: " + temp + " versus \"ZX\""); | |
300 | |
301 temp = test8.getVariant(); | |
302 //if (temp != UnicodeString("SPECIAL") ) | |
303 // errln("Variant code mismatch: " + temp + " versus \"SPECIAL\""); | |
304 // As of 3.0, the "@special" will *not* be parsed by uloc_getName() | |
305 if (temp != UnicodeString("") ) | |
306 errln("Variant code mismatch: " + temp + " versus \"\""); | |
307 | |
308 if (Locale::getDefault() != Locale::createFromName(NULL)) | |
309 errln("Locale::getDefault() == Locale::createFromName(NULL)"); | |
310 | |
311 /*----------*/ | |
312 // NOTE: There used to be a special test for locale names that had language
or | |
313 // country codes that were longer than two letters. The new version of Loca
le | |
314 // doesn't support anything that isn't an officially recognized language or | |
315 // country code, so we no longer support this feature. | |
316 | |
317 Locale bogusLang("THISISABOGUSLANGUAGE"); // Jitterbug 2864: language code t
oo long | |
318 if(!bogusLang.isBogus()) { | |
319 errln("Locale(\"THISISABOGUSLANGUAGE\").isBogus()==FALSE"); | |
320 } | |
321 | |
322 bogusLang=Locale("eo"); | |
323 if( bogusLang.isBogus() || | |
324 strcmp(bogusLang.getLanguage(), "eo")!=0 || | |
325 *bogusLang.getCountry()!=0 || | |
326 *bogusLang.getVariant()!=0 || | |
327 strcmp(bogusLang.getName(), "eo")!=0 | |
328 ) { | |
329 errln("assignment to bogus Locale does not unbogus it or sets bad data")
; | |
330 } | |
331 | |
332 Locale a("eo_DE@currency=DEM"); | |
333 Locale *pb=a.clone(); | |
334 if(pb==&a || *pb!=a) { | |
335 errln("Locale.clone() failed"); | |
336 } | |
337 delete pb; | |
338 } | |
339 | |
340 void LocaleTest::TestParallelAPIValues() { | |
341 logln("Test synchronization between C and C++ API"); | |
342 if (strcmp(Locale::getChinese().getName(), ULOC_CHINESE) != 0) { | |
343 errln("Differences for ULOC_CHINESE Locale"); | |
344 } | |
345 if (strcmp(Locale::getEnglish().getName(), ULOC_ENGLISH) != 0) { | |
346 errln("Differences for ULOC_ENGLISH Locale"); | |
347 } | |
348 if (strcmp(Locale::getFrench().getName(), ULOC_FRENCH) != 0) { | |
349 errln("Differences for ULOC_FRENCH Locale"); | |
350 } | |
351 if (strcmp(Locale::getGerman().getName(), ULOC_GERMAN) != 0) { | |
352 errln("Differences for ULOC_GERMAN Locale"); | |
353 } | |
354 if (strcmp(Locale::getItalian().getName(), ULOC_ITALIAN) != 0) { | |
355 errln("Differences for ULOC_ITALIAN Locale"); | |
356 } | |
357 if (strcmp(Locale::getJapanese().getName(), ULOC_JAPANESE) != 0) { | |
358 errln("Differences for ULOC_JAPANESE Locale"); | |
359 } | |
360 if (strcmp(Locale::getKorean().getName(), ULOC_KOREAN) != 0) { | |
361 errln("Differences for ULOC_KOREAN Locale"); | |
362 } | |
363 if (strcmp(Locale::getSimplifiedChinese().getName(), ULOC_SIMPLIFIED_CHINESE
) != 0) { | |
364 errln("Differences for ULOC_SIMPLIFIED_CHINESE Locale"); | |
365 } | |
366 if (strcmp(Locale::getTraditionalChinese().getName(), ULOC_TRADITIONAL_CHINE
SE) != 0) { | |
367 errln("Differences for ULOC_TRADITIONAL_CHINESE Locale"); | |
368 } | |
369 | |
370 | |
371 if (strcmp(Locale::getCanada().getName(), ULOC_CANADA) != 0) { | |
372 errln("Differences for ULOC_CANADA Locale"); | |
373 } | |
374 if (strcmp(Locale::getCanadaFrench().getName(), ULOC_CANADA_FRENCH) != 0) { | |
375 errln("Differences for ULOC_CANADA_FRENCH Locale"); | |
376 } | |
377 if (strcmp(Locale::getChina().getName(), ULOC_CHINA) != 0) { | |
378 errln("Differences for ULOC_CHINA Locale"); | |
379 } | |
380 if (strcmp(Locale::getPRC().getName(), ULOC_PRC) != 0) { | |
381 errln("Differences for ULOC_PRC Locale"); | |
382 } | |
383 if (strcmp(Locale::getFrance().getName(), ULOC_FRANCE) != 0) { | |
384 errln("Differences for ULOC_FRANCE Locale"); | |
385 } | |
386 if (strcmp(Locale::getGermany().getName(), ULOC_GERMANY) != 0) { | |
387 errln("Differences for ULOC_GERMANY Locale"); | |
388 } | |
389 if (strcmp(Locale::getItaly().getName(), ULOC_ITALY) != 0) { | |
390 errln("Differences for ULOC_ITALY Locale"); | |
391 } | |
392 if (strcmp(Locale::getJapan().getName(), ULOC_JAPAN) != 0) { | |
393 errln("Differences for ULOC_JAPAN Locale"); | |
394 } | |
395 if (strcmp(Locale::getKorea().getName(), ULOC_KOREA) != 0) { | |
396 errln("Differences for ULOC_KOREA Locale"); | |
397 } | |
398 if (strcmp(Locale::getTaiwan().getName(), ULOC_TAIWAN) != 0) { | |
399 errln("Differences for ULOC_TAIWAN Locale"); | |
400 } | |
401 if (strcmp(Locale::getUK().getName(), ULOC_UK) != 0) { | |
402 errln("Differences for ULOC_UK Locale"); | |
403 } | |
404 if (strcmp(Locale::getUS().getName(), ULOC_US) != 0) { | |
405 errln("Differences for ULOC_US Locale"); | |
406 } | |
407 } | |
408 | |
409 | |
410 void LocaleTest::TestSimpleResourceInfo() { | |
411 UnicodeString temp; | |
412 char temp2[20]; | |
413 UErrorCode err = U_ZERO_ERROR; | |
414 int32_t i = 0; | |
415 | |
416 for (i = 0; i <= MAX_LOCALES; i++) { | |
417 Locale testLocale(rawData[LANG][i], rawData[CTRY][i], rawData[VAR][i]); | |
418 logln("Testing " + (temp=testLocale.getName()) + "..."); | |
419 | |
420 if ( (temp=testLocale.getISO3Language()) != (dataTable[LANG3][i])) | |
421 errln(" ISO-3 language code mismatch: " + temp | |
422 + " versus " + dataTable[LANG3][i]); | |
423 if ( (temp=testLocale.getISO3Country()) != (dataTable[CTRY3][i])) | |
424 errln(" ISO-3 country code mismatch: " + temp | |
425 + " versus " + dataTable[CTRY3][i]); | |
426 | |
427 sprintf(temp2, "%x", (int)testLocale.getLCID()); | |
428 if (UnicodeString(temp2) != dataTable[LCID][i]) | |
429 errln((UnicodeString)" LCID mismatch: " + temp2 + " versus " | |
430 + dataTable[LCID][i]); | |
431 | |
432 if(U_FAILURE(err)) | |
433 { | |
434 errln((UnicodeString)"Some error on number " + i + u_errorName(err))
; | |
435 } | |
436 err = U_ZERO_ERROR; | |
437 } | |
438 | |
439 Locale locale("en"); | |
440 if(strcmp(locale.getName(), "en") != 0|| | |
441 strcmp(locale.getLanguage(), "en") != 0) { | |
442 errln("construction of Locale(en) failed\n"); | |
443 } | |
444 /*-----*/ | |
445 | |
446 } | |
447 | |
448 /* | |
449 * Jitterbug 2439 -- markus 20030425 | |
450 * | |
451 * The lookup of display names must not fall back through the default | |
452 * locale because that yields useless results. | |
453 */ | |
454 void | |
455 LocaleTest::TestDisplayNames() | |
456 { | |
457 Locale english("en", "US"); | |
458 Locale french("fr", "FR"); | |
459 Locale croatian("ca", "ES"); | |
460 Locale greek("el", "GR"); | |
461 | |
462 logln(" In locale = en_US..."); | |
463 doTestDisplayNames(english, DLANG_EN); | |
464 logln(" In locale = fr_FR..."); | |
465 doTestDisplayNames(french, DLANG_FR); | |
466 logln(" In locale = ca_ES..."); | |
467 doTestDisplayNames(croatian, DLANG_CA); | |
468 logln(" In locale = el_GR..."); | |
469 doTestDisplayNames(greek, DLANG_EL); | |
470 | |
471 UnicodeString s; | |
472 UErrorCode status = U_ZERO_ERROR; | |
473 | |
474 #if !UCONFIG_NO_FORMATTING | |
475 DecimalFormatSymbols symb(status); | |
476 /* Check to see if ICU supports this locale */ | |
477 if (symb.getLocale(ULOC_VALID_LOCALE, status) != Locale("root")) { | |
478 /* test that the default locale has a display name for its own language
*/ | |
479 /* Currently, there is no language information in the "tl" data file so
this test will fail if default locale is "tl" */ | |
480 if (uprv_strcmp(Locale().getLanguage(), "tl") != 0) { | |
481 Locale().getDisplayLanguage(Locale(), s); | |
482 if(s.length()<=3 && s.charAt(0)<=0x7f) { | |
483 /* check <=3 to reject getting the language code as a display na
me */ | |
484 dataerrln("unable to get a display string for the language of th
e default locale: " + s); | |
485 } | |
486 | |
487 /* | |
488 * API coverage improvements: call | |
489 * Locale::getDisplayLanguage(UnicodeString &) and | |
490 * Locale::getDisplayCountry(UnicodeString &) | |
491 */ | |
492 s.remove(); | |
493 Locale().getDisplayLanguage(s); | |
494 if(s.length()<=3 && s.charAt(0)<=0x7f) { | |
495 dataerrln("unable to get a display string for the language of th
e default locale [2]: " + s); | |
496 } | |
497 } | |
498 } | |
499 else { | |
500 logln("Default locale %s is unsupported by ICU\n", Locale().getName()); | |
501 } | |
502 s.remove(); | |
503 #endif | |
504 | |
505 french.getDisplayCountry(s); | |
506 if(s.isEmpty()) { | |
507 errln("unable to get any default-locale display string for the country o
f fr_FR\n"); | |
508 } | |
509 s.remove(); | |
510 Locale("zh", "Hant").getDisplayScript(s); | |
511 if(s.isEmpty()) { | |
512 errln("unable to get any default-locale display string for the country o
f zh_Hant\n"); | |
513 } | |
514 } | |
515 | |
516 void LocaleTest::TestSimpleObjectStuff() { | |
517 Locale test1("aa", "AA"); | |
518 Locale test2("aa", "AA"); | |
519 Locale test3(test1); | |
520 Locale test4("zz", "ZZ"); | |
521 Locale test5("aa", "AA", ""); | |
522 Locale test6("aa", "AA", "ANTARES"); | |
523 Locale test7("aa", "AA", "JUPITER"); | |
524 Locale test8 = Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@
jupiter" but in 3.0 getName won't normalize that | |
525 | |
526 // now list them all for debugging usage. | |
527 test_dumpLocale(test1); | |
528 test_dumpLocale(test2); | |
529 test_dumpLocale(test3); | |
530 test_dumpLocale(test4); | |
531 test_dumpLocale(test5); | |
532 test_dumpLocale(test6); | |
533 test_dumpLocale(test7); | |
534 test_dumpLocale(test8); | |
535 | |
536 // Make sure things compare to themselves! | |
537 test_assert(test1 == test1); | |
538 test_assert(test2 == test2); | |
539 test_assert(test3 == test3); | |
540 test_assert(test4 == test4); | |
541 test_assert(test5 == test5); | |
542 test_assert(test6 == test6); | |
543 test_assert(test7 == test7); | |
544 test_assert(test8 == test8); | |
545 | |
546 // make sure things are not equal to themselves. | |
547 test_assert(!(test1 != test1)); | |
548 test_assert(!(test2 != test2)); | |
549 test_assert(!(test3 != test3)); | |
550 test_assert(!(test4 != test4)); | |
551 test_assert(!(test5 != test5)); | |
552 test_assert(!(test6 != test6)); | |
553 test_assert(!(test7 != test7)); | |
554 test_assert(!(test8 != test8)); | |
555 | |
556 // make sure things that are equal to each other don't show up as unequal. | |
557 test_assert(!(test1 != test2)); | |
558 test_assert(!(test2 != test1)); | |
559 test_assert(!(test1 != test3)); | |
560 test_assert(!(test2 != test3)); | |
561 test_assert(test5 == test1); | |
562 test_assert(test6 != test2); | |
563 test_assert(test6 != test5); | |
564 | |
565 test_assert(test6 != test7); | |
566 | |
567 // test for things that shouldn't compare equal. | |
568 test_assert(!(test1 == test4)); | |
569 test_assert(!(test2 == test4)); | |
570 test_assert(!(test3 == test4)); | |
571 | |
572 test_assert(test7 == test8); | |
573 | |
574 // test for hash codes to be the same. | |
575 int32_t hash1 = test1.hashCode(); | |
576 int32_t hash2 = test2.hashCode(); | |
577 int32_t hash3 = test3.hashCode(); | |
578 | |
579 test_assert(hash1 == hash2); | |
580 test_assert(hash1 == hash3); | |
581 test_assert(hash2 == hash3); | |
582 | |
583 // test that the assignment operator works. | |
584 test4 = test1; | |
585 logln("test4=test1;"); | |
586 test_dumpLocale(test4); | |
587 test_assert(test4 == test4); | |
588 | |
589 test_assert(!(test1 != test4)); | |
590 test_assert(!(test2 != test4)); | |
591 test_assert(!(test3 != test4)); | |
592 test_assert(test1 == test4); | |
593 test_assert(test4 == test1); | |
594 | |
595 // test assignments with a variant | |
596 logln("test7 = test6"); | |
597 test7 = test6; | |
598 test_dumpLocale(test7); | |
599 test_assert(test7 == test7); | |
600 test_assert(test7 == test6); | |
601 test_assert(test7 != test5); | |
602 | |
603 logln("test6 = test1"); | |
604 test6=test1; | |
605 test_dumpLocale(test6); | |
606 test_assert(test6 != test7); | |
607 test_assert(test6 == test1); | |
608 test_assert(test6 == test6); | |
609 } | |
610 | |
611 // A class which exposes constructors that are implemented in terms of the POSIX
parsing code. | |
612 class POSIXLocale : public Locale | |
613 { | |
614 public: | |
615 POSIXLocale(const UnicodeString& l) | |
616 :Locale() | |
617 { | |
618 char *ch; | |
619 ch = new char[l.length() + 1]; | |
620 ch[l.extract(0, 0x7fffffff, ch, "")] = 0; | |
621 setFromPOSIXID(ch); | |
622 delete [] ch; | |
623 } | |
624 POSIXLocale(const char *l) | |
625 :Locale() | |
626 { | |
627 setFromPOSIXID(l); | |
628 } | |
629 }; | |
630 | |
631 void LocaleTest::TestPOSIXParsing() | |
632 { | |
633 POSIXLocale test1("ab_AB"); | |
634 POSIXLocale test2(UnicodeString("ab_AB")); | |
635 Locale test3("ab","AB"); | |
636 | |
637 POSIXLocale test4("ab_AB_Antares"); | |
638 POSIXLocale test5(UnicodeString("ab_AB_Antares")); | |
639 Locale test6("ab", "AB", "Antares"); | |
640 | |
641 test_dumpLocale(test1); | |
642 test_dumpLocale(test2); | |
643 test_dumpLocale(test3); | |
644 test_dumpLocale(test4); | |
645 test_dumpLocale(test5); | |
646 test_dumpLocale(test6); | |
647 | |
648 test_assert(test1 == test1); | |
649 | |
650 test_assert(test1 == test2); | |
651 test_assert(test2 == test3); | |
652 test_assert(test3 == test1); | |
653 | |
654 test_assert(test4 == test5); | |
655 test_assert(test5 == test6); | |
656 test_assert(test6 == test4); | |
657 | |
658 test_assert(test1 != test4); | |
659 test_assert(test5 != test3); | |
660 test_assert(test5 != test2); | |
661 | |
662 int32_t hash1 = test1.hashCode(); | |
663 int32_t hash2 = test2.hashCode(); | |
664 int32_t hash3 = test3.hashCode(); | |
665 | |
666 test_assert(hash1 == hash2); | |
667 test_assert(hash2 == hash3); | |
668 test_assert(hash3 == hash1); | |
669 } | |
670 | |
671 void LocaleTest::TestGetAvailableLocales() | |
672 { | |
673 int32_t locCount = 0; | |
674 const Locale* locList = Locale::getAvailableLocales(locCount); | |
675 | |
676 if (locCount == 0) | |
677 dataerrln("getAvailableLocales() returned an empty list!"); | |
678 else { | |
679 logln(UnicodeString("Number of locales returned = ") + locCount); | |
680 UnicodeString temp; | |
681 for(int32_t i = 0; i < locCount; ++i) | |
682 logln(locList[i].getName()); | |
683 } | |
684 // I have no idea how to test this function... | |
685 } | |
686 | |
687 // This test isn't applicable anymore - getISO3Language is | |
688 // independent of the data directory | |
689 void LocaleTest::TestDataDirectory() | |
690 { | |
691 /* | |
692 char oldDirectory[80]; | |
693 const char* temp; | |
694 UErrorCode err = U_ZERO_ERROR; | |
695 UnicodeString testValue; | |
696 | |
697 temp = Locale::getDataDirectory(); | |
698 strcpy(oldDirectory, temp); | |
699 logln(UnicodeString("oldDirectory = ") + oldDirectory); | |
700 | |
701 Locale test(Locale::US); | |
702 test.getISO3Language(testValue); | |
703 logln("first fetch of language retrieved " + testValue); | |
704 if (testValue != "eng") | |
705 errln("Initial check of ISO3 language failed: expected \"eng\", got \""
+ testValue + "\""); | |
706 | |
707 { | |
708 char *path; | |
709 path=IntlTest::getTestDirectory(); | |
710 Locale::setDataDirectory( path ); | |
711 } | |
712 | |
713 test.getISO3Language(testValue); | |
714 logln("second fetch of language retrieved " + testValue); | |
715 if (testValue != "xxx") | |
716 errln("setDataDirectory() failed: expected \"xxx\", got \"" + testValue
+ "\""); | |
717 | |
718 Locale::setDataDirectory(oldDirectory); | |
719 test.getISO3Language(testValue); | |
720 logln("third fetch of language retrieved " + testValue); | |
721 if (testValue != "eng") | |
722 errln("get/setDataDirectory() failed: expected \"eng\", got \"" + testVa
lue + "\""); | |
723 */ | |
724 } | |
725 | |
726 //=========================================================== | |
727 | |
728 void LocaleTest::doTestDisplayNames(Locale& displayLocale, int32_t compareIndex)
{ | |
729 UnicodeString temp; | |
730 | |
731 for (int32_t i = 0; i <= MAX_LOCALES; i++) { | |
732 Locale testLocale(""); | |
733 if (rawData[SCRIPT][i] && rawData[SCRIPT][i][0] != 0) { | |
734 testLocale = Locale(rawData[LANG][i], rawData[SCRIPT][i], rawData[CT
RY][i], rawData[VAR][i]); | |
735 } | |
736 else { | |
737 testLocale = Locale(rawData[LANG][i], rawData[CTRY][i], rawData[VAR]
[i]); | |
738 } | |
739 logln(" Testing " + (temp=testLocale.getName()) + "..."); | |
740 | |
741 UnicodeString testLang; | |
742 UnicodeString testScript; | |
743 UnicodeString testCtry; | |
744 UnicodeString testVar; | |
745 UnicodeString testName; | |
746 | |
747 testLocale.getDisplayLanguage(displayLocale, testLang); | |
748 testLocale.getDisplayScript(displayLocale, testScript); | |
749 testLocale.getDisplayCountry(displayLocale, testCtry); | |
750 testLocale.getDisplayVariant(displayLocale, testVar); | |
751 testLocale.getDisplayName(displayLocale, testName); | |
752 | |
753 UnicodeString expectedLang; | |
754 UnicodeString expectedScript; | |
755 UnicodeString expectedCtry; | |
756 UnicodeString expectedVar; | |
757 UnicodeString expectedName; | |
758 | |
759 expectedLang = dataTable[compareIndex][i]; | |
760 if (expectedLang.length() == 0) | |
761 expectedLang = dataTable[DLANG_EN][i]; | |
762 | |
763 expectedScript = dataTable[compareIndex + 1][i]; | |
764 if (expectedScript.length() == 0) | |
765 expectedScript = dataTable[DSCRIPT_EN][i]; | |
766 | |
767 expectedCtry = dataTable[compareIndex + 2][i]; | |
768 if (expectedCtry.length() == 0) | |
769 expectedCtry = dataTable[DCTRY_EN][i]; | |
770 | |
771 expectedVar = dataTable[compareIndex + 3][i]; | |
772 if (expectedVar.length() == 0) | |
773 expectedVar = dataTable[DVAR_EN][i]; | |
774 | |
775 expectedName = dataTable[compareIndex + 4][i]; | |
776 if (expectedName.length() == 0) | |
777 expectedName = dataTable[DNAME_EN][i]; | |
778 | |
779 if (testLang != expectedLang) | |
780 dataerrln("Display language (" + UnicodeString(displayLocale.getName
()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testLang + " e
xpected " + expectedLang); | |
781 if (testScript != expectedScript) | |
782 dataerrln("Display script (" + UnicodeString(displayLocale.getName()
) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testScript + " e
xpected " + expectedScript); | |
783 if (testCtry != expectedCtry) | |
784 dataerrln("Display country (" + UnicodeString(displayLocale.getName(
)) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testCtry + " ex
pected " + expectedCtry); | |
785 if (testVar != expectedVar) | |
786 dataerrln("Display variant (" + UnicodeString(displayLocale.getName(
)) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testVar + " exp
ected " + expectedVar); | |
787 if (testName != expectedName) | |
788 dataerrln("Display name (" + UnicodeString(displayLocale.getName())
+ ") of (" + UnicodeString(testLocale.getName()) + ") got " + testName + " expec
ted " + expectedName); | |
789 } | |
790 } | |
791 | |
792 //--------------------------------------------------- | |
793 // table of valid data | |
794 //--------------------------------------------------- | |
795 | |
796 | |
797 | |
798 void LocaleTest::setUpDataTable() | |
799 { | |
800 if (dataTable == 0) { | |
801 dataTable = new UnicodeString*[33]; | |
802 | |
803 for (int32_t i = 0; i < 33; i++) { | |
804 dataTable[i] = new UnicodeString[8]; | |
805 for (int32_t j = 0; j < 8; j++) { | |
806 dataTable[i][j] = CharsToUnicodeString(rawData[i][j]); | |
807 } | |
808 } | |
809 } | |
810 } | |
811 | |
812 // ==================== | |
813 | |
814 | |
815 /** | |
816 * @bug 4011756 4011380 | |
817 */ | |
818 void | |
819 LocaleTest::TestISO3Fallback() | |
820 { | |
821 Locale test("xx", "YY"); | |
822 | |
823 const char * result; | |
824 | |
825 result = test.getISO3Language(); | |
826 | |
827 // Conform to C API usage | |
828 | |
829 if (!result || (result[0] != 0)) | |
830 errln("getISO3Language() on xx_YY returned " + UnicodeString(result) + "
instead of \"\""); | |
831 | |
832 result = test.getISO3Country(); | |
833 | |
834 if (!result || (result[0] != 0)) | |
835 errln("getISO3Country() on xx_YY returned " + UnicodeString(result) + "
instead of \"\""); | |
836 } | |
837 | |
838 /** | |
839 * @bug 4106155 4118587 | |
840 */ | |
841 void | |
842 LocaleTest::TestGetLangsAndCountries() | |
843 { | |
844 // It didn't seem right to just do an exhaustive test of everything here, so
I check | |
845 // for the following things: | |
846 // 1) Does each list have the right total number of entries? | |
847 // 2) Does each list contain certain language and country codes we think are
important | |
848 // (the G7 countries, plus a couple others)? | |
849 // 3) Does each list have every entry formatted correctly? (i.e., two charac
ters, | |
850 // all lower case for the language codes, all upper case for the country
codes) | |
851 // 4) Is each list in sorted order? | |
852 int32_t testCount = 0; | |
853 const char * const * test = Locale::getISOLanguages(); | |
854 const char spotCheck1[ ][4] = { "en", "es", "fr", "de", "it", | |
855 "ja", "ko", "zh", "th", "he", | |
856 "id", "iu", "ug", "yi", "za" }; | |
857 | |
858 int32_t i; | |
859 | |
860 for(testCount = 0;test[testCount];testCount++) | |
861 ; | |
862 | |
863 /* TODO: Change this test to be more like the cloctst version? */ | |
864 if (testCount != 593) | |
865 errln("Expected getISOLanguages() to return 593 languages; it returned %
d", testCount); | |
866 else { | |
867 for (i = 0; i < 15; i++) { | |
868 int32_t j; | |
869 for (j = 0; j < testCount; j++) | |
870 if (uprv_strcmp(test[j],spotCheck1[i])== 0) | |
871 break; | |
872 if (j == testCount || (uprv_strcmp(test[j],spotCheck1[i])!=0)) | |
873 errln("Couldn't find " + (UnicodeString)spotCheck1[i] + " in lan
guage list."); | |
874 } | |
875 } | |
876 for (i = 0; i < testCount; i++) { | |
877 UnicodeString testee(test[i],""); | |
878 UnicodeString lc(test[i],""); | |
879 if (testee != lc.toLower()) | |
880 errln(lc + " is not all lower case."); | |
881 if ( (testee.length() != 2) && (testee.length() != 3)) | |
882 errln(testee + " is not two or three characters long."); | |
883 if (i > 0 && testee.compare(test[i - 1]) <= 0) | |
884 errln(testee + " appears in an out-of-order position in the list."); | |
885 } | |
886 | |
887 test = Locale::getISOCountries(); | |
888 UnicodeString spotCheck2 [] = { "US", "CA", "GB", "FR", "DE", | |
889 "IT", "JP", "KR", "CN", "TW", | |
890 "TH" }; | |
891 int32_t spot2Len = 11; | |
892 for(testCount=0;test[testCount];testCount++) | |
893 ; | |
894 | |
895 if (testCount != 249){ | |
896 errln("Expected getISOCountries to return 249 countries; it returned %d"
, testCount); | |
897 }else { | |
898 for (i = 0; i < spot2Len; i++) { | |
899 int32_t j; | |
900 for (j = 0; j < testCount; j++) | |
901 { | |
902 UnicodeString testee(test[j],""); | |
903 | |
904 if (testee == spotCheck2[i]) | |
905 break; | |
906 } | |
907 UnicodeString testee(test[j],""); | |
908 if (j == testCount || testee != spotCheck2[i]) | |
909 errln("Couldn't find " + spotCheck2[i] + " in country list."); | |
910 } | |
911 } | |
912 for (i = 0; i < testCount; i++) { | |
913 UnicodeString testee(test[i],""); | |
914 UnicodeString uc(test[i],""); | |
915 if (testee != uc.toUpper()) | |
916 errln(testee + " is not all upper case."); | |
917 if (testee.length() != 2) | |
918 errln(testee + " is not two characters long."); | |
919 if (i > 0 && testee.compare(test[i - 1]) <= 0) | |
920 errln(testee + " appears in an out-of-order position in the list."); | |
921 } | |
922 | |
923 // This getAvailableLocales and getISO3Language | |
924 { | |
925 int32_t numOfLocales; | |
926 Locale enLoc ("en"); | |
927 const Locale *pLocales = Locale::getAvailableLocales(numOfLocales); | |
928 | |
929 for (int i = 0; i < numOfLocales; i++) { | |
930 const Locale &loc(pLocales[i]); | |
931 UnicodeString name; | |
932 char szName[200]; | |
933 | |
934 loc.getDisplayName (enLoc, name); | |
935 name.extract (0, 200, szName, sizeof(szName)); | |
936 | |
937 if (strlen(loc.getISO3Language()) == 0) { | |
938 errln("getISO3Language() returned an empty string for: " + name)
; | |
939 } | |
940 } | |
941 } | |
942 } | |
943 | |
944 /** | |
945 * @bug 4118587 | |
946 */ | |
947 void | |
948 LocaleTest::TestSimpleDisplayNames() | |
949 { | |
950 // This test is different from TestDisplayNames because TestDisplayNames che
cks | |
951 // fallback behavior, combination of language and country names to form loca
le | |
952 // names, and other stuff like that. This test just checks specific languag
e | |
953 // and country codes to make sure we have the correct names for them. | |
954 char languageCodes[] [4] = { "he", "id", "iu", "ug", "yi", "za" }; | |
955 UnicodeString languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uyg
hur", "Yiddish", | |
956 "Zhuang" }; | |
957 | |
958 for (int32_t i = 0; i < 6; i++) { | |
959 UnicodeString test; | |
960 Locale l(languageCodes[i], "", ""); | |
961 l.getDisplayLanguage(Locale::getUS(), test); | |
962 if (test != languageNames[i]) | |
963 dataerrln("Got wrong display name for " + UnicodeString(languageCode
s[i]) + ": Expected \"" + | |
964 languageNames[i] + "\", got \"" + test + "\"."); | |
965 } | |
966 } | |
967 | |
968 /** | |
969 * @bug 4118595 | |
970 */ | |
971 void | |
972 LocaleTest::TestUninstalledISO3Names() | |
973 { | |
974 // This test checks to make sure getISO3Language and getISO3Country work rig
ht | |
975 // even for locales that are not installed. | |
976 const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn", | |
977 "ss", "tw", "zu" }; | |
978 const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run", | |
979 "ssw", "twi", "zul" }; | |
980 | |
981 int32_t i; | |
982 | |
983 for (i = 0; i < 8; i++) { | |
984 UErrorCode err = U_ZERO_ERROR; | |
985 | |
986 UnicodeString test; | |
987 Locale l(iso2Languages[i], "", ""); | |
988 test = l.getISO3Language(); | |
989 if((test != iso3Languages[i]) || U_FAILURE(err)) | |
990 errln("Got wrong ISO3 code for " + UnicodeString(iso2Languages[i]) +
": Expected \"" + | |
991 iso3Languages[i] + "\", got \"" + test + "\"." + UnicodeStri
ng(u_errorName(err))); | |
992 } | |
993 | |
994 char iso2Countries [][4] = { "AF", "BW", "KZ", "MO", "MN", | |
995 "SB", "TC", "ZW" }; | |
996 char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG", | |
997 "SLB", "TCA", "ZWE" }; | |
998 | |
999 for (i = 0; i < 8; i++) { | |
1000 UErrorCode err = U_ZERO_ERROR; | |
1001 Locale l("", iso2Countries[i], ""); | |
1002 UnicodeString test(l.getISO3Country(), ""); | |
1003 if (test != iso3Countries[i]) | |
1004 errln("Got wrong ISO3 code for " + UnicodeString(iso2Countries[i]) +
": Expected \"" + | |
1005 UnicodeString(iso3Countries[i]) + "\", got \"" + test + "\".
" + u_errorName(err)); | |
1006 } | |
1007 } | |
1008 | |
1009 /** | |
1010 * @bug 4092475 | |
1011 * I could not reproduce this bug. I'm pretty convinced it was fixed with the | |
1012 * big locale-data reorg of 10/28/97. The lookup logic for language and country | |
1013 * display names was also changed at that time in that check-in. --rtg 3/20/9
8 | |
1014 */ | |
1015 void | |
1016 LocaleTest::TestAtypicalLocales() | |
1017 { | |
1018 Locale localesToTest [] = { Locale("de", "CA"), | |
1019 Locale("ja", "ZA"), | |
1020 Locale("ru", "MX"), | |
1021 Locale("en", "FR"), | |
1022 Locale("es", "DE"), | |
1023 Locale("", "HR"), | |
1024 Locale("", "SE"), | |
1025 Locale("", "DO"), | |
1026 Locale("", "BE") }; | |
1027 | |
1028 UnicodeString englishDisplayNames [] = { "German (Canada)", | |
1029 "Japanese (South Africa)", | |
1030 "Russian (Mexico)", | |
1031 "English (France)", | |
1032 "Spanish (Germany)", | |
1033 "Croatia", | |
1034 "Sweden", | |
1035 "Dominican Republic", | |
1036 "Belgium" }; | |
1037 UnicodeString frenchDisplayNames []= { "allemand (Canada)", | |
1038 "japonais (Afrique du Sud)", | |
1039 "russe (Mexique)", | |
1040 "anglais (France)", | |
1041 "espagnol (Allemagne)", | |
1042 "Croatie", | |
1043 CharsToUnicodeString("Su\\u00E8de"), | |
1044 CharsToUnicodeString("R\\u00E9publique domin
icaine"), | |
1045 "Belgique" }; | |
1046 UnicodeString spanishDisplayNames [] = { | |
1047 CharsToUnicodeString("alem\\u00E1n (Canad\\
u00E1)"), | |
1048 CharsToUnicodeString("japon\\u00E9s (Sud\\u
00E1frica)"), | |
1049 CharsToUnicodeString("ruso (M\\u00E9xico)")
, | |
1050 CharsToUnicodeString("ingl\\u00E9s (Francia
)"), | |
1051 CharsToUnicodeString("espa\\u00F1ol (Aleman
ia)"), | |
1052 "Croacia", | |
1053 "Suecia", | |
1054 CharsToUnicodeString("Rep\\u00FAblica Domin
icana"), | |
1055 CharsToUnicodeString("B\\u00E9lgica") }; | |
1056 // De-Anglicizing root required the change from | |
1057 // English display names to ISO Codes - ram 2003/09/26 | |
1058 UnicodeString invDisplayNames [] = { "German (Canada)", | |
1059 "Japanese (South Africa)", | |
1060 "Russian (Mexico)", | |
1061 "English (France)", | |
1062 "Spanish (Germany)", | |
1063 "Croatia", | |
1064 "Sweden", | |
1065 "Dominican Republic", | |
1066 "Belgium" }; | |
1067 | |
1068 int32_t i; | |
1069 UErrorCode status = U_ZERO_ERROR; | |
1070 Locale saveLocale; | |
1071 Locale::setDefault(Locale::getUS(), status); | |
1072 for (i = 0; i < 9; ++i) { | |
1073 UnicodeString name; | |
1074 localesToTest[i].getDisplayName(Locale::getUS(), name); | |
1075 logln(name); | |
1076 if (name != englishDisplayNames[i]) | |
1077 { | |
1078 dataerrln("Lookup in English failed: expected \"" + englishDisplayNa
mes[i] | |
1079 + "\", got \"" + name + "\""); | |
1080 logln("Locale name was-> " + (name=localesToTest[i].getName())); | |
1081 } | |
1082 } | |
1083 | |
1084 for (i = 0; i < 9; i++) { | |
1085 UnicodeString name; | |
1086 localesToTest[i].getDisplayName(Locale("es", "ES"), name); | |
1087 logln(name); | |
1088 if (name != spanishDisplayNames[i]) | |
1089 dataerrln("Lookup in Spanish failed: expected \"" + spanishDisplayNa
mes[i] | |
1090 + "\", got \"" + name + "\""); | |
1091 } | |
1092 | |
1093 for (i = 0; i < 9; i++) { | |
1094 UnicodeString name; | |
1095 localesToTest[i].getDisplayName(Locale::getFrance(), name); | |
1096 logln(name); | |
1097 if (name != frenchDisplayNames[i]) | |
1098 dataerrln("Lookup in French failed: expected \"" + frenchDisplayName
s[i] | |
1099 + "\", got \"" + name + "\""); | |
1100 } | |
1101 | |
1102 for (i = 0; i < 9; i++) { | |
1103 UnicodeString name; | |
1104 localesToTest[i].getDisplayName(Locale("inv", "IN"), name); | |
1105 logln(name + " Locale fallback to be, and data fallback to root"); | |
1106 if (name != invDisplayNames[i]) | |
1107 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayN
ames[i]) | |
1108 + "\", got \"" + prettify(name) + "\""); | |
1109 localesToTest[i].getDisplayName(Locale("inv", "BD"), name); | |
1110 logln(name + " Data fallback to root"); | |
1111 if (name != invDisplayNames[i]) | |
1112 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayN
ames[i]) | |
1113 + "\", got \"" + prettify(name )+ "\""); | |
1114 } | |
1115 Locale::setDefault(saveLocale, status); | |
1116 } | |
1117 | |
1118 #if !UCONFIG_NO_FORMATTING | |
1119 | |
1120 /** | |
1121 * @bug 4135752 | |
1122 * This would be better tested by the LocaleDataTest. Will move it when I | |
1123 * get the LocaleDataTest working again. | |
1124 */ | |
1125 void | |
1126 LocaleTest::TestThaiCurrencyFormat() | |
1127 { | |
1128 UErrorCode status = U_ZERO_ERROR; | |
1129 DecimalFormat *thaiCurrency = (DecimalFormat*)NumberFormat::createCurrencyIn
stance( | |
1130 Locale("th", "TH"), status); | |
1131 UnicodeString posPrefix("THB", 3, US_INV); // per cldrbug 7618 | |
1132 UnicodeString temp; | |
1133 | |
1134 if(U_FAILURE(status) || !thaiCurrency) | |
1135 { | |
1136 dataerrln("Couldn't get th_TH currency -> " + UnicodeString(u_errorName(
status))); | |
1137 return; | |
1138 } | |
1139 if (thaiCurrency->getPositivePrefix(temp) != posPrefix) | |
1140 errln("Thai currency prefix wrong: expected THB, got \"" + | |
1141 thaiCurrency->getPositivePrefix(temp) + "\""); | |
1142 if (thaiCurrency->getPositiveSuffix(temp) != "") | |
1143 errln("Thai currency suffix wrong: expected \"\", got \"" + | |
1144 thaiCurrency->getPositiveSuffix(temp) + "\""); | |
1145 | |
1146 delete thaiCurrency; | |
1147 } | |
1148 | |
1149 /** | |
1150 * @bug 4122371 | |
1151 * Confirm that Euro support works. This test is pretty rudimentary; all it doe
s | |
1152 * is check that any locales with the EURO variant format a number using the | |
1153 * Euro currency symbol. | |
1154 * | |
1155 * ASSUME: All locales encode the Euro character "\u20AC". | |
1156 * If this is changed to use the single-character Euro symbol, this | |
1157 * test must be updated. | |
1158 * | |
1159 */ | |
1160 void | |
1161 LocaleTest::TestEuroSupport() | |
1162 { | |
1163 UChar euro = 0x20ac; | |
1164 const UnicodeString EURO_CURRENCY(&euro, 1, 1); // Look for this UnicodeStri
ng in formatted Euro currency | |
1165 const char* localeArr[] = { | |
1166 "ca_ES", | |
1167 "de_AT", | |
1168 "de_DE", | |
1169 "de_LU", | |
1170 "el_GR", | |
1171 "en_BE", | |
1172 "en_IE", | |
1173 "en_GB_EURO", | |
1174 "en_US_EURO", | |
1175 "es_ES", | |
1176 "eu_ES", | |
1177 "fi_FI", | |
1178 "fr_BE", | |
1179 "fr_FR", | |
1180 "fr_LU", | |
1181 "ga_IE", | |
1182 "gl_ES", | |
1183 "it_IT", | |
1184 "nl_BE", | |
1185 "nl_NL", | |
1186 "pt_PT", | |
1187 NULL | |
1188 }; | |
1189 const char** locales = localeArr; | |
1190 | |
1191 UErrorCode status = U_ZERO_ERROR; | |
1192 | |
1193 UnicodeString temp; | |
1194 | |
1195 for (;*locales!=NULL;locales++) { | |
1196 Locale loc (*locales); | |
1197 UnicodeString temp; | |
1198 NumberFormat *nf = NumberFormat::createCurrencyInstance(loc, status); | |
1199 UnicodeString pos; | |
1200 | |
1201 if (U_FAILURE(status)) { | |
1202 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)",
*locales); | |
1203 continue; | |
1204 } | |
1205 | |
1206 nf->format(271828.182845, pos); | |
1207 UnicodeString neg; | |
1208 nf->format(-271828.182845, neg); | |
1209 if (pos.indexOf(EURO_CURRENCY) >= 0 && | |
1210 neg.indexOf(EURO_CURRENCY) >= 0) { | |
1211 logln("Ok: " + (temp=loc.getName()) + | |
1212 ": " + pos + " / " + neg); | |
1213 } | |
1214 else { | |
1215 errln("Fail: " + (temp=loc.getName()) + | |
1216 " formats without " + EURO_CURRENCY + | |
1217 ": " + pos + " / " + neg + | |
1218 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED *
**"); | |
1219 } | |
1220 | |
1221 delete nf; | |
1222 } | |
1223 | |
1224 UnicodeString dollarStr("USD", ""), euroStr("EUR", ""), genericStr((UChar)0x
00a4), resultStr; | |
1225 UChar tmp[4]; | |
1226 status = U_ZERO_ERROR; | |
1227 | |
1228 ucurr_forLocale("en_US", tmp, 4, &status); | |
1229 resultStr.setTo(tmp); | |
1230 if (dollarStr != resultStr) { | |
1231 errcheckln(status, "Fail: en_US didn't return USD - %s", u_errorName(sta
tus)); | |
1232 } | |
1233 ucurr_forLocale("en_US_EURO", tmp, 4, &status); | |
1234 resultStr.setTo(tmp); | |
1235 if (euroStr != resultStr) { | |
1236 errcheckln(status, "Fail: en_US_EURO didn't return EUR - %s", u_errorNam
e(status)); | |
1237 } | |
1238 ucurr_forLocale("en_GB_EURO", tmp, 4, &status); | |
1239 resultStr.setTo(tmp); | |
1240 if (euroStr != resultStr) { | |
1241 errcheckln(status, "Fail: en_GB_EURO didn't return EUR - %s", u_errorNam
e(status)); | |
1242 } | |
1243 ucurr_forLocale("en_US_PREEURO", tmp, 4, &status); | |
1244 resultStr.setTo(tmp); | |
1245 if (dollarStr != resultStr) { | |
1246 errcheckln(status, "Fail: en_US_PREEURO didn't fallback to en_US - %s",
u_errorName(status)); | |
1247 } | |
1248 ucurr_forLocale("en_US_Q", tmp, 4, &status); | |
1249 resultStr.setTo(tmp); | |
1250 if (dollarStr != resultStr) { | |
1251 errcheckln(status, "Fail: en_US_Q didn't fallback to en_US - %s", u_erro
rName(status)); | |
1252 } | |
1253 int32_t invalidLen = ucurr_forLocale("en_QQ", tmp, 4, &status); | |
1254 if (invalidLen || U_SUCCESS(status)) { | |
1255 errln("Fail: en_QQ didn't return NULL"); | |
1256 } | |
1257 } | |
1258 | |
1259 #endif | |
1260 | |
1261 /** | |
1262 * @bug 4139504 | |
1263 * toString() doesn't work with language_VARIANT. | |
1264 */ | |
1265 void | |
1266 LocaleTest::TestToString() { | |
1267 Locale DATA [] = { | |
1268 Locale("xx", "", ""), | |
1269 Locale("", "YY", ""), | |
1270 Locale("", "", "ZZ"), | |
1271 Locale("xx", "YY", ""), | |
1272 Locale("xx", "", "ZZ"), | |
1273 Locale("", "YY", "ZZ"), | |
1274 Locale("xx", "YY", "ZZ"), | |
1275 }; | |
1276 | |
1277 const char DATA_S [][20] = { | |
1278 "xx", | |
1279 "_YY", | |
1280 "__ZZ", | |
1281 "xx_YY", | |
1282 "xx__ZZ", | |
1283 "_YY_ZZ", | |
1284 "xx_YY_ZZ", | |
1285 }; | |
1286 | |
1287 for (int32_t i=0; i < 7; ++i) { | |
1288 const char *name; | |
1289 name = DATA[i].getName(); | |
1290 | |
1291 if (strcmp(name, DATA_S[i]) != 0) | |
1292 { | |
1293 errln("Fail: Locale.getName(), got:" + UnicodeString(name) + ", expe
cted: " + DATA_S[i]); | |
1294 } | |
1295 else | |
1296 logln("Pass: Locale.getName(), got:" + UnicodeString(name) ); | |
1297 } | |
1298 } | |
1299 | |
1300 #if !UCONFIG_NO_FORMATTING | |
1301 | |
1302 /** | |
1303 * @bug 4139940 | |
1304 * Couldn't reproduce this bug -- probably was fixed earlier. | |
1305 * | |
1306 * ORIGINAL BUG REPORT: | |
1307 * -- basically, hungarian for monday shouldn't have an \u00f4 | |
1308 * (o circumflex)in it instead it should be an o with 2 inclined | |
1309 * (right) lines over it.. | |
1310 * | |
1311 * You may wonder -- why do all this -- why not just add a line to | |
1312 * LocaleData? Well, I could see by inspection that the locale file had the | |
1313 * right character in it, so I wanted to check the rest of the pipeline -- a | |
1314 * very remote possibility, but I wanted to be sure. The other possibility | |
1315 * is that something is wrong with the font mapping subsystem, but we can't | |
1316 * test that here. | |
1317 */ | |
1318 void | |
1319 LocaleTest::Test4139940() | |
1320 { | |
1321 Locale mylocale("hu", "", ""); | |
1322 UDate mydate = date(98,3,13); // A Monday | |
1323 UErrorCode status = U_ZERO_ERROR; | |
1324 SimpleDateFormat df_full("EEEE", mylocale, status); | |
1325 if(U_FAILURE(status)){ | |
1326 dataerrln(UnicodeString("Could not create SimpleDateFormat object for lo
cale hu. Error: ") + UnicodeString(u_errorName(status))); | |
1327 return; | |
1328 } | |
1329 UnicodeString str; | |
1330 FieldPosition pos(FieldPosition::DONT_CARE); | |
1331 df_full.format(mydate, str, pos); | |
1332 // Make sure that o circumflex (\u00F4) is NOT there, and | |
1333 // o double acute (\u0151) IS. | |
1334 UChar ocf = 0x00f4; | |
1335 UChar oda = 0x0151; | |
1336 if (str.indexOf(oda) < 0 || str.indexOf(ocf) >= 0) { | |
1337 /* If the default locale is "th" this test will fail because of the buddhi
st calendar. */ | |
1338 if (strcmp(Locale::getDefault().getLanguage(), "th") != 0) { | |
1339 errln("Fail: Monday in Hungarian is wrong - oda's index is %d and ocf's
is %d", | |
1340 str.indexOf(oda), str.indexOf(ocf)); | |
1341 } else { | |
1342 logln(UnicodeString("An error is produce in buddhist calendar.")); | |
1343 } | |
1344 logln(UnicodeString("String is: ") + str ); | |
1345 } | |
1346 } | |
1347 | |
1348 UDate | |
1349 LocaleTest::date(int32_t y, int32_t m, int32_t d, int32_t hr, int32_t min, int32
_t sec) | |
1350 { | |
1351 UErrorCode status = U_ZERO_ERROR; | |
1352 Calendar *cal = Calendar::createInstance(status); | |
1353 if (cal == 0) | |
1354 return 0.0; | |
1355 cal->clear(); | |
1356 cal->set(1900 + y, m, d, hr, min, sec); // Add 1900 to follow java.util.Date
protocol | |
1357 UDate dt = cal->getTime(status); | |
1358 if (U_FAILURE(status)) | |
1359 return 0.0; | |
1360 | |
1361 delete cal; | |
1362 return dt; | |
1363 } | |
1364 | |
1365 /** | |
1366 * @bug 4143951 | |
1367 * Russian first day of week should be Monday. Confirmed. | |
1368 */ | |
1369 void | |
1370 LocaleTest::Test4143951() | |
1371 { | |
1372 UErrorCode status = U_ZERO_ERROR; | |
1373 Calendar *cal = Calendar::createInstance(Locale("ru", "", ""), status); | |
1374 if(U_SUCCESS(status)) { | |
1375 if (cal->getFirstDayOfWeek(status) != UCAL_MONDAY) { | |
1376 dataerrln("Fail: First day of week in Russia should be Monday"); | |
1377 } | |
1378 } | |
1379 delete cal; | |
1380 } | |
1381 | |
1382 #endif | |
1383 | |
1384 /** | |
1385 * @bug 4147315 | |
1386 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes. | |
1387 * Should throw an exception for unknown locales | |
1388 */ | |
1389 void | |
1390 LocaleTest::Test4147315() | |
1391 { | |
1392 UnicodeString temp; | |
1393 // Try with codes that are the wrong length but happen to match text | |
1394 // at a valid offset in the mapping table | |
1395 Locale locale("xxx", "CCC"); | |
1396 | |
1397 const char *result = locale.getISO3Country(); | |
1398 | |
1399 // Change to conform to C api usage | |
1400 if((result==NULL)||(result[0] != 0)) | |
1401 errln("ERROR: getISO3Country() returns: " + UnicodeString(result,"") + | |
1402 " for locale '" + (temp=locale.getName()) + "' rather than excep
tion" ); | |
1403 } | |
1404 | |
1405 /** | |
1406 * @bug 4147317 | |
1407 * java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes. | |
1408 * Should throw an exception for unknown locales | |
1409 */ | |
1410 void | |
1411 LocaleTest::Test4147317() | |
1412 { | |
1413 UnicodeString temp; | |
1414 // Try with codes that are the wrong length but happen to match text | |
1415 // at a valid offset in the mapping table | |
1416 Locale locale("xxx", "CCC"); | |
1417 | |
1418 const char *result = locale.getISO3Language(); | |
1419 | |
1420 // Change to conform to C api usage | |
1421 if((result==NULL)||(result[0] != 0)) | |
1422 errln("ERROR: getISO3Language() returns: " + UnicodeString(result,"") + | |
1423 " for locale '" + (temp=locale.getName()) + "' rather than excep
tion" ); | |
1424 } | |
1425 | |
1426 /* | |
1427 * @bug 4147552 | |
1428 */ | |
1429 void | |
1430 LocaleTest::Test4147552() | |
1431 { | |
1432 Locale locales [] = { Locale("no", "NO"), | |
1433 Locale("no", "NO", "B"), | |
1434 Locale("no", "NO", "NY") | |
1435 }; | |
1436 | |
1437 UnicodeString edn("Norwegian (Norway, B)"); | |
1438 UnicodeString englishDisplayNames [] = { | |
1439 "Norwegian (Norway)", | |
1440 edn, | |
1441 // "Norwegian (Norway,B)", | |
1442 //"Norwegian (Norway,NY)" | |
1443 "Norwegian (Norway, NY)" | |
1444 }; | |
1445 UnicodeString ndn("norsk (Norge, B"); | |
1446 UnicodeString norwegianDisplayNames [] = { | |
1447 "norsk (Norge)", | |
1448 "norsk (Norge, B)", | |
1449 //ndn, | |
1450 "norsk (Noreg, NY)" | |
1451 //"Norsk (Noreg, Nynorsk)" | |
1452 }; | |
1453 UErrorCode status = U_ZERO_ERROR; | |
1454 | |
1455 Locale saveLocale; | |
1456 Locale::setDefault(Locale::getEnglish(), status); | |
1457 for (int32_t i = 0; i < 3; ++i) { | |
1458 Locale loc = locales[i]; | |
1459 UnicodeString temp; | |
1460 if (loc.getDisplayName(temp) != englishDisplayNames[i]) | |
1461 dataerrln("English display-name mismatch: expected " + | |
1462 englishDisplayNames[i] + ", got " + loc.getDisplayName(temp))
; | |
1463 if (loc.getDisplayName(loc, temp) != norwegianDisplayNames[i]) | |
1464 dataerrln("Norwegian display-name mismatch: expected " + | |
1465 norwegianDisplayNames[i] + ", got " + | |
1466 loc.getDisplayName(loc, temp)); | |
1467 } | |
1468 Locale::setDefault(saveLocale, status); | |
1469 } | |
1470 | |
1471 void | |
1472 LocaleTest::TestVariantParsing() | |
1473 { | |
1474 Locale en_US_custom("en", "US", "De Anza_Cupertino_California_United States_
Earth"); | |
1475 | |
1476 UnicodeString dispName("English (United States, DE ANZA_CUPERTINO_CALIFORNIA
_UNITED STATES_EARTH)"); | |
1477 UnicodeString dispVar("DE ANZA_CUPERTINO_CALIFORNIA_UNITED STATES_EARTH"); | |
1478 | |
1479 UnicodeString got; | |
1480 | |
1481 en_US_custom.getDisplayVariant(Locale::getUS(), got); | |
1482 if(got != dispVar) { | |
1483 errln("FAIL: getDisplayVariant()"); | |
1484 errln("Wanted: " + dispVar); | |
1485 errln("Got : " + got); | |
1486 } | |
1487 | |
1488 en_US_custom.getDisplayName(Locale::getUS(), got); | |
1489 if(got != dispName) { | |
1490 dataerrln("FAIL: getDisplayName()"); | |
1491 dataerrln("Wanted: " + dispName); | |
1492 dataerrln("Got : " + got); | |
1493 } | |
1494 | |
1495 Locale shortVariant("fr", "FR", "foo"); | |
1496 shortVariant.getDisplayVariant(got); | |
1497 | |
1498 if(got != "FOO") { | |
1499 errln("FAIL: getDisplayVariant()"); | |
1500 errln("Wanted: foo"); | |
1501 errln("Got : " + got); | |
1502 } | |
1503 | |
1504 Locale bogusVariant("fr", "FR", "_foo"); | |
1505 bogusVariant.getDisplayVariant(got); | |
1506 | |
1507 if(got != "FOO") { | |
1508 errln("FAIL: getDisplayVariant()"); | |
1509 errln("Wanted: foo"); | |
1510 errln("Got : " + got); | |
1511 } | |
1512 | |
1513 Locale bogusVariant2("fr", "FR", "foo_"); | |
1514 bogusVariant2.getDisplayVariant(got); | |
1515 | |
1516 if(got != "FOO") { | |
1517 errln("FAIL: getDisplayVariant()"); | |
1518 errln("Wanted: foo"); | |
1519 errln("Got : " + got); | |
1520 } | |
1521 | |
1522 Locale bogusVariant3("fr", "FR", "_foo_"); | |
1523 bogusVariant3.getDisplayVariant(got); | |
1524 | |
1525 if(got != "FOO") { | |
1526 errln("FAIL: getDisplayVariant()"); | |
1527 errln("Wanted: foo"); | |
1528 errln("Got : " + got); | |
1529 } | |
1530 } | |
1531 | |
1532 #if !UCONFIG_NO_FORMATTING | |
1533 | |
1534 /** | |
1535 * @bug 4105828 | |
1536 * Currency symbol in zh is wrong. We will test this at the NumberFormat | |
1537 * end to test the whole pipe. | |
1538 */ | |
1539 void | |
1540 LocaleTest::Test4105828() | |
1541 { | |
1542 Locale LOC [] = { Locale::getChinese(), Locale("zh", "CN", ""), | |
1543 Locale("zh", "TW", ""), Locale("zh", "HK", "") }; | |
1544 UErrorCode status = U_ZERO_ERROR; | |
1545 for (int32_t i = 0; i < 4; ++i) { | |
1546 NumberFormat *fmt = NumberFormat::createPercentInstance(LOC[i], status); | |
1547 if(U_FAILURE(status)) { | |
1548 dataerrln("Couldn't create NumberFormat - %s", u_errorName(status)); | |
1549 return; | |
1550 } | |
1551 UnicodeString result; | |
1552 FieldPosition pos(0); | |
1553 fmt->format((int32_t)1, result, pos); | |
1554 UnicodeString temp; | |
1555 if(result != "100%") { | |
1556 errln(UnicodeString("Percent for ") + LOC[i].getDisplayName(temp) +
" should be 100%, got " + result); | |
1557 } | |
1558 delete fmt; | |
1559 } | |
1560 } | |
1561 | |
1562 #endif | |
1563 | |
1564 // Tests setBogus and isBogus APIs for Locale | |
1565 // Jitterbug 1735 | |
1566 void | |
1567 LocaleTest::TestSetIsBogus() { | |
1568 Locale l("en_US"); | |
1569 l.setToBogus(); | |
1570 if(l.isBogus() != TRUE) { | |
1571 errln("After setting bogus, didn't return TRUE"); | |
1572 } | |
1573 l = "en_US"; // This should reset bogus | |
1574 if(l.isBogus() != FALSE) { | |
1575 errln("After resetting bogus, didn't return FALSE"); | |
1576 } | |
1577 } | |
1578 | |
1579 | |
1580 void | |
1581 LocaleTest::TestKeywordVariants(void) { | |
1582 static const struct { | |
1583 const char *localeID; | |
1584 const char *expectedLocaleID; | |
1585 //const char *expectedLocaleIDNoKeywords; | |
1586 //const char *expectedCanonicalID; | |
1587 const char *expectedKeywords[10]; | |
1588 int32_t numKeywords; | |
1589 UErrorCode expectedStatus; | |
1590 } testCases[] = { | |
1591 { | |
1592 "de_DE@ currency = euro; C o ll A t i o n = Phonebook ; C alen
dar = buddhist ", | |
1593 "de_DE@calendar=buddhist;collation=Phonebook;currency=euro", | |
1594 //"de_DE", | |
1595 //"de_DE@calendar=buddhist;collation=Phonebook;currency=euro", | |
1596 {"calendar", "collation", "currency"}, | |
1597 3, | |
1598 U_ZERO_ERROR | |
1599 }, | |
1600 { | |
1601 "de_DE@euro", | |
1602 "de_DE@euro", | |
1603 //"de_DE", | |
1604 //"de_DE@currency=EUR", | |
1605 {"","","","","","",""}, | |
1606 0, | |
1607 U_INVALID_FORMAT_ERROR /* must have '=' after '@' */ | |
1608 } | |
1609 }; | |
1610 UErrorCode status = U_ZERO_ERROR; | |
1611 | |
1612 int32_t i = 0, j = 0; | |
1613 const char *result = NULL; | |
1614 StringEnumeration *keywords; | |
1615 int32_t keyCount = 0; | |
1616 const char *keyword = NULL; | |
1617 const UnicodeString *keywordString; | |
1618 int32_t keywordLen = 0; | |
1619 | |
1620 for(i = 0; i < (int32_t)(sizeof(testCases)/sizeof(testCases[0])); i++) { | |
1621 status = U_ZERO_ERROR; | |
1622 Locale l(testCases[i].localeID); | |
1623 keywords = l.createKeywords(status); | |
1624 | |
1625 if(status != testCases[i].expectedStatus) { | |
1626 err("Expected to get status %s. Got %s instead\n", | |
1627 u_errorName(testCases[i].expectedStatus), u_errorName(status)); | |
1628 } | |
1629 status = U_ZERO_ERROR; | |
1630 if(keywords) { | |
1631 if((keyCount = keywords->count(status)) != testCases[i].numKeywords)
{ | |
1632 err("Expected to get %i keywords, got %i\n", testCases[i].numKey
words, keyCount); | |
1633 } | |
1634 if(keyCount) { | |
1635 for(j = 0;;) { | |
1636 if((j&1)==0) { | |
1637 if((keyword = keywords->next(&keywordLen, status)) == NU
LL) { | |
1638 break; | |
1639 } | |
1640 if(strcmp(keyword, testCases[i].expectedKeywords[j]) !=
0) { | |
1641 err("Expected to get keyword value %s, got %s\n", te
stCases[i].expectedKeywords[j], keyword); | |
1642 } | |
1643 } else { | |
1644 if((keywordString = keywords->snext(status)) == NULL) { | |
1645 break; | |
1646 } | |
1647 if(*keywordString != UnicodeString(testCases[i].expected
Keywords[j], "")) { | |
1648 err("Expected to get keyword UnicodeString %s, got %
s\n", testCases[i].expectedKeywords[j], keyword); | |
1649 } | |
1650 } | |
1651 j++; | |
1652 | |
1653 if(j == keyCount / 2) { | |
1654 // replace keywords with a clone of itself | |
1655 StringEnumeration *k2 = keywords->clone(); | |
1656 if(k2 == NULL || keyCount != k2->count(status)) { | |
1657 errln("KeywordEnumeration.clone() failed"); | |
1658 } else { | |
1659 delete keywords; | |
1660 keywords = k2; | |
1661 } | |
1662 } | |
1663 } | |
1664 keywords->reset(status); // Make sure that reset works. | |
1665 for(j = 0;;) { | |
1666 if((keyword = keywords->next(&keywordLen, status)) == NULL)
{ | |
1667 break; | |
1668 } | |
1669 if(strcmp(keyword, testCases[i].expectedKeywords[j]) != 0) { | |
1670 err("Expected to get keyword value %s, got %s\n", testCa
ses[i].expectedKeywords[j], keyword); | |
1671 } | |
1672 j++; | |
1673 } | |
1674 } | |
1675 delete keywords; | |
1676 } | |
1677 result = l.getName(); | |
1678 if(uprv_strcmp(testCases[i].expectedLocaleID, result) != 0) { | |
1679 err("Expected to get \"%s\" from \"%s\". Got \"%s\" instead\n", | |
1680 testCases[i].expectedLocaleID, testCases[i].localeID, result); | |
1681 } | |
1682 | |
1683 } | |
1684 | |
1685 } | |
1686 | |
1687 void | |
1688 LocaleTest::TestKeywordVariantParsing(void) { | |
1689 static const struct { | |
1690 const char *localeID; | |
1691 const char *keyword; | |
1692 const char *expectedValue; | |
1693 } testCases[] = { | |
1694 { "de_DE@ C o ll A t i o n = Phonebook ", "collation", "Phonebook"
}, | |
1695 { "de_DE", "collation", ""}, | |
1696 { "de_DE@collation= PHONEBOOK", "collation", "PHONEBOOK" }, | |
1697 { "de_DE@ currency = euro ; CoLLaTion = PHONEBOOk ", "collation",
"PHONEBOOk" }, | |
1698 }; | |
1699 | |
1700 UErrorCode status = U_ZERO_ERROR; | |
1701 | |
1702 int32_t i = 0; | |
1703 int32_t resultLen = 0; | |
1704 char buffer[256]; | |
1705 | |
1706 for(i = 0; i < (int32_t)(sizeof(testCases)/sizeof(testCases[0])); i++) { | |
1707 *buffer = 0; | |
1708 Locale l(testCases[i].localeID); | |
1709 resultLen = l.getKeywordValue(testCases[i].keyword, buffer, 256, status)
; | |
1710 (void)resultLen; // Suppress unused variable warning. | |
1711 if(uprv_strcmp(testCases[i].expectedValue, buffer) != 0) { | |
1712 err("Expected to extract \"%s\" from \"%s\" for keyword \"%s\". Got
\"%s\" instead\n", | |
1713 testCases[i].expectedValue, testCases[i].localeID, testCases[i].
keyword, buffer); | |
1714 } | |
1715 } | |
1716 } | |
1717 | |
1718 void | |
1719 LocaleTest::TestSetKeywordValue(void) { | |
1720 static const struct { | |
1721 const char *keyword; | |
1722 const char *value; | |
1723 } testCases[] = { | |
1724 { "collation", "phonebook" }, | |
1725 { "currency", "euro" }, | |
1726 { "calendar", "buddhist" } | |
1727 }; | |
1728 | |
1729 UErrorCode status = U_ZERO_ERROR; | |
1730 | |
1731 int32_t i = 0; | |
1732 int32_t resultLen = 0; | |
1733 char buffer[256]; | |
1734 | |
1735 Locale l(Locale::getGerman()); | |
1736 | |
1737 for(i = 0; i < (int32_t)(sizeof(testCases)/sizeof(testCases[0])); i++) { | |
1738 l.setKeywordValue(testCases[i].keyword, testCases[i].value, status); | |
1739 if(U_FAILURE(status)) { | |
1740 err("FAIL: Locale::setKeywordValue failed - %s\n", u_errorName(statu
s)); | |
1741 } | |
1742 | |
1743 *buffer = 0; | |
1744 resultLen = l.getKeywordValue(testCases[i].keyword, buffer, 256, status)
; | |
1745 (void)resultLen; // Suppress unused variable warning. | |
1746 if(uprv_strcmp(testCases[i].value, buffer) != 0) { | |
1747 err("Expected to extract \"%s\" for keyword \"%s\". Got \"%s\" inste
ad\n", | |
1748 testCases[i].value, testCases[i].keyword, buffer); | |
1749 } | |
1750 } | |
1751 } | |
1752 | |
1753 void | |
1754 LocaleTest::TestGetBaseName(void) { | |
1755 static const struct { | |
1756 const char *localeID; | |
1757 const char *baseName; | |
1758 } testCases[] = { | |
1759 { "de_DE@ C o ll A t i o n = Phonebook ", "de_DE" }, | |
1760 { "de@currency = euro; CoLLaTion = PHONEBOOk", "de" }, | |
1761 { "ja@calendar = buddhist", "ja" }, | |
1762 { "de-u-co-phonebk", "de"} | |
1763 }; | |
1764 | |
1765 int32_t i = 0; | |
1766 | |
1767 for(i = 0; i < UPRV_LENGTHOF(testCases); i++) { | |
1768 Locale loc(testCases[i].localeID); | |
1769 if(strcmp(testCases[i].baseName, loc.getBaseName())) { | |
1770 errln("For locale \"%s\" expected baseName \"%s\", but got \"%s\"", | |
1771 testCases[i].localeID, testCases[i].baseName, loc.getBaseName())
; | |
1772 return; | |
1773 } | |
1774 } | |
1775 | |
1776 // Verify that adding a keyword to an existing Locale doesn't change the bas
e name. | |
1777 UErrorCode status = U_ZERO_ERROR; | |
1778 Locale loc2("en-US"); | |
1779 if (strcmp("en_US", loc2.getBaseName())) { | |
1780 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__, __LINE__, loc2.g
etBaseName()); | |
1781 } | |
1782 loc2.setKeywordValue("key", "value", status); | |
1783 if (strcmp("en_US@key=value", loc2.getName())) { | |
1784 errln("%s:%d Expected \"en_US@key=value\", got \"%s\"", __FILE__, __LINE
__, loc2.getName()); | |
1785 } | |
1786 if (strcmp("en_US", loc2.getBaseName())) { | |
1787 errln("%s:%d Expected \"en_US\", got \"%s\"", __FILE__, __LINE__, loc2.g
etBaseName()); | |
1788 } | |
1789 } | |
1790 | |
1791 /** | |
1792 * Compare two locale IDs. If they are equal, return 0. If `string' | |
1793 * starts with `prefix' plus an additional element, that is, string == | |
1794 * prefix + '_' + x, then return 1. Otherwise return a value < 0. | |
1795 */ | |
1796 static UBool _loccmp(const char* string, const char* prefix) { | |
1797 int32_t slen = (int32_t)strlen(string), | |
1798 plen = (int32_t)strlen(prefix); | |
1799 int32_t c = uprv_strncmp(string, prefix, plen); | |
1800 /* 'root' is "less than" everything */ | |
1801 if (uprv_strcmp(prefix, "root") == 0) { | |
1802 return (uprv_strcmp(string, "root") == 0) ? 0 : 1; | |
1803 } | |
1804 if (c) return -1; /* mismatch */ | |
1805 if (slen == plen) return 0; | |
1806 if (string[plen] == '_') return 1; | |
1807 return -2; /* false match, e.g. "en_USX" cmp "en_US" */ | |
1808 } | |
1809 | |
1810 /** | |
1811 * Check the relationship between requested locales, and report problems. | |
1812 * The caller specifies the expected relationships between requested | |
1813 * and valid (expReqValid) and between valid and actual (expValidActual). | |
1814 * Possible values are: | |
1815 * "gt" strictly greater than, e.g., en_US > en | |
1816 * "ge" greater or equal, e.g., en >= en | |
1817 * "eq" equal, e.g., en == en | |
1818 */ | |
1819 void LocaleTest::_checklocs(const char* label, | |
1820 const char* req, | |
1821 const Locale& validLoc, | |
1822 const Locale& actualLoc, | |
1823 const char* expReqValid, | |
1824 const char* expValidActual) { | |
1825 const char* valid = validLoc.getName(); | |
1826 const char* actual = actualLoc.getName(); | |
1827 int32_t reqValid = _loccmp(req, valid); | |
1828 int32_t validActual = _loccmp(valid, actual); | |
1829 if (((0 == uprv_strcmp(expReqValid, "gt") && reqValid > 0) || | |
1830 (0 == uprv_strcmp(expReqValid, "ge") && reqValid >= 0) || | |
1831 (0 == uprv_strcmp(expReqValid, "eq") && reqValid == 0)) && | |
1832 ((0 == uprv_strcmp(expValidActual, "gt") && validActual > 0) || | |
1833 (0 == uprv_strcmp(expValidActual, "ge") && validActual >= 0) || | |
1834 (0 == uprv_strcmp(expValidActual, "eq") && validActual == 0))) { | |
1835 logln("%s; req=%s, valid=%s, actual=%s", | |
1836 label, req, valid, actual); | |
1837 } else { | |
1838 dataerrln("FAIL: %s; req=%s, valid=%s, actual=%s. Require (R %s V) and
(V %s A)", | |
1839 label, req, valid, actual, | |
1840 expReqValid, expValidActual); | |
1841 } | |
1842 } | |
1843 | |
1844 void LocaleTest::TestGetLocale(void) { | |
1845 #if !UCONFIG_NO_SERVICE | |
1846 const char *req; | |
1847 Locale valid, actual, reqLoc; | |
1848 | |
1849 // Calendar | |
1850 #if !UCONFIG_NO_FORMATTING | |
1851 { | |
1852 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error
code | |
1853 req = "en_US_BROOKLYN"; | |
1854 Calendar* cal = Calendar::createInstance(Locale::createFromName(req), ec
); | |
1855 if (U_FAILURE(ec)) { | |
1856 dataerrln("FAIL: Calendar::createInstance failed - %s", u_errorName(
ec)); | |
1857 } else { | |
1858 valid = cal->getLocale(ULOC_VALID_LOCALE, ec); | |
1859 actual = cal->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
1860 if (U_FAILURE(ec)) { | |
1861 errln("FAIL: Calendar::getLocale() failed"); | |
1862 } else { | |
1863 _checklocs("Calendar", req, valid, actual); | |
1864 } | |
1865 /* Make sure that it fails correctly */ | |
1866 ec = U_FILE_ACCESS_ERROR; | |
1867 if (cal->getLocale(ULOC_VALID_LOCALE, ec).getName()[0] != 0) { | |
1868 errln("FAIL: Calendar::getLocale() failed to fail correctly. It
should have returned \"\""); | |
1869 } | |
1870 ec = U_ZERO_ERROR; | |
1871 } | |
1872 delete cal; | |
1873 } | |
1874 #endif | |
1875 | |
1876 // DecimalFormat, DecimalFormatSymbols | |
1877 #if !UCONFIG_NO_FORMATTING | |
1878 { | |
1879 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error
code | |
1880 req = "fr_FR_NICE"; | |
1881 NumberFormat* nf = NumberFormat::createInstance(Locale::createFromName(r
eq), ec); | |
1882 if (U_FAILURE(ec)) { | |
1883 dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorN
ame(ec)); | |
1884 } else { | |
1885 DecimalFormat* dec = dynamic_cast<DecimalFormat*>(nf); | |
1886 if (dec == NULL) { | |
1887 errln("FAIL: NumberFormat::createInstance does not return a Deci
malFormat"); | |
1888 return; | |
1889 } | |
1890 valid = dec->getLocale(ULOC_VALID_LOCALE, ec); | |
1891 actual = dec->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
1892 if (U_FAILURE(ec)) { | |
1893 errln("FAIL: DecimalFormat::getLocale() failed"); | |
1894 } else { | |
1895 _checklocs("DecimalFormat", req, valid, actual); | |
1896 } | |
1897 | |
1898 const DecimalFormatSymbols* sym = dec->getDecimalFormatSymbols(); | |
1899 if (sym == NULL) { | |
1900 errln("FAIL: getDecimalFormatSymbols returned NULL"); | |
1901 return; | |
1902 } | |
1903 valid = sym->getLocale(ULOC_VALID_LOCALE, ec); | |
1904 actual = sym->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
1905 if (U_FAILURE(ec)) { | |
1906 errln("FAIL: DecimalFormatSymbols::getLocale() failed"); | |
1907 } else { | |
1908 _checklocs("DecimalFormatSymbols", req, valid, actual); | |
1909 } | |
1910 } | |
1911 delete nf; | |
1912 } | |
1913 #endif | |
1914 | |
1915 // DateFormat, DateFormatSymbols | |
1916 #if !UCONFIG_NO_FORMATTING | |
1917 { | |
1918 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error
code | |
1919 req = "de_CH_LUCERNE"; | |
1920 DateFormat* df = | |
1921 DateFormat::createDateInstance(DateFormat::kDefault, | |
1922 Locale::createFromName(req)); | |
1923 if (df == 0){ | |
1924 dataerrln("Error calling DateFormat::createDateInstance()"); | |
1925 } else { | |
1926 SimpleDateFormat* dat = dynamic_cast<SimpleDateFormat*>(df); | |
1927 if (dat == NULL) { | |
1928 errln("FAIL: DateFormat::createInstance does not return a Simple
DateFormat"); | |
1929 return; | |
1930 } | |
1931 valid = dat->getLocale(ULOC_VALID_LOCALE, ec); | |
1932 actual = dat->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
1933 if (U_FAILURE(ec)) { | |
1934 errln("FAIL: SimpleDateFormat::getLocale() failed"); | |
1935 } else { | |
1936 _checklocs("SimpleDateFormat", req, valid, actual); | |
1937 } | |
1938 | |
1939 const DateFormatSymbols* sym = dat->getDateFormatSymbols(); | |
1940 if (sym == NULL) { | |
1941 errln("FAIL: getDateFormatSymbols returned NULL"); | |
1942 return; | |
1943 } | |
1944 valid = sym->getLocale(ULOC_VALID_LOCALE, ec); | |
1945 actual = sym->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
1946 if (U_FAILURE(ec)) { | |
1947 errln("FAIL: DateFormatSymbols::getLocale() failed"); | |
1948 } else { | |
1949 _checklocs("DateFormatSymbols", req, valid, actual); | |
1950 } | |
1951 } | |
1952 delete df; | |
1953 } | |
1954 #endif | |
1955 | |
1956 // BreakIterator | |
1957 #if !UCONFIG_NO_BREAK_ITERATION | |
1958 { | |
1959 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error
code | |
1960 req = "es_ES_BARCELONA"; | |
1961 reqLoc = Locale::createFromName(req); | |
1962 BreakIterator* brk = BreakIterator::createWordInstance(reqLoc, ec); | |
1963 if (U_FAILURE(ec)) { | |
1964 dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_e
rrorName(ec)); | |
1965 } else { | |
1966 valid = brk->getLocale(ULOC_VALID_LOCALE, ec); | |
1967 actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
1968 if (U_FAILURE(ec)) { | |
1969 errln("FAIL: BreakIterator::getLocale() failed"); | |
1970 } else { | |
1971 _checklocs("BreakIterator", req, valid, actual); | |
1972 } | |
1973 | |
1974 // After registering something, the behavior should be different | |
1975 URegistryKey key = BreakIterator::registerInstance(brk, reqLoc, UBRK
_WORD, ec); | |
1976 brk = 0; // registerInstance adopts | |
1977 if (U_FAILURE(ec)) { | |
1978 errln("FAIL: BreakIterator::registerInstance() failed"); | |
1979 } else { | |
1980 brk = BreakIterator::createWordInstance(reqLoc, ec); | |
1981 if (U_FAILURE(ec)) { | |
1982 errln("FAIL: BreakIterator::createWordInstance failed"); | |
1983 } else { | |
1984 valid = brk->getLocale(ULOC_VALID_LOCALE, ec); | |
1985 actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
1986 if (U_FAILURE(ec)) { | |
1987 errln("FAIL: BreakIterator::getLocale() failed"); | |
1988 } else { | |
1989 // N.B.: now expect valid==actual==req | |
1990 _checklocs("BreakIterator(registered)", | |
1991 req, valid, actual, "eq", "eq"); | |
1992 } | |
1993 } | |
1994 // No matter what, unregister | |
1995 BreakIterator::unregister(key, ec); | |
1996 if (U_FAILURE(ec)) { | |
1997 errln("FAIL: BreakIterator::unregister() failed"); | |
1998 } | |
1999 delete brk; | |
2000 brk = 0; | |
2001 } | |
2002 | |
2003 // After unregistering, should behave normally again | |
2004 brk = BreakIterator::createWordInstance(reqLoc, ec); | |
2005 if (U_FAILURE(ec)) { | |
2006 errln("FAIL: BreakIterator::createWordInstance failed"); | |
2007 } else { | |
2008 valid = brk->getLocale(ULOC_VALID_LOCALE, ec); | |
2009 actual = brk->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
2010 if (U_FAILURE(ec)) { | |
2011 errln("FAIL: BreakIterator::getLocale() failed"); | |
2012 } else { | |
2013 _checklocs("BreakIterator(unregistered)", req, valid, actual
); | |
2014 } | |
2015 } | |
2016 } | |
2017 delete brk; | |
2018 } | |
2019 #endif | |
2020 | |
2021 // Collator | |
2022 #if !UCONFIG_NO_COLLATION | |
2023 { | |
2024 UErrorCode ec = U_ZERO_ERROR; // give each resource type its own error
code | |
2025 | |
2026 checkRegisteredCollators(NULL); // Don't expect any extras | |
2027 | |
2028 req = "hi_IN_BHOPAL"; | |
2029 reqLoc = Locale::createFromName(req); | |
2030 Collator* coll = Collator::createInstance(reqLoc, ec); | |
2031 if (U_FAILURE(ec)) { | |
2032 dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(
ec)); | |
2033 } else { | |
2034 valid = coll->getLocale(ULOC_VALID_LOCALE, ec); | |
2035 actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
2036 if (U_FAILURE(ec)) { | |
2037 errln("FAIL: Collator::getLocale() failed"); | |
2038 } else { | |
2039 _checklocs("Collator", req, valid, actual); | |
2040 } | |
2041 | |
2042 // After registering something, the behavior should be different | |
2043 URegistryKey key = Collator::registerInstance(coll, reqLoc, ec); | |
2044 coll = 0; // registerInstance adopts | |
2045 if (U_FAILURE(ec)) { | |
2046 errln("FAIL: Collator::registerInstance() failed"); | |
2047 } else { | |
2048 coll = Collator::createInstance(reqLoc, ec); | |
2049 if (U_FAILURE(ec)) { | |
2050 errln("FAIL: Collator::createWordInstance failed"); | |
2051 } else { | |
2052 valid = coll->getLocale(ULOC_VALID_LOCALE, ec); | |
2053 actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
2054 if (U_FAILURE(ec)) { | |
2055 errln("FAIL: Collator::getLocale() failed"); | |
2056 } else { | |
2057 // N.B.: now expect valid==actual==req | |
2058 _checklocs("Collator(registered)", | |
2059 req, valid, actual, "eq", "eq"); | |
2060 } | |
2061 } | |
2062 checkRegisteredCollators(req); // include hi_IN_BHOPAL | |
2063 | |
2064 // No matter what, unregister | |
2065 Collator::unregister(key, ec); | |
2066 if (U_FAILURE(ec)) { | |
2067 errln("FAIL: Collator::unregister() failed"); | |
2068 } | |
2069 delete coll; | |
2070 coll = 0; | |
2071 } | |
2072 | |
2073 // After unregistering, should behave normally again | |
2074 coll = Collator::createInstance(reqLoc, ec); | |
2075 if (U_FAILURE(ec)) { | |
2076 errln("FAIL: Collator::createInstance failed"); | |
2077 } else { | |
2078 valid = coll->getLocale(ULOC_VALID_LOCALE, ec); | |
2079 actual = coll->getLocale(ULOC_ACTUAL_LOCALE, ec); | |
2080 if (U_FAILURE(ec)) { | |
2081 errln("FAIL: Collator::getLocale() failed"); | |
2082 } else { | |
2083 _checklocs("Collator(unregistered)", req, valid, actual); | |
2084 } | |
2085 } | |
2086 } | |
2087 delete coll; | |
2088 | |
2089 checkRegisteredCollators(NULL); // extra should be gone again | |
2090 } | |
2091 #endif | |
2092 #endif | |
2093 } | |
2094 | |
2095 #if !UCONFIG_NO_COLLATION | |
2096 /** | |
2097 * Compare Collator::getAvailableLocales(int) [ "old", returning an array ] | |
2098 * with Collator::getAvailableLocales() [ "new", returning a StringEnumera
tion ] | |
2099 * These should be identical (check their API docs) EXCEPT that | |
2100 * if expectExtra is non-NULL, it will be in the "new" array but not "old". | |
2101 * Does not return any status but calls errln on error. | |
2102 * @param expectExtra an extra locale, will be in "new" but not "old". Or NULL. | |
2103 */ | |
2104 void LocaleTest::checkRegisteredCollators(const char *expectExtra) { | |
2105 UErrorCode status = U_ZERO_ERROR; | |
2106 int32_t count1=0,count2=0; | |
2107 Hashtable oldHash(status); | |
2108 Hashtable newHash(status); | |
2109 TEST_ASSERT_STATUS(status); | |
2110 | |
2111 UnicodeString expectStr(expectExtra?expectExtra:"n/a", ""); | |
2112 | |
2113 // the 'old' list (non enumeration) | |
2114 const Locale* oldList = Collator::getAvailableLocales(count1); | |
2115 if(oldList == NULL) { | |
2116 dataerrln("Error: Collator::getAvailableLocales(count) returned NULL"); | |
2117 return; | |
2118 } | |
2119 | |
2120 // the 'new' list (enumeration) | |
2121 LocalPointer<StringEnumeration> newEnum(Collator::getAvailableLocales()); | |
2122 if(newEnum.isNull()) { | |
2123 errln("Error: collator::getAvailableLocales() returned NULL"); | |
2124 return; | |
2125 } | |
2126 | |
2127 // OK. Let's add all of the OLD | |
2128 // then check for any in the NEW not in OLD | |
2129 // then check for any in OLD not in NEW. | |
2130 | |
2131 // 1. add all of OLD | |
2132 for(int32_t i=0;i<count1;i++) { | |
2133 const UnicodeString key(oldList[i].getName(), ""); | |
2134 int32_t oldI = oldHash.puti(key, 1, status); | |
2135 if( oldI == 1 ){ | |
2136 errln("Error: duplicate key %s in Collator::getAvailableLocales(coun
t) list.\n", | |
2137 oldList[i].getName()); | |
2138 return; | |
2139 } | |
2140 if(expectExtra != NULL && !strcmp(expectExtra, oldList[i].getName())) { | |
2141 errln("Inexplicably, Collator::getAvailableCollators(count) had regi
stered collator %s. This shouldn't happen, so I am going to consider it an error
.\n", expectExtra); | |
2142 } | |
2143 } | |
2144 | |
2145 // 2. add all of NEW | |
2146 const UnicodeString *locStr; | |
2147 UBool foundExpected = FALSE; | |
2148 while((locStr = newEnum->snext(status)) && U_SUCCESS(status)) { | |
2149 count2++; | |
2150 | |
2151 if(expectExtra != NULL && expectStr == *locStr) { | |
2152 foundExpected = TRUE; | |
2153 logln(UnicodeString("Found expected registered collator: ","") + exp
ectStr); | |
2154 } | |
2155 (void)foundExpected; // Hush unused variable compiler warning. | |
2156 | |
2157 if( oldHash.geti(*locStr) == 0 ) { | |
2158 if(expectExtra != NULL && expectStr==*locStr) { | |
2159 logln(UnicodeString("As expected, Collator::getAvailableLocales(
count) is missing registered collator ") + expectStr); | |
2160 } else { | |
2161 errln(UnicodeString("Error: Collator::getAvailableLocales(count)
is missing: ","") | |
2162 + *locStr); | |
2163 } | |
2164 } | |
2165 newHash.puti(*locStr, 1, status); | |
2166 } | |
2167 | |
2168 // 3. check all of OLD again | |
2169 for(int32_t i=0;i<count1;i++) { | |
2170 const UnicodeString key(oldList[i].getName(), ""); | |
2171 int32_t newI = newHash.geti(key); | |
2172 if(newI == 0) { | |
2173 errln(UnicodeString("Error: Collator::getAvailableLocales() is missi
ng: ","") | |
2174 + key); | |
2175 } | |
2176 } | |
2177 | |
2178 int32_t expectCount2 = count1; | |
2179 if(expectExtra != NULL) { | |
2180 expectCount2 ++; // if an extra item registered, bump the expect count | |
2181 } | |
2182 | |
2183 assertEquals("Collator::getAvail() count", expectCount2, count2); | |
2184 } | |
2185 #endif | |
2186 | |
2187 | |
2188 | |
2189 void LocaleTest::TestVariantWithOutCountry(void) { | |
2190 Locale loc("en","","POSIX"); | |
2191 if (0 != strcmp(loc.getVariant(), "POSIX")) { | |
2192 errln("FAIL: en__POSIX didn't get parsed correctly - name is %s - expect
ed %s got %s", loc.getName(), "POSIX", loc.getVariant()); | |
2193 } | |
2194 Locale loc2("en","","FOUR"); | |
2195 if (0 != strcmp(loc2.getVariant(), "FOUR")) { | |
2196 errln("FAIL: en__FOUR didn't get parsed correctly - name is %s - expecte
d %s got %s", loc2.getName(), "FOUR", loc2.getVariant()); | |
2197 } | |
2198 Locale loc3("en","Latn","","FOUR"); | |
2199 if (0 != strcmp(loc3.getVariant(), "FOUR")) { | |
2200 errln("FAIL: en_Latn__FOUR didn't get parsed correctly - name is %s - ex
pected %s got %s", loc3.getName(), "FOUR", loc3.getVariant()); | |
2201 } | |
2202 Locale loc4("","Latn","","FOUR"); | |
2203 if (0 != strcmp(loc4.getVariant(), "FOUR")) { | |
2204 errln("FAIL: _Latn__FOUR didn't get parsed correctly - name is %s - expe
cted %s got %s", loc4.getName(), "FOUR", loc4.getVariant()); | |
2205 } | |
2206 Locale loc5("","Latn","US","FOUR"); | |
2207 if (0 != strcmp(loc5.getVariant(), "FOUR")) { | |
2208 errln("FAIL: _Latn_US_FOUR didn't get parsed correctly - name is %s - ex
pected %s got %s", loc5.getName(), "FOUR", loc5.getVariant()); | |
2209 } | |
2210 Locale loc6("de-1901"); | |
2211 if (0 != strcmp(loc6.getVariant(), "1901")) { | |
2212 errln("FAIL: de-1901 didn't get parsed correctly - name is %s - expected
%s got %s", loc6.getName(), "1901", loc6.getVariant()); | |
2213 } | |
2214 } | |
2215 | |
2216 static Locale _canonicalize(int32_t selector, /* 0==createFromName, 1==createCan
onical, 2==Locale ct */ | |
2217 const char* localeID) { | |
2218 switch (selector) { | |
2219 case 0: | |
2220 return Locale::createFromName(localeID); | |
2221 case 1: | |
2222 return Locale::createCanonical(localeID); | |
2223 case 2: | |
2224 return Locale(localeID); | |
2225 default: | |
2226 return Locale(""); | |
2227 } | |
2228 } | |
2229 | |
2230 void LocaleTest::TestCanonicalization(void) | |
2231 { | |
2232 static const struct { | |
2233 const char *localeID; /* input */ | |
2234 const char *getNameID; /* expected getName() result */ | |
2235 const char *canonicalID; /* expected canonicalize() result */ | |
2236 } testCases[] = { | |
2237 { "", "", "en_US_POSIX" }, | |
2238 { "C", "c", "en_US_POSIX" }, | |
2239 { "POSIX", "posix", "en_US_POSIX" }, | |
2240 { "ca_ES_PREEURO-with-extra-stuff-that really doesn't make any sense-unl
ess-you're trying to increase code coverage", | |
2241 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNL
ESS_YOU'RE TRYING TO INCREASE CODE COVERAGE", | |
2242 "ca_ES_PREEURO_WITH_EXTRA_STUFF_THAT REALLY DOESN'T MAKE ANY SENSE_UNL
ESS_YOU'RE TRYING TO INCREASE CODE COVERAGE"}, | |
2243 { "ca_ES_PREEURO", "ca_ES_PREEURO", "ca_ES@currency=ESP" }, | |
2244 { "de_AT_PREEURO", "de_AT_PREEURO", "de_AT@currency=ATS" }, | |
2245 { "de_DE_PREEURO", "de_DE_PREEURO", "de_DE@currency=DEM" }, | |
2246 { "de_LU_PREEURO", "de_LU_PREEURO", "de_LU@currency=LUF" }, | |
2247 { "el_GR_PREEURO", "el_GR_PREEURO", "el_GR@currency=GRD" }, | |
2248 { "en_BE_PREEURO", "en_BE_PREEURO", "en_BE@currency=BEF" }, | |
2249 { "en_IE_PREEURO", "en_IE_PREEURO", "en_IE@currency=IEP" }, | |
2250 { "es_ES_PREEURO", "es_ES_PREEURO", "es_ES@currency=ESP" }, | |
2251 { "eu_ES_PREEURO", "eu_ES_PREEURO", "eu_ES@currency=ESP" }, | |
2252 { "fi_FI_PREEURO", "fi_FI_PREEURO", "fi_FI@currency=FIM" }, | |
2253 { "fr_BE_PREEURO", "fr_BE_PREEURO", "fr_BE@currency=BEF" }, | |
2254 { "fr_FR_PREEURO", "fr_FR_PREEURO", "fr_FR@currency=FRF" }, | |
2255 { "fr_LU_PREEURO", "fr_LU_PREEURO", "fr_LU@currency=LUF" }, | |
2256 { "ga_IE_PREEURO", "ga_IE_PREEURO", "ga_IE@currency=IEP" }, | |
2257 { "gl_ES_PREEURO", "gl_ES_PREEURO", "gl_ES@currency=ESP" }, | |
2258 { "it_IT_PREEURO", "it_IT_PREEURO", "it_IT@currency=ITL" }, | |
2259 { "nl_BE_PREEURO", "nl_BE_PREEURO", "nl_BE@currency=BEF" }, | |
2260 { "nl_NL_PREEURO", "nl_NL_PREEURO", "nl_NL@currency=NLG" }, | |
2261 { "pt_PT_PREEURO", "pt_PT_PREEURO", "pt_PT@currency=PTE" }, | |
2262 { "de__PHONEBOOK", "de__PHONEBOOK", "de@collation=phonebook" }, | |
2263 { "en_GB_EURO", "en_GB_EURO", "en_GB@currency=EUR" }, | |
2264 { "en_GB@EURO", "en_GB@EURO", "en_GB@currency=EUR" }, /* POSIX ID */ | |
2265 { "es__TRADITIONAL", "es__TRADITIONAL", "es@collation=traditional" }, | |
2266 { "hi__DIRECT", "hi__DIRECT", "hi@collation=direct" }, | |
2267 { "ja_JP_TRADITIONAL", "ja_JP_TRADITIONAL", "ja_JP@calendar=japanese" }, | |
2268 { "th_TH_TRADITIONAL", "th_TH_TRADITIONAL", "th_TH@calendar=buddhist" }, | |
2269 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" }, | |
2270 { "zh__PINYIN", "zh__PINYIN", "zh@collation=pinyin" }, | |
2271 { "zh@collation=pinyin", "zh@collation=pinyin", "zh@collation=pinyin" }, | |
2272 { "zh_CN@collation=pinyin", "zh_CN@collation=pinyin", "zh_CN@collation=p
inyin" }, | |
2273 { "zh_CN_CA@collation=pinyin", "zh_CN_CA@collation=pinyin", "zh_CN_CA@co
llation=pinyin" }, | |
2274 { "en_US_POSIX", "en_US_POSIX", "en_US_POSIX" }, | |
2275 { "hy_AM_REVISED", "hy_AM_REVISED", "hy_AM_REVISED" }, | |
2276 { "no_NO_NY", "no_NO_NY", "no_NO_NY" /* not: "nn_NO" [alan ICU3.0] */ }, | |
2277 { "no@ny", "no@ny", "no__NY" /* not: "nn" [alan ICU3.0] */ }, /* POSIX I
D */ | |
2278 { "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B" /* not: "nb_NO_B" [alan IC
U3.0] */ }, /* POSIX ID */ | |
2279 { "qz-qz@Euro", "qz_QZ@Euro", "qz_QZ@currency=EUR" }, /* qz-qz uses priv
ate use iso codes */ | |
2280 // NOTE: uloc_getName() works on en-BOONT, but Locale() parser considers
it BOGUS | |
2281 // TODO: unify this behavior | |
2282 { "en-BOONT", "en__BOONT", "en__BOONT" }, /* registered name */ | |
2283 { "de-1901", "de__1901", "de__1901" }, /* registered name */ | |
2284 { "de-1906", "de__1906", "de__1906" }, /* registered name */ | |
2285 { "sr-SP-Cyrl", "sr_SP_CYRL", "sr_Cyrl_RS" }, /* .NET name */ | |
2286 { "sr-SP-Latn", "sr_SP_LATN", "sr_Latn_RS" }, /* .NET name */ | |
2287 { "sr_YU_CYRILLIC", "sr_YU_CYRILLIC", "sr_Cyrl_RS" }, /* Linux name */ | |
2288 { "uz-UZ-Cyrl", "uz_UZ_CYRL", "uz_Cyrl_UZ" }, /* .NET name */ | |
2289 { "uz-UZ-Latn", "uz_UZ_LATN", "uz_Latn_UZ" }, /* .NET name */ | |
2290 { "zh-CHS", "zh_CHS", "zh_Hans" }, /* .NET name */ | |
2291 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to
zh_Hant */ | |
2292 | |
2293 /* posix behavior that used to be performed by getName */ | |
2294 { "mr.utf8", "mr.utf8", "mr" }, | |
2295 { "de-tv.koi8r", "de_TV.koi8r", "de_TV" }, | |
2296 { "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML" }, | |
2297 { "i-cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US" }, | |
2298 { "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfl
i_MT_FILFLA" }, | |
2299 { "no-no-ny.utf8@B", "no_NO_NY.utf8@B", "no_NO_NY_B" /* not: "nn_NO" [al
an ICU3.0] */ }, /* @ ignored unless variant is empty */ | |
2300 | |
2301 /* fleshing out canonicalization */ | |
2302 /* trim space and sort keywords, ';' is separator so not present at end
in canonical form */ | |
2303 { "en_Hant_IL_VALLEY_GIRL@ currency = EUR; calendar = Japanese ;", "en_H
ant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@cale
ndar=Japanese;currency=EUR" }, | |
2304 /* already-canonical ids are not changed */ | |
2305 { "en_Hant_IL_VALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_V
ALLEY_GIRL@calendar=Japanese;currency=EUR", "en_Hant_IL_VALLEY_GIRL@calendar=Jap
anese;currency=EUR" }, | |
2306 /* PRE_EURO and EURO conversions don't affect other keywords */ | |
2307 { "es_ES_PREEURO@CALendar=Japanese", "es_ES_PREEURO@calendar=Japanese",
"es_ES@calendar=Japanese;currency=ESP" }, | |
2308 { "es_ES_EURO@SHOUT=zipeedeedoodah", "es_ES_EURO@shout=zipeedeedoodah",
"es_ES@currency=EUR;shout=zipeedeedoodah" }, | |
2309 /* currency keyword overrides PRE_EURO and EURO currency */ | |
2310 { "es_ES_PREEURO@currency=EUR", "es_ES_PREEURO@currency=EUR", "es_ES@cur
rency=EUR" }, | |
2311 { "es_ES_EURO@currency=ESP", "es_ES_EURO@currency=ESP", "es_ES@currency=
ESP" }, | |
2312 /* norwegian is just too weird, if we handle things in their full genera
lity */ | |
2313 { "no-Hant-GB_NY@currency=$$$", "no_Hant_GB_NY@currency=$$$", "no_Hant_G
B_NY@currency=$$$" /* not: "nn_Hant_GB@currency=$$$" [alan ICU3.0] */ }, | |
2314 | |
2315 /* test cases reflecting internal resource bundle usage */ | |
2316 { "root@kw=foo", "root@kw=foo", "root@kw=foo" }, | |
2317 { "@calendar=gregorian", "@calendar=gregorian", "@calendar=gregorian" }, | |
2318 { "ja_JP@calendar=Japanese", "ja_JP@calendar=Japanese", "ja_JP@calendar=
Japanese" } | |
2319 }; | |
2320 | |
2321 static const char* label[] = { "createFromName", "createCanonical", "Locale"
}; | |
2322 | |
2323 int32_t i, j; | |
2324 | |
2325 for (i=0; i < (int)(sizeof(testCases)/sizeof(testCases[0])); i++) { | |
2326 for (j=0; j<3; ++j) { | |
2327 const char* expected = (j==1) ? testCases[i].canonicalID : testCases
[i].getNameID; | |
2328 Locale loc = _canonicalize(j, testCases[i].localeID); | |
2329 const char* getName = loc.isBogus() ? "BOGUS" : loc.getName(); | |
2330 if(uprv_strcmp(expected, getName) != 0) { | |
2331 errln("FAIL: %s(%s).getName() => \"%s\", expected \"%s\"", | |
2332 label[j], testCases[i].localeID, getName, expected); | |
2333 } else { | |
2334 logln("Ok: %s(%s) => \"%s\"", | |
2335 label[j], testCases[i].localeID, getName); | |
2336 } | |
2337 } | |
2338 } | |
2339 } | |
2340 | |
2341 void LocaleTest::TestCurrencyByDate(void) | |
2342 { | |
2343 #if !UCONFIG_NO_FORMATTING | |
2344 UErrorCode status = U_ZERO_ERROR; | |
2345 UDate date = uprv_getUTCtime(); | |
2346 UChar TMP[4]; | |
2347 int32_t index = 0; | |
2348 int32_t resLen = 0; | |
2349 UnicodeString tempStr, resultStr; | |
2350 | |
2351 // Cycle through historical currencies | |
2352 date = (UDate)-630720000000.0; // pre 1961 - no currency defined | |
2353 index = ucurr_countCurrencies("eo_AM", date, &status); | |
2354 if (index != 0) | |
2355 { | |
2356 errcheckln(status, "FAIL: didn't return 0 for eo_AM - %s", u_err
orName(status)); | |
2357 } | |
2358 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status); | |
2359 if (resLen != 0) { | |
2360 errcheckln(status, "FAIL: eo_AM didn't return NULL - %s", u_erro
rName(status)); | |
2361 } | |
2362 status = U_ZERO_ERROR; | |
2363 | |
2364 date = (UDate)0.0; // 1970 - one currency defined | |
2365 index = ucurr_countCurrencies("eo_AM", date, &status); | |
2366 if (index != 1) | |
2367 { | |
2368 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_err
orName(status)); | |
2369 } | |
2370 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status); | |
2371 tempStr.setTo(TMP); | |
2372 resultStr.setTo("SUR"); | |
2373 if (resultStr != tempStr) { | |
2374 errcheckln(status, "FAIL: didn't return SUR for eo_AM - %s", u_errorName
(status)); | |
2375 } | |
2376 | |
2377 date = (UDate)693792000000.0; // 1992 - one currency defined | |
2378 index = ucurr_countCurrencies("eo_AM", date, &status); | |
2379 if (index != 1) | |
2380 { | |
2381 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_err
orName(status)); | |
2382 } | |
2383 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status); | |
2384 tempStr.setTo(TMP); | |
2385 resultStr.setTo("RUR"); | |
2386 if (resultStr != tempStr) { | |
2387 errcheckln(status, "FAIL: didn't return RUR for eo_AM - %s", u_errorName
(status)); | |
2388 } | |
2389 | |
2390 date = (UDate)977616000000.0; // post 1993 - one currency defined | |
2391 index = ucurr_countCurrencies("eo_AM", date, &status); | |
2392 if (index != 1) | |
2393 { | |
2394 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_err
orName(status)); | |
2395 } | |
2396 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status); | |
2397 tempStr.setTo(TMP); | |
2398 resultStr.setTo("AMD"); | |
2399 if (resultStr != tempStr) { | |
2400 errcheckln(status, "FAIL: didn't return AMD for eo_AM - %s", u_errorName
(status)); | |
2401 } | |
2402 | |
2403 // Locale AD has multiple currencies at once | |
2404 date = (UDate)977616000000.0; // year 2001 | |
2405 index = ucurr_countCurrencies("eo_AD", date, &status); | |
2406 if (index != 4) | |
2407 { | |
2408 errcheckln(status, "FAIL: didn't return 4 for eo_AD - %s", u_err
orName(status)); | |
2409 } | |
2410 resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status); | |
2411 tempStr.setTo(TMP); | |
2412 resultStr.setTo("EUR"); | |
2413 if (resultStr != tempStr) { | |
2414 errcheckln(status, "FAIL: didn't return EUR for eo_AD - %s", u_errorName
(status)); | |
2415 } | |
2416 resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status); | |
2417 tempStr.setTo(TMP); | |
2418 resultStr.setTo("ESP"); | |
2419 if (resultStr != tempStr) { | |
2420 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName
(status)); | |
2421 } | |
2422 resLen = ucurr_forLocaleAndDate("eo_AD", date, 3, TMP, 4, &status); | |
2423 tempStr.setTo(TMP); | |
2424 resultStr.setTo("FRF"); | |
2425 if (resultStr != tempStr) { | |
2426 errcheckln(status, "FAIL: didn't return FRF for eo_AD - %s", u_errorName
(status)); | |
2427 } | |
2428 resLen = ucurr_forLocaleAndDate("eo_AD", date, 4, TMP, 4, &status); | |
2429 tempStr.setTo(TMP); | |
2430 resultStr.setTo("ADP"); | |
2431 if (resultStr != tempStr) { | |
2432 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName
(status)); | |
2433 } | |
2434 | |
2435 date = (UDate)0.0; // year 1970 | |
2436 index = ucurr_countCurrencies("eo_AD", date, &status); | |
2437 if (index != 3) | |
2438 { | |
2439 errcheckln(status, "FAIL: didn't return 3 for eo_AD - %s", u_err
orName(status)); | |
2440 } | |
2441 resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status); | |
2442 tempStr.setTo(TMP); | |
2443 resultStr.setTo("ESP"); | |
2444 if (resultStr != tempStr) { | |
2445 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName
(status)); | |
2446 } | |
2447 resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status); | |
2448 tempStr.setTo(TMP); | |
2449 resultStr.setTo("FRF"); | |
2450 if (resultStr != tempStr) { | |
2451 errcheckln(status, "FAIL: didn't return FRF for eo_AD - %s", u_errorName
(status)); | |
2452 } | |
2453 resLen = ucurr_forLocaleAndDate("eo_AD", date, 3, TMP, 4, &status); | |
2454 tempStr.setTo(TMP); | |
2455 resultStr.setTo("ADP"); | |
2456 if (resultStr != tempStr) { | |
2457 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName
(status)); | |
2458 } | |
2459 | |
2460 date = (UDate)-630720000000.0; // year 1950 | |
2461 index = ucurr_countCurrencies("eo_AD", date, &status); | |
2462 if (index != 2) | |
2463 { | |
2464 errcheckln(status, "FAIL: didn't return 2 for eo_AD - %s", u_err
orName(status)); | |
2465 } | |
2466 resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status); | |
2467 tempStr.setTo(TMP); | |
2468 resultStr.setTo("ESP"); | |
2469 if (resultStr != tempStr) { | |
2470 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName
(status)); | |
2471 } | |
2472 resLen = ucurr_forLocaleAndDate("eo_AD", date, 2, TMP, 4, &status); | |
2473 tempStr.setTo(TMP); | |
2474 resultStr.setTo("ADP"); | |
2475 if (resultStr != tempStr) { | |
2476 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName
(status)); | |
2477 } | |
2478 | |
2479 date = (UDate)-2207520000000.0; // year 1900 | |
2480 index = ucurr_countCurrencies("eo_AD", date, &status); | |
2481 if (index != 1) | |
2482 { | |
2483 errcheckln(status, "FAIL: didn't return 1 for eo_AD - %s", u_err
orName(status)); | |
2484 } | |
2485 resLen = ucurr_forLocaleAndDate("eo_AD", date, 1, TMP, 4, &status); | |
2486 tempStr.setTo(TMP); | |
2487 resultStr.setTo("ESP"); | |
2488 if (resultStr != tempStr) { | |
2489 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName
(status)); | |
2490 } | |
2491 | |
2492 // Locale UA has gap between years 1994 - 1996 | |
2493 date = (UDate)788400000000.0; | |
2494 index = ucurr_countCurrencies("eo_UA", date, &status); | |
2495 if (index != 0) | |
2496 { | |
2497 errcheckln(status, "FAIL: didn't return 0 for eo_UA - %s", u_err
orName(status)); | |
2498 } | |
2499 resLen = ucurr_forLocaleAndDate("eo_UA", date, index, TMP, 4, &status); | |
2500 if (resLen != 0) { | |
2501 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_erro
rName(status)); | |
2502 } | |
2503 status = U_ZERO_ERROR; | |
2504 | |
2505 // Test index bounds | |
2506 resLen = ucurr_forLocaleAndDate("eo_UA", date, 100, TMP, 4, &status); | |
2507 if (resLen != 0) { | |
2508 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_erro
rName(status)); | |
2509 } | |
2510 status = U_ZERO_ERROR; | |
2511 | |
2512 resLen = ucurr_forLocaleAndDate("eo_UA", date, 0, TMP, 4, &status); | |
2513 if (resLen != 0) { | |
2514 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_erro
rName(status)); | |
2515 } | |
2516 status = U_ZERO_ERROR; | |
2517 | |
2518 // Test for bogus locale | |
2519 index = ucurr_countCurrencies("eo_QQ", date, &status); | |
2520 if (index != 0) | |
2521 { | |
2522 errcheckln(status, "FAIL: didn't return 0 for eo_QQ - %s", u_err
orName(status)); | |
2523 } | |
2524 status = U_ZERO_ERROR; | |
2525 resLen = ucurr_forLocaleAndDate("eo_QQ", date, 1, TMP, 4, &status); | |
2526 if (resLen != 0) { | |
2527 errcheckln(status, "FAIL: eo_QQ didn't return NULL - %s", u_erro
rName(status)); | |
2528 } | |
2529 status = U_ZERO_ERROR; | |
2530 resLen = ucurr_forLocaleAndDate("eo_QQ", date, 0, TMP, 4, &status); | |
2531 if (resLen != 0) { | |
2532 errcheckln(status, "FAIL: eo_QQ didn't return NULL - %s", u_erro
rName(status)); | |
2533 } | |
2534 status = U_ZERO_ERROR; | |
2535 | |
2536 // Cycle through histrocial currencies | |
2537 date = (UDate)977616000000.0; // 2001 - one currency | |
2538 index = ucurr_countCurrencies("eo_AO", date, &status); | |
2539 if (index != 1) | |
2540 { | |
2541 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_err
orName(status)); | |
2542 } | |
2543 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status); | |
2544 tempStr.setTo(TMP); | |
2545 resultStr.setTo("AOA"); | |
2546 if (resultStr != tempStr) { | |
2547 errcheckln(status, "FAIL: didn't return AOA for eo_AO - %s", u_errorName
(status)); | |
2548 } | |
2549 | |
2550 date = (UDate)819936000000.0; // 1996 - 2 currencies | |
2551 index = ucurr_countCurrencies("eo_AO", date, &status); | |
2552 if (index != 2) | |
2553 { | |
2554 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_err
orName(status)); | |
2555 } | |
2556 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status); | |
2557 tempStr.setTo(TMP); | |
2558 resultStr.setTo("AOR"); | |
2559 if (resultStr != tempStr) { | |
2560 errcheckln(status, "FAIL: didn't return AOR for eo_AO - %s", u_errorName
(status)); | |
2561 } | |
2562 resLen = ucurr_forLocaleAndDate("eo_AO", date, 2, TMP, 4, &status); | |
2563 tempStr.setTo(TMP); | |
2564 resultStr.setTo("AON"); | |
2565 if (resultStr != tempStr) { | |
2566 errcheckln(status, "FAIL: didn't return AON for eo_AO - %s", u_errorName
(status)); | |
2567 } | |
2568 | |
2569 date = (UDate)662256000000.0; // 1991 - 2 currencies | |
2570 index = ucurr_countCurrencies("eo_AO", date, &status); | |
2571 if (index != 2) | |
2572 { | |
2573 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_err
orName(status)); | |
2574 } | |
2575 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status); | |
2576 tempStr.setTo(TMP); | |
2577 resultStr.setTo("AON"); | |
2578 if (resultStr != tempStr) { | |
2579 errcheckln(status, "FAIL: didn't return AON for eo_AO - %s", u_errorName
(status)); | |
2580 } | |
2581 resLen = ucurr_forLocaleAndDate("eo_AO", date, 2, TMP, 4, &status); | |
2582 tempStr.setTo(TMP); | |
2583 resultStr.setTo("AOK"); | |
2584 if (resultStr != tempStr) { | |
2585 errcheckln(status, "FAIL: didn't return AOK for eo_AO - %s", u_errorName
(status)); | |
2586 } | |
2587 | |
2588 date = (UDate)315360000000.0; // 1980 - one currency | |
2589 index = ucurr_countCurrencies("eo_AO", date, &status); | |
2590 if (index != 1) | |
2591 { | |
2592 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_err
orName(status)); | |
2593 } | |
2594 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status); | |
2595 tempStr.setTo(TMP); | |
2596 resultStr.setTo("AOK"); | |
2597 if (resultStr != tempStr) { | |
2598 errcheckln(status, "FAIL: didn't return AOK for eo_AO - %s", u_errorName
(status)); | |
2599 } | |
2600 | |
2601 date = (UDate)0.0; // 1970 - no currencies | |
2602 index = ucurr_countCurrencies("eo_AO", date, &status); | |
2603 if (index != 0) | |
2604 { | |
2605 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_err
orName(status)); | |
2606 } | |
2607 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status); | |
2608 if (resLen != 0) { | |
2609 errcheckln(status, "FAIL: eo_AO didn't return NULL - %s", u_erro
rName(status)); | |
2610 } | |
2611 status = U_ZERO_ERROR; | |
2612 | |
2613 // Test with currency keyword override | |
2614 date = (UDate)977616000000.0; // 2001 - two currencies | |
2615 index = ucurr_countCurrencies("eo_DE@currency=DEM", date, &status); | |
2616 if (index != 2) | |
2617 { | |
2618 errcheckln(status, "FAIL: didn't return 2 for eo_DE@currency=DEM
- %s", u_errorName(status)); | |
2619 } | |
2620 resLen = ucurr_forLocaleAndDate("eo_DE@currency=DEM", date, 1, TMP, 4, &stat
us); | |
2621 tempStr.setTo(TMP); | |
2622 resultStr.setTo("EUR"); | |
2623 if (resultStr != tempStr) { | |
2624 errcheckln(status, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s"
, u_errorName(status)); | |
2625 } | |
2626 resLen = ucurr_forLocaleAndDate("eo_DE@currency=DEM", date, 2, TMP, 4, &stat
us); | |
2627 tempStr.setTo(TMP); | |
2628 resultStr.setTo("DEM"); | |
2629 if (resultStr != tempStr) { | |
2630 errcheckln(status, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s"
, u_errorName(status)); | |
2631 } | |
2632 | |
2633 // Test Euro Support | |
2634 status = U_ZERO_ERROR; // reset | |
2635 date = uprv_getUTCtime(); | |
2636 | |
2637 UChar USD[4]; | |
2638 ucurr_forLocaleAndDate("en_US", date, 1, USD, 4, &status); | |
2639 | |
2640 UChar YEN[4]; | |
2641 ucurr_forLocaleAndDate("ja_JP", date, 1, YEN, 4, &status); | |
2642 | |
2643 ucurr_forLocaleAndDate("en_US", date, 1, TMP, 4, &status); | |
2644 if (u_strcmp(USD, TMP) != 0) { | |
2645 errcheckln(status, "Fail: en_US didn't return USD - %s", u_errorName(sta
tus)); | |
2646 } | |
2647 ucurr_forLocaleAndDate("en_US_PREEURO", date, 1, TMP, 4, &status); | |
2648 if (u_strcmp(USD, TMP) != 0) { | |
2649 errcheckln(status, "Fail: en_US_PREEURO didn't fallback to en_US - %s",
u_errorName(status)); | |
2650 } | |
2651 ucurr_forLocaleAndDate("en_US_Q", date, 1, TMP, 4, &status); | |
2652 if (u_strcmp(USD, TMP) != 0) { | |
2653 errcheckln(status, "Fail: en_US_Q didn't fallback to en_US - %s", u_erro
rName(status)); | |
2654 } | |
2655 status = U_ZERO_ERROR; // reset | |
2656 #endif | |
2657 } | |
2658 | |
2659 void LocaleTest::TestGetVariantWithKeywords(void) | |
2660 { | |
2661 Locale l("en_US_VALLEY@foo=value"); | |
2662 const char *variant = l.getVariant(); | |
2663 logln(variant); | |
2664 test_assert(strcmp("VALLEY", variant) == 0); | |
2665 | |
2666 UErrorCode status = U_ZERO_ERROR; | |
2667 char buffer[50]; | |
2668 int32_t len = l.getKeywordValue("foo", buffer, 50, status); | |
2669 buffer[len] = '\0'; | |
2670 test_assert(strcmp("value", buffer) == 0); | |
2671 } | |
2672 | |
2673 void LocaleTest::TestIsRightToLeft() { | |
2674 assertFalse("root LTR", Locale::getRoot().isRightToLeft()); | |
2675 assertFalse("zh LTR", Locale::getChinese().isRightToLeft()); | |
2676 assertTrue("ar RTL", Locale("ar").isRightToLeft()); | |
2677 assertTrue("und-EG RTL", Locale("und-EG").isRightToLeft(), FALSE, TRUE); | |
2678 assertFalse("fa-Cyrl LTR", Locale("fa-Cyrl").isRightToLeft()); | |
2679 assertTrue("en-Hebr RTL", Locale("en-Hebr").isRightToLeft()); | |
2680 assertTrue("ckb RTL", Locale("ckb").isRightToLeft(), FALSE, TRUE); // Soran
i Kurdish | |
2681 assertFalse("fil LTR", Locale("fil").isRightToLeft()); | |
2682 assertFalse("he-Zyxw LTR", Locale("he-Zyxw").isRightToLeft()); | |
2683 } | |
2684 | |
2685 void LocaleTest::TestBug11421() { | |
2686 Locale::getDefault().getBaseName(); | |
2687 int32_t numLocales; | |
2688 const Locale *localeList = Locale::getAvailableLocales(numLocales); | |
2689 for (int localeIndex = 0; localeIndex < numLocales; localeIndex++) { | |
2690 const Locale &loc = localeList[localeIndex]; | |
2691 if (strncmp(loc.getName(), loc.getBaseName(), strlen(loc.getBaseName()))
) { | |
2692 errln("%s:%d loc.getName=\"%s\"; loc.getBaseName=\"%s\"", | |
2693 __FILE__, __LINE__, loc.getName(), loc.getBaseName()); | |
2694 break; | |
2695 } | |
2696 } | |
2697 } | |
OLD | NEW |