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