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