1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2009, 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 "putilimp.h" 17 #include "unicode/ustring.h" 18 19 static const char* const rawData[33][8] = { 20 21 // language code 22 { "en", "fr", "ca", "el", "no", "it", "xx", "zh" }, 23 // script code 24 { "", "", "", "", "", "", "", "Hans" }, 25 // country code 26 { "US", "FR", "ES", "GR", "NO", "", "YY", "CN" }, 27 // variant code 28 { "", "", "", "", "NY", "", "", "" }, 29 // full name 30 { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "it", "xx_YY", "zh_Hans_CN" }, 31 // ISO-3 language 32 { "eng", "fra", "cat", "ell", "nor", "ita", "", "zho" }, 33 // ISO-3 country 34 { "USA", "FRA", "ESP", "GRC", "NOR", "", "", "CHN" }, 35 // LCID 36 { "409", "40c", "403", "408", "814", "10", "0", "804" }, 37 38 // display langage (English) 39 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "Chinese" }, 40 // display script (English) 41 { "", "", "", "", "", "", "", "Simplified Han" }, 42 // display country (English) 43 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "China" }, 44 // display variant (English) 45 { "", "", "", "", "NY", "", "", ""}, 46 // display name (English) 47 // Updated no_NO_NY English display name for new pattern-based algorithm 48 // (part of Euro support). 49 { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Italian", "xx (YY)", "Chinese (Simplified Han, China)" }, 50 51 // display langage (French) 52 { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "italien", "xx", "chinois" }, 53 // display script (French) 54 { "", "", "", "", "", "", "", "id\\u00E9ogrammes han simplifi\\u00E9s" }, 55 // display country (French) 56 { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "", "YY", "Chine" }, 57 // display variant (French) 58 { "", "", "", "", "NY", "", "", "" }, 59 // display name (French) 60 //{ "anglais (Etats-Unis)", "francais (France)", "catalan (Espagne)", "grec (Grece)", "norvegien (Norvege,Nynorsk)", "italien", "xx (YY)" }, 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 62 63 64 /* display language (Catalan) */ 65 { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "itali\\u00E0", "", "xin\\u00E8s" }, 66 /* display script (Catalan) */ 67 { "", "", "", "", "", "", "", "xin\\u00E8s simplificat" }, 68 /* display country (Catalan) */ 69 { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "", "", "Xina" }, 70 /* display variant (Catalan) */ 71 { "", "", "", "", "NY", "", "" }, 72 /* display name (Catalan) */ 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, Xina)" }, 74 75 // display langage (Greek)[actual values listed below] 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) 86 { "", "", "", "", "", "", "", "\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc" }, 87 // display country (Greek)[actual values listed below] 88 { "\\u0397\\u03BD\\u03C9\\u03BC\\u03AD\\u03BD\\u03B5\\u03C2 \\u03A0\\u03BF\\u03BB\\u03B9\\u03C4\\u03B5\\u03AF\\u03B5\\u03C2 \\u03C4\\u03B7\\u03C2 \\u0391\\u03BC\\u03B5\\u03C1\\u03B9\\u03BA\\u03AE\\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 }, 97 // display variant (Greek) 98 { "", "", "", "", "NY", "", "" }, 99 // display name (Greek)[actual values listed below] 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 \\u03C4\\u03B7\\u03C2 \\u0391\\u03BC\\u03B5\\u03C1\\u03B9\\u03BA\\u03AE\\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 "", 107 "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (\\u0391\\u03c0\\u03bb\\u03bf\\u03c0\\u03bf\\u03b9\\u03b7\\u03bc\\u03ad\\u03bd\\u03bf \\u039a\\u03b9\\u03bd\\u03b5\\u03b6\\u03b9\\u03ba\\u03cc, \\u039A\\u03AF\\u03BD\\u03B1)" 108 }, 109 110 // display langage (<root>) 111 { "English", "French", "Catalan", "Greek", "Norwegian", "Italian", "xx", "" }, 112 // display script (<root>) 113 { "", "", "", "", "", "", "", ""}, 114 // display country (<root>) 115 { "United States", "France", "Spain", "Greece", "Norway", "", "YY", "" }, 116 // display variant (<root>) 117 { "", "", "", "", "Nynorsk", "", "", ""}, 118 // display name (<root>) 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)", "" } 121 }; 122 123 124 /* 125 Usage: 126 test_assert( Test (should be TRUE) ) 127 128 Example: 129 test_assert(i==3); 130 131 the macro is ugly but makes the tests pretty. 132 */ 133 134 #define test_assert(test) \ 135 { \ 136 if(!(test)) \ 137 errln("FAIL: " #test " was not true. In " __FILE__ " on line %d", __LINE__ ); \ 138 else \ 139 logln("PASS: asserted " #test); \ 140 } 141 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)) \ 155 errln("FAIL: " #test " was not true. " + UnicodeString(print) ); \ 156 else \ 157 logln("PASS: asserted " #test "-> " + UnicodeString(print)); \ 158 } 159 160 161 #define test_dumpLocale(l) { logln(#l " = " + UnicodeString(l.getName(), "")); } 162 163 LocaleTest::LocaleTest() 164 : dataTable(NULL) 165 { 166 setUpDataTable(); 167 } 168 169 LocaleTest::~LocaleTest() 170 { 171 if (dataTable != 0) { 172 for (int32_t i = 0; i < 33; i++) { 173 delete []dataTable[i]; 174 } 175 delete []dataTable; 176 dataTable = 0; 177 } 178 } 179 180 void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 181 { 182 switch (index) { 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); 195 #if !UCONFIG_NO_FORMATTING 196 TESTCASE(12, TestThaiCurrencyFormat); 197 TESTCASE(13, TestEuroSupport); 198 #endif 199 TESTCASE(14, TestToString); 200 #if !UCONFIG_NO_FORMATTING 201 TESTCASE(15, Test4139940); 202 TESTCASE(16, Test4143951); 203 #endif 204 TESTCASE(17, Test4147315); 205 TESTCASE(18, Test4147317); 206 TESTCASE(19, Test4147552); 207 TESTCASE(20, TestVariantParsing); 208 #if !UCONFIG_NO_FORMATTING 209 TESTCASE(21, Test4105828); 210 #endif 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); 219 TESTCASE(30, TestCurrencyByDate); 220 221 // keep the last index in sync with the condition in default: 222 223 default: 224 if (index <= 28) { // keep this in sync with the last index! 225 name = "(test omitted by !UCONFIG_NO_FORMATTING)"; 226 } else { 227 name = ""; 228 } 229 break; //needed to end loop 230 } 231 } 232 233 void LocaleTest::TestBasicGetters() { 234 UnicodeString temp; 235 236 int32_t i; 237 for (i = 0; i <= MAX_LOCALES; i++) { 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 } 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]); 250 if ( (temp=testLocale.getScript()) != (dataTable[SCRIPT][i])) 251 errln(" Script code mismatch: " + temp + " versus " 252 + dataTable[SCRIPT][i]); 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++) { 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 } 273 logln("Testing " + (temp=testLocale.getName()) + "..."); 274 275 if ( (temp=testLocale.getLanguage()) != (dataTable[LANG][i])) 276 errln("Language code mismatch: " + temp + " versus " 277 + dataTable[LANG][i]); 278 if ( (temp=testLocale.getScript()) != (dataTable[SCRIPT][i])) 279 errln("Script code mismatch: " + temp + " versus " 280 + dataTable[SCRIPT][i]); 281 if ( (temp=testLocale.getCountry()) != (dataTable[CTRY][i])) 282 errln("Country code mismatch: " + temp + " versus " 283 + dataTable[CTRY][i]); 284 if (testLocale.getVariant()[0] != 0) 285 errln("Variant code mismatch: something versus \"\""); 286 } 287 288 logln("Testing long language names and getters"); 289 Locale test8 = Locale::createFromName("x-klingon-latn-zx.utf32be@special"); 290 291 temp = test8.getLanguage(); 292 if (temp != UnicodeString("x-klingon") ) 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\""); 298 299 temp = test8.getCountry(); 300 if (temp != UnicodeString("ZX") ) 301 errln("Country code mismatch: " + temp + " versus \"ZX\""); 302 303 temp = test8.getVariant(); 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 \"\""); 309 310 if (Locale::getDefault() != Locale::createFromName(NULL)) 311 errln("Locale::getDefault() == Locale::createFromName(NULL)"); 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 } 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; 340 } 341 342 void 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 412 void LocaleTest::TestSimpleResourceInfo() { 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]); 433 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 /*-----*/ 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 */ 456 void 457 LocaleTest::TestDisplayNames() 458 { 459 Locale english("en", "US"); 460 Locale french("fr", "FR"); 461 Locale croatian("ca", "ES"); 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); 468 logln(" In locale = ca_ES..."); 469 doTestDisplayNames(croatian, DLANG_CA); 470 logln(" In locale = el_GR..."); 471 doTestDisplayNames(greek, DLANG_EL); 472 473 UnicodeString s; 474 UErrorCode status = U_ZERO_ERROR; 475 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 dataerrln("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 dataerrln("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()); 500 } 501 s.remove(); 502 #endif 503 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 } 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"); 512 } 513 } 514 515 void LocaleTest::TestSimpleObjectStuff() { 516 Locale test1("aa", "AA"); 517 Locale test2("aa", "AA"); 518 Locale test3(test1); 519 Locale test4("zz", "ZZ"); 520 Locale test5("aa", "AA", ""); 521 Locale test6("aa", "AA", "ANTARES"); 522 Locale test7("aa", "AA", "JUPITER"); 523 Locale test8 = Locale::createFromName("aa-aa-jupiTER"); // was "aa-aa.utf8@jupiter" but in 3.0 getName won't normalize that 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); 593 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. 611 class POSIXLocale : public Locale 612 { 613 public: 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 630 void 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")); 638 Locale test6("ab", "AB", "Antares"); 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 670 void LocaleTest::TestGetAvailableLocales() 671 { 672 int32_t locCount = 0; 673 const Locale* locList = Locale::getAvailableLocales(locCount); 674 675 if (locCount == 0) 676 dataerrln("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 688 void 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 + "\""); 716 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 727 void LocaleTest::doTestDisplayNames(Locale& displayLocale, int32_t compareIndex) { 728 UnicodeString temp; 729 730 for (int32_t i = 0; i <= MAX_LOCALES; i++) { 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 } 738 logln(" Testing " + (temp=testLocale.getName()) + "..."); 739 740 UnicodeString testLang; 741 UnicodeString testScript; 742 UnicodeString testCtry; 743 UnicodeString testVar; 744 UnicodeString testName; 745 746 testLocale.getDisplayLanguage(displayLocale, testLang); 747 testLocale.getDisplayScript(displayLocale, testScript); 748 testLocale.getDisplayCountry(displayLocale, testCtry); 749 testLocale.getDisplayVariant(displayLocale, testVar); 750 testLocale.getDisplayName(displayLocale, testName); 751 752 UnicodeString expectedLang; 753 UnicodeString expectedScript; 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 762 expectedScript = dataTable[compareIndex + 1][i]; 763 if (expectedScript.length() == 0) 764 expectedScript = dataTable[DSCRIPT_EN][i]; 765 766 expectedCtry = dataTable[compareIndex + 2][i]; 767 if (expectedCtry.length() == 0) 768 expectedCtry = dataTable[DCTRY_EN][i]; 769 770 expectedVar = dataTable[compareIndex + 3][i]; 771 if (expectedVar.length() == 0) 772 expectedVar = dataTable[DVAR_EN][i]; 773 774 expectedName = dataTable[compareIndex + 4][i]; 775 if (expectedName.length() == 0) 776 expectedName = dataTable[DNAME_EN][i]; 777 778 if (testLang != expectedLang) 779 dataerrln("Display language (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testLang + " expected " + expectedLang); 780 if (testScript != expectedScript) 781 dataerrln("Display script (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testScript + " expected " + expectedScript); 782 if (testCtry != expectedCtry) 783 dataerrln("Display country (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testCtry + " expected " + expectedCtry); 784 if (testVar != expectedVar) 785 dataerrln("Display variant (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testVar + " expected " + expectedVar); 786 if (testName != expectedName) 787 dataerrln("Display name (" + UnicodeString(displayLocale.getName()) + ") of (" + UnicodeString(testLocale.getName()) + ") got " + testName + " expected " + expectedName); 788 } 789 } 790 791 //--------------------------------------------------- 792 // table of valid data 793 //--------------------------------------------------- 794 795 796 797 void LocaleTest::setUpDataTable() 798 { 799 if (dataTable == 0) { 800 dataTable = new UnicodeString*[33]; 801 802 for (int32_t i = 0; i < 33; i++) { 803 dataTable[i] = new UnicodeString[8]; 804 for (int32_t j = 0; j < 8; j++) { 805 dataTable[i][j] = CharsToUnicodeString(rawData[i][j]); 806 } 807 } 808 } 809 } 810 811 // ==================== 812 813 814 /** 815 * @bug 4011756 4011380 816 */ 817 void 818 LocaleTest::TestISO3Fallback() 819 { 820 Locale test("xx", "YY"); 821 822 const char * result; 823 824 result = test.getISO3Language(); 825 826 // Conform to C API usage 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 */ 840 void 841 LocaleTest::TestGetLangsAndCountries() 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(); 853 const char spotCheck1[ ][4] = { "en", "es", "fr", "de", "it", 854 "ja", "ko", "zh", "th", "he", 855 "id", "iu", "ug", "yi", "za" }; 856 857 int32_t i; 858 859 for(testCount = 0;test[testCount];testCount++) 860 ; 861 862 /* TODO: Change this test to be more like the cloctst version? */ 863 if (testCount != 491) 864 errln("Expected getISOLanguages() to return 491 languages; it returned %d", testCount); 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(); 887 UnicodeString spotCheck2 [] = { "US", "CA", "GB", "FR", "DE", 888 "IT", "JP", "KR", "CN", "TW", 889 "TH" }; 890 int32_t spot2Len = 11; 891 for(testCount=0;test[testCount];testCount++) 892 ; 893 894 if (testCount != 246){ 895 errln("Expected getISOCountries to return 240 countries; it returned %d", testCount); 896 }else { 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 } 911 for (i = 0; i < testCount; i++) { 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 */ 926 void 927 LocaleTest::TestSimpleDisplayNames() 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" }; 934 UnicodeString languageNames [] = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish", 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 dataerrln("Got wrong display name for " + UnicodeString(languageCodes[i]) + ": Expected \"" + 943 languageNames[i] + "\", got \"" + test + "\"."); 944 } 945 } 946 947 /** 948 * @bug 4118595 949 */ 950 void 951 LocaleTest::TestUninstalledISO3Names() 952 { 953 // This test checks to make sure getISO3Language and getISO3Country work right 954 // even for locales that are not installed. 955 const char iso2Languages [][4] = { "am", "ba", "fy", "mr", "rn", 956 "ss", "tw", "zu" }; 957 const char iso3Languages [][5] = { "amh", "bak", "fry", "mar", "run", 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 973 char iso2Countries [][4] = { "AF", "BW", "KZ", "MO", "MN", 974 "SB", "TC", "ZW" }; 975 char iso3Countries [][4] = { "AFG", "BWA", "KAZ", "MAC", "MNG", 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 */ 994 void 995 LocaleTest::TestAtypicalLocales() 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"), 1023 CharsToUnicodeString("R\\u00E9publique dominicaine"), 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") }; 1035 // De-Anglicizing root required the change from 1036 // English display names to ISO Codes - ram 2003/09/26 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" }; 1046 1047 int32_t i; 1048 UErrorCode status = U_ZERO_ERROR; 1049 Locale saveLocale; 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 dataerrln("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 dataerrln("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 dataerrln("Lookup in French failed: expected \"" + frenchDisplayNames[i] 1078 + "\", got \"" + name + "\""); 1079 } 1080 1081 for (i = 0; i < 9; i++) { 1082 UnicodeString name; 1083 localesToTest[i].getDisplayName(Locale("inv", "IN"), name); 1084 logln(name + " Locale fallback to be, and data fallback to root"); 1085 if (name != invDisplayNames[i]) 1086 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames[i]) 1087 + "\", got \"" + prettify(name) + "\""); 1088 localesToTest[i].getDisplayName(Locale("inv", "BD"), name); 1089 logln(name + " Data fallback to root"); 1090 if (name != invDisplayNames[i]) 1091 dataerrln("Lookup in INV failed: expected \"" + prettify(invDisplayNames[i]) 1092 + "\", got \"" + prettify(name )+ "\""); 1093 } 1094 Locale::setDefault(saveLocale, status); 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 */ 1104 void 1105 LocaleTest::TestThaiCurrencyFormat() 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 dataerrln("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 */ 1139 void 1140 LocaleTest::TestEuroSupport() 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", 1152 "en_GB_EURO", 1153 "en_US_EURO", 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; 1177 NumberFormat *nf = NumberFormat::createCurrencyInstance(loc, status); 1178 UnicodeString pos; 1179 1180 if (U_FAILURE(status)) { 1181 dataerrln("Error calling NumberFormat::createCurrencyInstance(%s)", *locales); 1182 continue; 1183 } 1184 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 errcheckln(status, "Fail: en_US didn't return USD - %s", u_errorName(status)); 1211 } 1212 ucurr_forLocale("en_US_EURO", tmp, 4, &status); 1213 resultStr.setTo(tmp); 1214 if (euroStr != resultStr) { 1215 errcheckln(status, "Fail: en_US_EURO didn't return EUR - %s", u_errorName(status)); 1216 } 1217 ucurr_forLocale("en_GB_EURO", tmp, 4, &status); 1218 resultStr.setTo(tmp); 1219 if (euroStr != resultStr) { 1220 errcheckln(status, "Fail: en_GB_EURO didn't return EUR - %s", u_errorName(status)); 1221 } 1222 ucurr_forLocale("en_US_PREEURO", tmp, 4, &status); 1223 resultStr.setTo(tmp); 1224 if (dollarStr != resultStr) { 1225 errcheckln(status, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status)); 1226 } 1227 ucurr_forLocale("en_US_Q", tmp, 4, &status); 1228 resultStr.setTo(tmp); 1229 if (dollarStr != resultStr) { 1230 errcheckln(status, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status)); 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"); 1235 } 1236 } 1237 1238 #endif 1239 1240 /** 1241 * @bug 4139504 1242 * toString() doesn't work with language_VARIANT. 1243 */ 1244 void 1245 LocaleTest::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 }; 1265 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: 1286 * -- basically, hungarian for monday shouldn't have an \u00f4 1287 * (o circumflex)in it instead it should be an o with 2 inclined 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 */ 1297 void 1298 LocaleTest::Test4139940() 1299 { 1300 Locale mylocale("hu", "", ""); 1301 UDate mydate = date(98,3,13); // A Monday 1302 UErrorCode status = U_ZERO_ERROR; 1303 SimpleDateFormat df_full("EEEE", mylocale, status); 1304 if(U_FAILURE(status)){ 1305 errcheckln(status, UnicodeString("Could not create SimpleDateFormat object for locale hu. Error: " )+ UnicodeString(u_errorName(status))); 1306 return; 1307 } 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; 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 } 1320 } 1321 1322 UDate 1323 LocaleTest::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); 1327 if (cal == 0) 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; 1334 1335 delete cal; 1336 return dt; 1337 } 1338 1339 /** 1340 * @bug 4143951 1341 * Russian first day of week should be Monday. Confirmed. 1342 */ 1343 void 1344 LocaleTest::Test4143951() 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 dataerrln("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 */ 1363 void 1364 LocaleTest::Test4147315() 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"); 1370 1371 const char *result = locale.getISO3Country(); 1372 1373 // Change to conform to C api usage 1374 if((result==NULL)||(result[0] != 0)) 1375 errln("ERROR: getISO3Country() returns: " + UnicodeString(result,"") + 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 */ 1384 void 1385 LocaleTest::Test4147317() 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"); 1391 1392 const char *result = locale.getISO3Language(); 1393 1394 // Change to conform to C api usage 1395 if((result==NULL)||(result[0] != 0)) 1396 errln("ERROR: getISO3Language() returns: " + UnicodeString(result,"") + 1397 " for locale '" + (temp=locale.getName()) + "' rather than exception" ); 1398 } 1399 1400 /* 1401 * @bug 4147552 1402 */ 1403 void 1404 LocaleTest::Test4147552() 1405 { 1406 Locale locales [] = { Locale("no", "NO"), 1407 Locale("no", "NO", "B"), 1408 Locale("no", "NO", "NY") 1409 }; 1410 1411 UnicodeString edn("Norwegian (Norway, B)"); 1412 UnicodeString englishDisplayNames [] = { 1413 "Norwegian (Norway)", 1414 edn, 1415 // "Norwegian (Norway,B)", 1416 //"Norwegian (Norway,NY)" 1417 "Norwegian (Norway, NY)" 1418 }; 1419 UnicodeString ndn("norsk (Norge, B"); 1420 UnicodeString norwegianDisplayNames [] = { 1421 "norsk (Norge)", 1422 "norsk (Norge, B)", 1423 //ndn, 1424 "norsk (Noreg, NY)" 1425 //"Norsk (Noreg, Nynorsk)" 1426 }; 1427 UErrorCode status = U_ZERO_ERROR; 1428 1429 Locale saveLocale; 1430 Locale::setDefault(Locale::getEnglish(), status); 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 dataerrln("English display-name mismatch: expected " + 1436 englishDisplayNames[i] + ", got " + loc.getDisplayName(temp)); 1437 if (loc.getDisplayName(loc, temp) != norwegianDisplayNames[i]) 1438 dataerrln("Norwegian display-name mismatch: expected " + 1439 norwegianDisplayNames[i] + ", got " + 1440 loc.getDisplayName(loc, temp)); 1441 } 1442 Locale::setDefault(saveLocale, status); 1443 } 1444 1445 void 1446 LocaleTest::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"); 1452 1453 UnicodeString got; 1454 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 dataerrln("FAIL: getDisplayName()"); 1465 dataerrln("Wanted: " + dispName); 1466 dataerrln("Got : " + got); 1467 } 1468 1469 Locale shortVariant("fr", "FR", "foo"); 1470 shortVariant.getDisplayVariant(got); 1471 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); 1480 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); 1489 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); 1498 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 */ 1513 void 1514 LocaleTest::Test4105828() 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 dataerrln("Couldn't create NumberFormat - %s", u_errorName(status)); 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 1540 void 1541 LocaleTest::TestSetIsBogus() { 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 } 1551 } 1552 1553 1554 void 1555 LocaleTest::TestKeywordVariants(void) { 1556 static const struct { 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 } 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 } 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 1661 void 1662 LocaleTest::TestKeywordVariantParsing(void) { 1663 static const struct { 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 1691 void 1692 LocaleTest::TestGetBaseName(void) { 1693 static const struct { 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 */ 1719 static 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 */ 1742 void 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 dataerrln("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 1767 void 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 - %s", u_errorName(ec)); 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 } 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; 1793 } 1794 delete cal; 1795 #endif 1796 1797 // DecimalFormat, DecimalFormatSymbols 1798 #if !UCONFIG_NO_FORMATTING 1799 req = "fr_FR_NICE"; 1800 DecimalFormat* dec = (DecimalFormat*) 1801 NumberFormat::createInstance(Locale::createFromName(req), ec); 1802 if (U_FAILURE(ec)) { 1803 dataerrln("FAIL: NumberFormat::createInstance failed - %s", u_errorName(ec)); 1804 } else { 1805 if (dec->getDynamicClassID() != DecimalFormat::getStaticClassID()) { 1806 errln("FAIL: NumberFormat::createInstance does not return a DecimalFormat"); 1807 return; 1808 } 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(); 1818 if (sym == NULL) { 1819 errln("FAIL: getDecimalFormatSymbols returned NULL"); 1820 return; 1821 } 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)); 1839 if (dat == 0){ 1840 dataerrln("Error calling DateFormat::createDateInstance()"); 1841 } else { 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 } 1853 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 } 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 dataerrln("FAIL: BreakIterator::createWordInstance failed - %s", u_errorName(ec)); 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 dataerrln("FAIL: Collator::createInstance failed - %s", u_errorName(ec)); 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 1996 void 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 2019 static 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 2033 void LocaleTest::TestCanonicalization(void) 2034 { 2035 static const struct { 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" }, 2069 { "zh_TW_STROKE", "zh_TW_STROKE", "zh_TW@collation=stroke" }, 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 */ 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 */ 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 */ 2091 { "zh-CHT", "zh_CHT", "zh_Hant" }, /* .NET name This may change back to zh_Hant */ 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 } 2140 2141 void 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 errcheckln(status, "FAIL: didn't return 0 for eo_AM - %s", u_errorName(status)); 2157 } 2158 resLen = ucurr_forLocaleAndDate("eo_AM", date, index, TMP, 4, &status); 2159 if (resLen != 0) { 2160 errcheckln(status, "FAIL: eo_AM didn't return NULL - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return SUR for eo_AM - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return RUR for eo_AM - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return 1 for eo_AM - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return AMD for eo_AM - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return 4 for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return EUR for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status)); 2233 } 2234 2235 date = (UDate)0.0; // year 1970 2236 index = ucurr_countCurrencies("eo_AD", date, &status); 2237 if (index != 3) 2238 { 2239 errcheckln(status, "FAIL: didn't return 3 for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return FRF for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status)); 2258 } 2259 2260 date = (UDate)-630720000000.0; // year 1950 2261 index = ucurr_countCurrencies("eo_AD", date, &status); 2262 if (index != 2) 2263 { 2264 errcheckln(status, "FAIL: didn't return 2 for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return ADP for eo_AD - %s", u_errorName(status)); 2277 } 2278 2279 date = (UDate)-2207520000000.0; // year 1900 2280 index = ucurr_countCurrencies("eo_AD", date, &status); 2281 if (index != 1) 2282 { 2283 errcheckln(status, "FAIL: didn't return 1 for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return ESP for eo_AD - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return 0 for eo_UA - %s", u_errorName(status)); 2298 } 2299 resLen = ucurr_forLocaleAndDate("eo_UA", date, index, TMP, 4, &status); 2300 if (resLen != 0) { 2301 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status)); 2309 } 2310 status = U_ZERO_ERROR; 2311 2312 resLen = ucurr_forLocaleAndDate("eo_UA", date, 0, TMP, 4, &status); 2313 if (resLen != 0) { 2314 errcheckln(status, "FAIL: eo_UA didn't return NULL - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return 0 for eo_QQ - %s", u_errorName(status)); 2323 } 2324 status = U_ZERO_ERROR; 2325 resLen = ucurr_forLocaleAndDate("eo_QQ", date, 1, TMP, 4, &status); 2326 if (resLen != 0) { 2327 errcheckln(status, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status)); 2328 } 2329 status = U_ZERO_ERROR; 2330 resLen = ucurr_forLocaleAndDate("eo_QQ", date, 0, TMP, 4, &status); 2331 if (resLen != 0) { 2332 errcheckln(status, "FAIL: eo_QQ didn't return NULL - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return AOA for eo_AO - %s", u_errorName(status)); 2348 } 2349 2350 date = (UDate)819936000000.0; // 1996 - 2 currencies 2351 index = ucurr_countCurrencies("eo_AO", date, &status); 2352 if (index != 2) 2353 { 2354 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return AOR for eo_AO - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status)); 2367 } 2368 2369 date = (UDate)662256000000.0; // 1991 - 2 currencies 2370 index = ucurr_countCurrencies("eo_AO", date, &status); 2371 if (index != 2) 2372 { 2373 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return AON for eo_AO - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status)); 2386 } 2387 2388 date = (UDate)315360000000.0; // 1980 - one currency 2389 index = ucurr_countCurrencies("eo_AO", date, &status); 2390 if (index != 1) 2391 { 2392 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return AOK for eo_AO - %s", u_errorName(status)); 2399 } 2400 2401 date = (UDate)0.0; // 1970 - no currencies 2402 index = ucurr_countCurrencies("eo_AO", date, &status); 2403 if (index != 0) 2404 { 2405 errcheckln(status, "FAIL: didn't return 1 for eo_AO - %s", u_errorName(status)); 2406 } 2407 resLen = ucurr_forLocaleAndDate("eo_AO", date, 1, TMP, 4, &status); 2408 if (resLen != 0) { 2409 errcheckln(status, "FAIL: eo_AO didn't return NULL - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return 2 for eo_DE@currency=DEM - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return EUR for eo_DE@currency=DEM - %s", u_errorName(status)); 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 errcheckln(status, "FAIL: didn't return DEM for eo_DE@currency=DEM - %s", u_errorName(status)); 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 errcheckln(status, "Fail: en_US didn't return USD - %s", u_errorName(status)); 2446 } 2447 ucurr_forLocaleAndDate("en_US_PREEURO", date, 1, TMP, 4, &status); 2448 if (u_strcmp(USD, TMP) != 0) { 2449 errcheckln(status, "Fail: en_US_PREEURO didn't fallback to en_US - %s", u_errorName(status)); 2450 } 2451 ucurr_forLocaleAndDate("en_US_Q", date, 1, TMP, 4, &status); 2452 if (u_strcmp(USD, TMP) != 0) { 2453 errcheckln(status, "Fail: en_US_Q didn't fallback to en_US - %s", u_errorName(status)); 2454 } 2455 status = U_ZERO_ERROR; // reset 2456 #endif 2457 } 2458