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