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