1 /* 2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 /** 24 * @test 25 * @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613 26 * 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951 27 * 4147315 4147317 4147552 4335196 4778440 4940539 5010672 6475525 6544471 6627549 28 * 6786276 7066203 7085757 29 * @summary test Locales 30 */ 31 /* 32 * 33 * 34 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved 35 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved 36 * 37 * Portions copyright (c) 2007 Sun Microsystems, Inc. 38 * All Rights Reserved. 39 * 40 * The original version of this source code and documentation 41 * is copyrighted and owned by Taligent, Inc., a wholly-owned 42 * subsidiary of IBM. These materials are provided under terms 43 * of a License Agreement between Taligent and Sun. This technology 44 * is protected by multiple US and International patents. 45 * 46 * This notice and attribution to Taligent may not be removed. 47 * Taligent is a registered trademark of Taligent, Inc. 48 * 49 * Permission to use, copy, modify, and distribute this software 50 * and its documentation for NON-COMMERCIAL purposes and without 51 * fee is hereby granted provided that this copyright notice 52 * appears in all copies. Please refer to the file "copyright.html" 53 * for further important copyright and licensing information. 54 * 55 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF 56 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 57 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 58 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR 59 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 60 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. 61 * 62 */ 63 64 import java.text.*; 65 import java.util.Locale; 66 import java.util.MissingResourceException; 67 import java.util.Date; 68 import java.util.Calendar; 69 import java.io.*; 70 71 public class LocaleTest extends LocaleTestFmwk { 72 public LocaleTest() { 73 } 74 75 private int ENGLISH = 0; 76 private int FRENCH = 1; 77 private int CROATIAN = 2; 78 private int GREEK = 3; 79 private int NORWEGIAN = 4; 80 private int ITALIAN = 5; 81 private int DUMMY = 6; 82 private int MAX_LOCALES = 6; 83 84 private int LANG = 0; 85 private int CTRY = 1; 86 private int VAR = 2; 87 private int NAME = 3; 88 private int LANG3 = 4; 89 private int CTRY3 = 5; 90 private int LCID = 6; 91 private int DLANG_EN = 7; 92 private int DCTRY_EN = 8; 93 private int DVAR_EN = 9; 94 private int DNAME_EN = 10; 95 private int DLANG_FR = 11; 96 private int DCTRY_FR = 12; 97 private int DVAR_FR = 13; 98 private int DNAME_FR = 14; 99 private int DLANG_HR = 15; 100 private int DCTRY_HR = 16; 101 private int DVAR_HR = 17; 102 private int DNAME_HR = 18; 103 private int DLANG_EL = 19; 104 private int DCTRY_EL = 20; 105 private int DVAR_EL = 21; 106 private int DNAME_EL = 22; 107 private int DLANG_ROOT = 23; 108 private int DCTRY_ROOT = 24; 109 private int DVAR_ROOT = 25; 110 private int DNAME_ROOT = 26; 111 112 private String[][] dataTable = { 113 // language code 114 { "en", "fr", "hr", "el", "no", "it", "xx" }, 115 // country code 116 { "US", "FR", "HR", "GR", "NO", "", "YY" }, 117 // variant code 118 { "", "", "", "", "NY", "", "" }, 119 // full name 120 { "en_US", "fr_FR", "hr_HR", "el_GR", "no_NO_NY", "it", "xx_YY" }, 121 // ISO-3 language 122 { "eng", "fra", "hrv", "ell", "nor", "ita", "" }, 123 // ISO-3 country 124 { "USA", "FRA", "HRV", "GRC", "NOR", "", "" }, 125 // LCID (not currently public) 126 { "0409", "040c", "041a", "0408", "0814", "", "" }, 127 128 // display language (English) 129 { "English", "French", "Croatian", "Greek", "Norwegian", "Italian", "xx" }, 130 // display country (English) 131 { "United States", "France", "Croatia", "Greece", "Norway", "", "YY" }, 132 // display variant (English) 133 { "", "", "", "", "Nynorsk", "", ""}, 134 // display name (English) 135 // Updated no_NO_NY English display name for new pattern-based algorithm 136 // (part of Euro support). 137 { "English (United States)", "French (France)", "Croatian (Croatia)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" }, 138 139 // display langage (French) 140 { "anglais", "fran\u00e7ais", "croate", "grec", "norv\u00e9gien", "italien", "xx" }, 141 // display country (French) 142 { "Etats-Unis", "France", "Croatie", "Gr\u00e8ce", "Norv\u00e8ge", "", "YY" }, 143 // display variant (French) 144 { "", "", "", "", "", "", "" }, 145 // display name (French) 146 { "anglais (Etats-Unis)", "fran\u00e7ais (France)", "croate (Croatie)", "grec (Gr\u00e8ce)", "norv\u00e9gien (Norv\u00e8ge,Nynorsk)", "italien", "xx (YY)" }, 147 148 // display langage (Croatian) 149 { "", "", "hrvatski", "", "", "", "xx" }, 150 // display country (Croatian) 151 { "", "", "Hrvatska", "", "", "", "YY" }, 152 // display variant (Croatian) 153 { "", "", "", "", "", "", ""}, 154 // display name (Croatian) 155 { "", "", "hrvatski (Hrvatska)", "", "", "", "xx (YY)" }, 156 157 // display langage (Greek) 158 { "\u0391\u03b3\u03b3\u03bb\u03b9\u03ba\u03ac", "\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ac", "\u039a\u03c1\u03bf\u03b1\u03c4\u03b9\u03ba\u03ac", "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac", "\u039d\u03bf\u03c1\u03b2\u03b7\u03b3\u03b9\u03ba\u03ac", "\u0399\u03c4\u03b1\u03bb\u03b9\u03ba\u03ac", "xx" }, 159 // display country (Greek) 160 { "\u0397\u03bd\u03c9\u03bc\u03ad\u03bd\u03b5\u03c2 \u03a0\u03bf\u03bb\u03b9\u03c4\u03b5\u03af\u03b5\u03c2", "\u0393\u03b1\u03bb\u03bb\u03af\u03b1", "\u039a\u03c1\u03bf\u03b1\u03c4\u03af\u03b1", "\u0395\u03bb\u03bb\u03ac\u03b4\u03b1", "\u039d\u03bf\u03c1\u03b2\u03b7\u03b3\u03af\u03b1", "", "YY" }, 161 // display variant (Greek) 162 { "", "", "", "", "", "", "" }, 163 // display name (Greek) 164 { "\u0391\u03b3\u03b3\u03bb\u03b9\u03ba\u03ac (\u0397\u03bd\u03c9\u03bc\u03ad\u03bd\u03b5\u03c2 \u03a0\u03bf\u03bb\u03b9\u03c4\u03b5\u03af\u03b5\u03c2)", "\u0393\u03b1\u03bb\u03bb\u03b9\u03ba\u03ac (\u0393\u03b1\u03bb\u03bb\u03af\u03b1)", "\u039a\u03c1\u03bf\u03b1\u03c4\u03b9\u03ba\u03ac (\u039a\u03c1\u03bf\u03b1\u03c4\u03af\u03b1)", "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac (\u0395\u03bb\u03bb\u03ac\u03b4\u03b1)", "\u039d\u03bf\u03c1\u03b2\u03b7\u03b3\u03b9\u03ba\u03ac (\u039d\u03bf\u03c1\u03b2\u03b7\u03b3\u03af\u03b1,Nynorsk)", "\u0399\u03c4\u03b1\u03bb\u03b9\u03ba\u03ac", "xx (YY)" }, 165 166 // display langage (<root>) 167 { "English", "French", "Croatian", "Greek", "Norwegian", "Italian", "xx" }, 168 // display country (<root>) 169 { "United States", "France", "Croatia", "Greece", "Norway", "", "YY" }, 170 // display variant (<root>) 171 { "", "", "", "", "Nynorsk", "", ""}, 172 // display name (<root>) 173 { "English (United States)", "French (France)", "Croatian (Croatia)", "Greek (Greece)", "Norwegian (Norway,Nynorsk)", "Italian", "xx (YY)" }, 174 }; 175 176 public static void main(String[] args) throws Exception { 177 new LocaleTest().run(args); 178 } 179 180 public void TestBasicGetters() { 181 for (int i = 0; i <= MAX_LOCALES; i++) { 182 Locale testLocale = new Locale(dataTable[LANG][i], dataTable[CTRY][i], dataTable[VAR][i]); 183 logln("Testing " + testLocale + "..."); 184 185 if (!testLocale.getLanguage().equals(dataTable[LANG][i])) 186 errln(" Language code mismatch: " + testLocale.getLanguage() + " versus " 187 + dataTable[LANG][i]); 188 if (!testLocale.getCountry().equals(dataTable[CTRY][i])) 189 errln(" Country code mismatch: " + testLocale.getCountry() + " versus " 190 + dataTable[CTRY][i]); 191 if (!testLocale.getVariant().equals(dataTable[VAR][i])) 192 errln(" Variant code mismatch: " + testLocale.getVariant() + " versus " 193 + dataTable[VAR][i]); 194 if (!testLocale.toString().equals(dataTable[NAME][i])) 195 errln(" Locale name mismatch: " + testLocale.toString() + " versus " 196 + dataTable[NAME][i]); 197 } 198 199 logln("Same thing without variant codes..."); 200 for (int i = 0; i <= MAX_LOCALES; i++) { 201 Locale testLocale = new Locale(dataTable[LANG][i], dataTable[CTRY][i]); 202 logln("Testing " + testLocale + "..."); 203 204 if (!testLocale.getLanguage().equals(dataTable[LANG][i])) 205 errln(" Language code mismatch: " + testLocale.getLanguage() + " versus " 206 + dataTable[LANG][i]); 207 if (!testLocale.getCountry().equals(dataTable[CTRY][i])) 208 errln(" Country code mismatch: " + testLocale.getCountry() + " versus " 209 + dataTable[CTRY][i]); 210 if (!testLocale.getVariant().equals("")) 211 errln(" Variant code mismatch: " + testLocale.getVariant() + " versus \"\""); 212 } 213 } 214 215 public void TestSimpleResourceInfo() { 216 for (int i = 0; i <= MAX_LOCALES; i++) { 217 if (dataTable[LANG][i].equals("xx")) 218 continue; 219 220 Locale testLocale = new Locale(dataTable[LANG][i], dataTable[CTRY][i], dataTable[VAR][i]); 221 logln("Testing " + testLocale + "..."); 222 223 if (!testLocale.getISO3Language().equals(dataTable[LANG3][i])) 224 errln(" ISO-3 language code mismatch: " + testLocale.getISO3Language() 225 + " versus " + dataTable[LANG3][i]); 226 if (!testLocale.getISO3Country().equals(dataTable[CTRY3][i])) 227 errln(" ISO-3 country code mismatch: " + testLocale.getISO3Country() 228 + " versus " + dataTable[CTRY3][i]); 229 /* 230 // getLCID() is currently private 231 if (!String.valueOf(testLocale.getLCID()).equals(dataTable[LCID][i])) 232 errln(" LCID mismatch: " + testLocale.getLCID() + " versus " 233 + dataTable[LCID][i]); 234 */ 235 } 236 } 237 238 /* 239 * @bug 4101316 240 * @bug 4084688 (This bug appears to be a duplicate of something, because it was fixed 241 * between 1.1.5 and 1.1.6, but I included a new test for it anyway) 242 * @bug 4052440 Stop falling back to the default locale. 243 */ 244 public void TestDisplayNames() { 245 Locale saveDefault = Locale.getDefault(); 246 Locale english = new Locale("en", "US"); 247 Locale french = new Locale("fr", "FR"); 248 Locale croatian = new Locale("hr", "HR"); 249 Locale greek = new Locale("el", "GR"); 250 251 Locale.setDefault(english); 252 logln("With default = en_US..."); 253 logln(" In default locale..."); 254 doTestDisplayNames(null, DLANG_EN, false); 255 logln(" In locale = en_US..."); 256 doTestDisplayNames(english, DLANG_EN, false); 257 logln(" In locale = fr_FR..."); 258 doTestDisplayNames(french, DLANG_FR, false); 259 logln(" In locale = hr_HR..."); 260 doTestDisplayNames(croatian, DLANG_HR, false); 261 logln(" In locale = el_GR..."); 262 doTestDisplayNames(greek, DLANG_EL, false); 263 264 Locale.setDefault(french); 265 logln("With default = fr_FR..."); 266 logln(" In default locale..."); 267 doTestDisplayNames(null, DLANG_FR, true); 268 logln(" In locale = en_US..."); 269 doTestDisplayNames(english, DLANG_EN, true); 270 logln(" In locale = fr_FR..."); 271 doTestDisplayNames(french, DLANG_FR, true); 272 logln(" In locale = hr_HR..."); 273 doTestDisplayNames(croatian, DLANG_HR, true); 274 logln(" In locale = el_GR..."); 275 doTestDisplayNames(greek, DLANG_EL, true); 276 277 Locale.setDefault(saveDefault); 278 } 279 280 private void doTestDisplayNames(Locale inLocale, int compareIndex, boolean defaultIsFrench) { 281 if (defaultIsFrench && !Locale.getDefault().getLanguage().equals("fr")) 282 errln("Default locale should be French, but it's really " + Locale.getDefault().getLanguage()); 283 else if (!defaultIsFrench && !Locale.getDefault().getLanguage().equals("en")) 284 errln("Default locale should be English, but it's really " + Locale.getDefault().getLanguage()); 285 286 for (int i = 0; i <= MAX_LOCALES; i++) { 287 Locale testLocale = new Locale(dataTable[LANG][i], dataTable[CTRY][i], dataTable[VAR][i]); 288 logln(" Testing " + testLocale + "..."); 289 290 String testLang; 291 String testCtry; 292 String testVar; 293 String testName; 294 295 if (inLocale == null) { 296 testLang = testLocale.getDisplayLanguage(); 297 testCtry = testLocale.getDisplayCountry(); 298 testVar = testLocale.getDisplayVariant(); 299 testName = testLocale.getDisplayName(); 300 } 301 else { 302 testLang = testLocale.getDisplayLanguage(inLocale); 303 testCtry = testLocale.getDisplayCountry(inLocale); 304 testVar = testLocale.getDisplayVariant(inLocale); 305 testName = testLocale.getDisplayName(inLocale); 306 } 307 308 String expectedLang; 309 String expectedCtry; 310 String expectedVar; 311 String expectedName; 312 313 expectedLang = dataTable[compareIndex][i]; 314 if (expectedLang.equals("") && defaultIsFrench) 315 expectedLang = dataTable[DLANG_EN][i]; 316 if (expectedLang.equals("")) 317 expectedLang = dataTable[DLANG_ROOT][i]; 318 319 expectedCtry = dataTable[compareIndex + 1][i]; 320 if (expectedCtry.equals("") && defaultIsFrench) 321 expectedCtry = dataTable[DCTRY_EN][i]; 322 if (expectedCtry.equals("")) 323 expectedCtry = dataTable[DCTRY_ROOT][i]; 324 325 expectedVar = dataTable[compareIndex + 2][i]; 326 if (expectedVar.equals("") && defaultIsFrench) 327 expectedVar = dataTable[DVAR_EN][i]; 328 if (expectedVar.equals("")) 329 expectedVar = dataTable[DVAR_ROOT][i]; 330 331 expectedName = dataTable[compareIndex + 3][i]; 332 if (expectedName.equals("") && defaultIsFrench) 333 expectedName = dataTable[DNAME_EN][i]; 334 if (expectedName.equals("")) 335 expectedName = dataTable[DNAME_ROOT][i]; 336 337 if (!testLang.equals(expectedLang)) 338 errln("Display language mismatch: " + testLang + " versus " + expectedLang); 339 if (!testCtry.equals(expectedCtry)) 340 errln("Display country mismatch: " + testCtry + " versus " + expectedCtry); 341 if (!testVar.equals(expectedVar)) 342 errln("Display variant mismatch: " + testVar + " versus " + expectedVar); 343 if (!testName.equals(expectedName)) 344 errln("Display name mismatch: " + testName + " versus " + expectedName); 345 } 346 } 347 348 public void TestSimpleObjectStuff() { 349 Locale test1 = new Locale("aa", "AA"); 350 Locale test2 = new Locale("aa", "AA"); 351 Locale test3 = (Locale)test1.clone(); 352 Locale test4 = new Locale("zz", "ZZ"); 353 354 if (test1 == test2 || test1 == test3 || test1 == test4 || test2 == test3) 355 errln("Some of the test variables point to the same locale!"); 356 357 if (test3 == null) 358 errln("clone() failed to produce a valid object!"); 359 360 if (!test1.equals(test2) || !test1.equals(test3) || !test2.equals(test3)) 361 errln("clone() or equals() failed: objects that should compare equal don't"); 362 363 if (test1.equals(test4) || test2.equals(test4) || test3.equals(test4)) 364 errln("equals() failed: objects that shouldn't compare equal do"); 365 366 int hash1 = test1.hashCode(); 367 int hash2 = test2.hashCode(); 368 int hash3 = test3.hashCode(); 369 370 if (hash1 != hash2 || hash1 != hash3 || hash2 != hash3) 371 errln("hashCode() failed: objects that should have the same hash code don't"); 372 } 373 374 /** 375 * @bug 4011756 4011380 376 */ 377 public void TestISO3Fallback() { 378 Locale test = new Locale("xx", "YY", ""); 379 boolean gotException = false; 380 String result = ""; 381 382 try { 383 result = test.getISO3Language(); 384 } 385 catch (MissingResourceException e) { 386 gotException = true; 387 } 388 if (!gotException) 389 errln("getISO3Language() on xx_YY returned " + result + " instead of throwing an exception"); 390 391 gotException = false; 392 try { 393 result = test.getISO3Country(); 394 } 395 catch (MissingResourceException e) { 396 gotException = true; 397 } 398 if (!gotException) 399 errln("getISO3Country() on xx_YY returned " + result + " instead of throwing an exception"); 400 } 401 402 /** 403 * @bug 4106155 4118587 7066203 404 */ 405 public void TestGetLangsAndCountries() { 406 // It didn't seem right to just do an exhaustive test of everything here, so I check 407 // for the following things: 408 // 1) Does each list have the right total number of entries? 409 // 2) Does each list contain certain language and country codes we think are important 410 // (the G7 countries, plus a couple others)? 411 // 3) Does each list have every entry formatted correctly? (i.e., two characters, 412 // all lower case for the language codes, all upper case for the country codes) 413 // 4) Is each list in sorted order? 414 String[] test = Locale.getISOLanguages(); 415 String[] spotCheck1 = { "en", "es", "fr", "de", "it", "ja", "ko", "zh", "th", 416 "he", "id", "iu", "ug", "yi", "za" }; 417 418 if (test.length != 188) 419 errln("Expected getISOLanguages() to return 188 languages; it returned " + test.length); 420 else { 421 for (int i = 0; i < spotCheck1.length; i++) { 422 int j; 423 for (j = 0; j < test.length; j++) 424 if (test[j].equals(spotCheck1[i])) 425 break; 426 if (j == test.length || !test[j].equals(spotCheck1[i])) 427 errln("Couldn't find " + spotCheck1[i] + " in language list."); 428 } 429 } 430 for (int i = 0; i < test.length; i++) { 431 if (!test[i].equals(test[i].toLowerCase())) 432 errln(test[i] + " is not all lower case."); 433 if (test[i].length() != 2) 434 errln(test[i] + " is not two characters long."); 435 if (i > 0 && test[i].compareTo(test[i - 1]) <= 0) 436 errln(test[i] + " appears in an out-of-order position in the list."); 437 } 438 439 test = Locale.getISOCountries(); 440 String[] spotCheck2 = { "US", "CA", "GB", "FR", "DE", "IT", "JP", "KR", "CN", "TW", "TH" }; 441 442 443 if (test.length != 250) 444 errln("Expected getISOCountries to return 250 countries; it returned " + test.length); 445 else { 446 for (int i = 0; i < spotCheck2.length; i++) { 447 int j; 448 for (j = 0; j < test.length; j++) 449 if (test[j].equals(spotCheck2[i])) 450 break; 451 if (j == test.length || !test[j].equals(spotCheck2[i])) 452 errln("Couldn't find " + spotCheck2[i] + " in country list."); 453 } 454 } 455 for (int i = 0; i < test.length; i++) { 456 if (!test[i].equals(test[i].toUpperCase())) 457 errln(test[i] + " is not all upper case."); 458 if (test[i].length() != 2) 459 errln(test[i] + " is not two characters long."); 460 if (i > 0 && test[i].compareTo(test[i - 1]) <= 0) 461 errln(test[i] + " appears in an out-of-order position in the list."); 462 } 463 } 464 465 /** 466 * @bug 4126880 467 */ 468 void Test4126880() { 469 String[] test; 470 471 test = Locale.getISOCountries(); 472 test[0] = "SUCKER!!!"; 473 test = Locale.getISOCountries(); 474 if (test[0].equals("SUCKER!!!")) 475 errln("Changed internal country code list!"); 476 477 test = Locale.getISOLanguages(); 478 test[0] = "HAHAHAHA!!!"; 479 test = Locale.getISOLanguages(); 480 if (test[0].equals("HAHAHAHA!!!")) // Fixed typo 481 errln("Changes internal language code list!"); 482 } 483 484 /** 485 * @bug 4107014 486 */ 487 public void TestGetAvailableLocales() { 488 Locale[] locales = Locale.getAvailableLocales(); 489 if (locales == null || locales.length == 0) 490 errln("Locale.getAvailableLocales() returned no installed locales!"); 491 else { 492 logln("Locale.getAvailableLocales() returned a list of " + locales.length + " locales."); 493 for (int i = 0; i < locales.length; i++) 494 logln(locales[i].toString()); 495 } 496 } 497 498 /** 499 * @bug 4135316 500 */ 501 public void TestBug4135316() { 502 Locale[] locales1 = Locale.getAvailableLocales(); 503 Locale[] locales2 = Locale.getAvailableLocales(); 504 if (locales1 == locales2) 505 errln("Locale.getAvailableLocales() doesn't clone its internal storage!"); 506 } 507 508 /** 509 * @bug 4107953 510 */ 511 /* 512 test commented out pending API-change approval 513 public void TestGetLanguagesForCountry() { 514 String[] languages = Locale.getLanguagesForCountry("US"); 515 516 if (!searchStringArrayFor("en", languages)) 517 errln("Didn't get en as a language for US"); 518 519 languages = Locale.getLanguagesForCountry("FR"); 520 if (!searchStringArrayFor("fr", languages)) 521 errln("Didn't get fr as a language for FR"); 522 523 languages = Locale.getLanguagesForCountry("CH"); 524 if (!searchStringArrayFor("fr", languages)) 525 errln("Didn't get fr as a language for CH"); 526 if (!searchStringArrayFor("it", languages)) 527 errln("Didn't get it as a language for CH"); 528 if (!searchStringArrayFor("de", languages)) 529 errln("Didn't get de as a language for CH"); 530 531 languages = Locale.getLanguagesForCountry("JP"); 532 if (!searchStringArrayFor("ja", languages)) 533 errln("Didn't get ja as a language for JP"); 534 } 535 */ 536 537 private boolean searchStringArrayFor(String s, String[] array) { 538 for (int i = 0; i < array.length; i++) 539 if (s.equals(array[i])) 540 return true; 541 return false; 542 } 543 /** 544 * @bug 4110613 545 */ 546 public void TestSerialization() throws ClassNotFoundException, OptionalDataException, 547 IOException, StreamCorruptedException 548 { 549 ObjectOutputStream ostream; 550 ByteArrayOutputStream obstream; 551 byte[] bytes = null; 552 553 obstream = new ByteArrayOutputStream(); 554 ostream = new ObjectOutputStream(obstream); 555 556 Locale test1 = new Locale("zh", "TW", ""); 557 int dummy = test1.hashCode(); // fill in the cached hash-code value 558 ostream.writeObject(test1); 559 560 bytes = obstream.toByteArray(); 561 562 ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(bytes)); 563 564 Locale test2 = (Locale)(istream.readObject()); 565 566 if (!test1.equals(test2) || test1.hashCode() != test2.hashCode()) 567 errln("Locale failed to deserialize correctly."); 568 } 569 570 /** 571 * @bug 4118587 572 */ 573 public void TestSimpleDisplayNames() { 574 // This test is different from TestDisplayNames because TestDisplayNames checks 575 // fallback behavior, combination of language and country names to form locale 576 // names, and other stuff like that. This test just checks specific language 577 // and country codes to make sure we have the correct names for them. 578 String[] languageCodes = { "he", "id", "iu", "ug", "yi", "za" }; 579 String[] languageNames = { "Hebrew", "Indonesian", "Inuktitut", "Uighur", "Yiddish", 580 "Zhuang" }; 581 582 for (int i = 0; i < languageCodes.length; i++) { 583 String test = (new Locale(languageCodes[i], "", "")).getDisplayLanguage(Locale.US); 584 if (!test.equals(languageNames[i])) 585 errln("Got wrong display name for " + languageCodes[i] + ": Expected \"" + 586 languageNames[i] + "\", got \"" + test + "\"."); 587 } 588 } 589 590 /** 591 * @bug 4118595 592 */ 593 public void TestUninstalledISO3Names() { 594 // This test checks to make sure getISO3Language and getISO3Country work right 595 // even for locales that are not installed. 596 String[] iso2Languages = { "am", "ba", "fy", "mr", "rn", "ss", "tw", "zu" }; 597 String[] iso3Languages = { "amh", "bak", "fry", "mar", "run", "ssw", "twi", "zul" }; 598 599 for (int i = 0; i < iso2Languages.length; i++) { 600 String test = (new Locale(iso2Languages[i], "", "")).getISO3Language(); 601 if (!test.equals(iso3Languages[i])) 602 errln("Got wrong ISO3 code for " + iso2Languages[i] + ": Expected \"" + 603 iso3Languages[i] + "\", got \"" + test + "\"."); 604 } 605 606 String[] iso2Countries = { "AF", "BW", "KZ", "MO", "MN", "SB", "TC", "ZW" }; 607 String[] iso3Countries = { "AFG", "BWA", "KAZ", "MAC", "MNG", "SLB", "TCA", "ZWE" }; 608 609 for (int i = 0; i < iso2Countries.length; i++) { 610 String test = (new Locale("", iso2Countries[i], "")).getISO3Country(); 611 if (!test.equals(iso3Countries[i])) 612 errln("Got wrong ISO3 code for " + iso2Countries[i] + ": Expected \"" + 613 iso3Countries[i] + "\", got \"" + test + "\"."); 614 } 615 } 616 617 /** 618 * @bug 4052404 4778440 619 */ 620 public void TestChangedISO639Codes() { 621 Locale hebrewOld = new Locale("iw", "IL", ""); 622 Locale hebrewNew = new Locale("he", "IL", ""); 623 Locale yiddishOld = new Locale("ji", "IL", ""); 624 Locale yiddishNew = new Locale("yi", "IL", ""); 625 Locale indonesianOld = new Locale("in", "", ""); 626 Locale indonesianNew = new Locale("id", "", ""); 627 628 if (!hebrewNew.getLanguage().equals("iw")) 629 errln("Got back wrong language code for Hebrew: expected \"iw\", got \"" + 630 hebrewNew.getLanguage() + "\""); 631 if (!yiddishNew.getLanguage().equals("ji")) 632 errln("Got back wrong language code for Yiddish: expected \"ji\", got \"" + 633 yiddishNew.getLanguage() + "\""); 634 if (!indonesianNew.getLanguage().equals("in")) 635 errln("Got back wrong language code for Indonesian: expected \"in\", got \"" + 636 indonesianNew.getLanguage() + "\""); 637 } 638 639 /** 640 * @bug 4092475 641 * I could not reproduce this bug. I'm pretty convinced it was fixed with the 642 * big locale-data reorg of 10/28/97. The lookup logic for language and country 643 * display names was also changed at that time in that check-in. --rtg 3/20/98 644 645 * This test is not designed to work in any other locale but en_US. 646 * Most of the LocaleElements do not contain display names for other languages, 647 * so this test fails (bug 4289223) when run under different locales. For example, 648 * LocaleElements_es as of kestrel does not have a localized name for Japanese, so 649 * the getDisplayName method asks the default locale for a display name. The Japanese 650 * localized name for "Japanese" does not equal "Japanese" so this test fails for es 651 * display names if run under a ja locale. Eventually, he LocaleElements should probably 652 * be updated to contain more localized language and region display names. 653 * 1999-11-19 joconner 654 * 655 */ 656 public void TestAtypicalLocales() { 657 Locale[] localesToTest = { new Locale("de", "CA"), 658 new Locale("ja", "ZA"), 659 new Locale("ru", "MX"), 660 new Locale("en", "FR"), 661 new Locale("es", "DE"), 662 new Locale("", "HR"), 663 new Locale("", "SE"), 664 new Locale("", "DO"), 665 new Locale("", "BE") }; 666 String[] englishDisplayNames = { "German (Canada)", 667 "Japanese (South Africa)", 668 "Russian (Mexico)", 669 "English (France)", 670 "Spanish (Germany)", 671 "Croatia", 672 "Sweden", 673 "Dominican Republic", 674 "Belgium" }; 675 String[] frenchDisplayNames = { "allemand (Canada)", 676 "japonais (Afrique du Sud)", 677 "russe (Mexique)", 678 "anglais (France)", 679 "espagnol (Allemagne)", 680 "Croatie", 681 "Su\u00e8de", 682 "R\u00e9publique Dominicaine", 683 "Belgique" }; 684 String[] spanishDisplayNames = { "alem\u00E1n (Canad\u00E1)", 685 "japon\u00E9s (Sud\u00E1frica)", 686 "ruso (M\u00e9xico)", 687 "ingl\u00E9s (Francia)", 688 "espa\u00f1ol (Alemania)", 689 "Croacia", 690 "Suecia", 691 "Rep\u00fablica Dominicana", 692 "B\u00E9lgica" }; 693 694 695 // save the default locale and set to the new default to en_US 696 Locale defaultLocale = Locale.getDefault(); 697 Locale.setDefault(Locale.US); 698 699 for (int i = 0; i < localesToTest.length; i++) { 700 String name = localesToTest[i].getDisplayName(Locale.US); 701 logln(name); 702 if (!name.equals(englishDisplayNames[i])) 703 errln("Lookup in English failed: expected \"" + englishDisplayNames[i] 704 + "\", got \"" + name + "\""); 705 } 706 707 for (int i = 0; i < localesToTest.length; i++) { 708 String name = localesToTest[i].getDisplayName(new Locale("es", "ES")); 709 logln(name); 710 if (!name.equals(spanishDisplayNames[i])) 711 errln("Lookup in Spanish failed: expected \"" + spanishDisplayNames[i] 712 + "\", got \"" + name + "\""); 713 } 714 715 for (int i = 0; i < localesToTest.length; i++) { 716 String name = localesToTest[i].getDisplayName(Locale.FRANCE); 717 logln(name); 718 if (!name.equals(frenchDisplayNames[i])) 719 errln("Lookup in French failed: expected \"" + frenchDisplayNames[i] 720 + "\", got \"" + name + "\""); 721 } 722 723 // restore the default locale for other tests 724 Locale.setDefault(defaultLocale); 725 } 726 727 /** 728 * @bug 4126371 729 */ 730 public void TestNullDefault() { 731 // why on earth anyone would ever try to do this is beyond me, but we should 732 // definitely make sure we don't let them 733 boolean gotException = false; 734 try { 735 Locale.setDefault(null); 736 } 737 catch (NullPointerException e) { 738 // all other exception types propagate through here back to the test harness 739 gotException = true; 740 } 741 if (Locale.getDefault() == null) 742 errln("Locale.getDefault() allowed us to set default to NULL!"); 743 if (!gotException) 744 errln("Trying to set default locale to NULL didn't throw exception!"); 745 } 746 747 /** 748 * @bug 4135752 749 * This would be better tested by the LocaleDataTest. Will move it when I 750 * get the LocaleDataTest working again. 751 */ 752 public void TestThaiCurrencyFormat() { 753 DecimalFormat thaiCurrency = (DecimalFormat)NumberFormat.getCurrencyInstance( 754 new Locale("th", "TH")); 755 if (!thaiCurrency.getPositivePrefix().equals("\u0e3f")) 756 errln("Thai currency prefix wrong: expected \"\u0e3f\", got \"" + 757 thaiCurrency.getPositivePrefix() + "\""); 758 if (!thaiCurrency.getPositiveSuffix().equals("")) 759 errln("Thai currency suffix wrong: expected \"\", got \"" + 760 thaiCurrency.getPositiveSuffix() + "\""); 761 } 762 763 /** 764 * @bug 4122371 765 * Confirm that Euro support works. This test is pretty rudimentary; all it does 766 * is check that any locales with the EURO variant format a number using the 767 * Euro currency symbol. 768 * 769 * ASSUME: All locales encode the Euro character "\u20AC". 770 * If this is changed to use the single-character Euro symbol, this 771 * test must be updated. 772 * 773 * DON'T ASSUME: Any specific countries support the Euro. Instead, 774 * iterate through all locales. 775 */ 776 public void TestEuroSupport() { 777 final String EURO_VARIANT = "EURO"; 778 final String EURO_CURRENCY = "\u20AC"; // Look for this string in formatted Euro currency 779 780 Locale[] locales = NumberFormat.getAvailableLocales(); 781 for (int i=0; i<locales.length; ++i) { 782 Locale loc = locales[i]; 783 if (loc.getVariant().indexOf(EURO_VARIANT) >= 0) { 784 NumberFormat nf = NumberFormat.getCurrencyInstance(loc); 785 String pos = nf.format(271828.182845); 786 String neg = nf.format(-271828.182845); 787 if (pos.indexOf(EURO_CURRENCY) >= 0 && 788 neg.indexOf(EURO_CURRENCY) >= 0) { 789 logln("Ok: " + loc.toString() + 790 ": " + pos + " / " + neg); 791 } 792 else { 793 errln("Fail: " + loc.toString() + 794 " formats without " + EURO_CURRENCY + 795 ": " + pos + " / " + neg + 796 "\n*** THIS FAILURE MAY ONLY MEAN THAT LOCALE DATA HAS CHANGED ***"); 797 } 798 } 799 } 800 } 801 802 /** 803 * @bug 4139504 804 * toString() doesn't work with language_VARIANT. 805 */ 806 public void TestToString() { 807 Object[] DATA = { 808 new Locale("xx", "", ""), "xx", 809 new Locale("", "YY", ""), "_YY", 810 new Locale("", "", "ZZ"), "", 811 new Locale("xx", "YY", ""), "xx_YY", 812 new Locale("xx", "", "ZZ"), "xx__ZZ", 813 new Locale("", "YY", "ZZ"), "_YY_ZZ", 814 new Locale("xx", "YY", "ZZ"), "xx_YY_ZZ", 815 }; 816 for (int i=0; i<DATA.length; i+=2) { 817 Locale loc = (Locale)DATA[i]; 818 String fmt = (String)DATA[i+1]; 819 if (!loc.toString().equals(fmt)) { 820 errln("Fail: Locale.toString(" + fmt + ")=>" + loc); 821 } 822 } 823 } 824 825 /** 826 * @bug 4105828 827 * Currency symbol in zh is wrong. We will test this at the NumberFormat 828 * end to test the whole pipe. 829 */ 830 public void Test4105828() { 831 Locale[] LOC = { Locale.CHINESE, new Locale("zh", "CN", ""), 832 new Locale("zh", "TW", ""), new Locale("zh", "HK", "") }; 833 for (int i=0; i<LOC.length; ++i) { 834 NumberFormat fmt = NumberFormat.getPercentInstance(LOC[i]); 835 String result = fmt.format(1); 836 if (!result.equals("100%")) { 837 errln("Percent for " + LOC[i] + " should be 100%, got " + result); 838 } 839 } 840 } 841 842 /** 843 * @bug 4139940 844 * Couldn't reproduce this bug -- probably was fixed earlier. 845 * 846 * ORIGINAL BUG REPORT: 847 * -- basically, hungarian for monday shouldn't have an \u00f4 848 * (o circumflex)in it instead it should be an o with 2 inclined 849 * (right) lines over it.. 850 * 851 * You may wonder -- why do all this -- why not just add a line to 852 * LocaleData? Well, I could see by inspection that the locale file had the 853 * right character in it, so I wanted to check the rest of the pipeline -- a 854 * very remote possibility, but I wanted to be sure. The other possibility 855 * is that something is wrong with the font mapping subsystem, but we can't 856 * test that here. 857 */ 858 public void Test4139940() { 859 Locale mylocale=new Locale("hu", "", ""); 860 Date mydate = new Date(98,3,13); // A Monday 861 DateFormat df_full = new SimpleDateFormat("EEEE", mylocale); 862 String str = df_full.format(mydate); 863 // Make sure that o circumflex (\u00F4) is NOT there, and 864 // o double acute (\u0151) IS. 865 if (str.indexOf('\u0151') < 0 || str.indexOf('\u00F4') >= 0) 866 errln("Fail: Monday in Hungarian is wrong"); 867 } 868 869 /** 870 * @bug 4143951 871 * Russian first day of week should be Monday. Confirmed. 872 */ 873 public void Test4143951() { 874 Calendar cal = Calendar.getInstance(new Locale("ru", "", "")); 875 if (cal.getFirstDayOfWeek() != Calendar.MONDAY) { 876 errln("Fail: First day of week in Russia should be Monday"); 877 } 878 } 879 880 /** 881 * @bug 4147315 882 * java.util.Locale.getISO3Country() works wrong for non ISO-3166 codes. 883 * Should throw an exception for unknown locales 884 */ 885 public void Test4147315() { 886 // Try with codes that are the wrong length but happen to match text 887 // at a valid offset in the mapping table 888 Locale locale = new Locale("aaa", "CCC"); 889 890 try { 891 String result = locale.getISO3Country(); 892 893 errln("ERROR: getISO3Country() returns: " + result + 894 " for locale '" + locale + "' rather than exception" ); 895 } catch(MissingResourceException e) { } 896 } 897 898 /** 899 * @bug 4147317 4940539 900 * java.util.Locale.getISO3Language() works wrong for non ISO-639 codes. 901 * Should throw an exception for unknown locales, except they have three 902 * letter language codes. 903 */ 904 public void Test4147317() { 905 // Try a three letter language code, and check whether it is 906 // returned as is. 907 Locale locale = new Locale("aaa", "CCC"); 908 909 String result = locale.getISO3Language(); 910 if (!result.equals("aaa")) { 911 errln("ERROR: getISO3Language() returns: " + result + 912 " for locale '" + locale + "' rather than returning it as is" ); 913 } 914 915 // Try an invalid two letter language code, and check whether it 916 // throws a MissingResourceException. 917 locale = new Locale("zz", "CCC"); 918 919 try { 920 result = locale.getISO3Language(); 921 922 errln("ERROR: getISO3Language() returns: " + result + 923 " for locale '" + locale + "' rather than exception" ); 924 } catch(MissingResourceException e) { } 925 } 926 927 /* 928 * @bug 4147552 4778440 929 */ 930 public void Test4147552() { 931 Locale[] locales = { new Locale("no", "NO"), new Locale("no", "NO", "B"), 932 new Locale("no", "NO", "NY") }; 933 String[] englishDisplayNames = { "Norwegian (Norway)", 934 "Norwegian (Norway,Bokm\u00e5l)", 935 "Norwegian (Norway,Nynorsk)" }; 936 String[] norwegianDisplayNames = { "norsk (Norge)", 937 "norsk (Norge,bokm\u00e5l)", "norsk (Norge,nynorsk)" }; 938 939 for (int i = 0; i < locales.length; i++) { 940 Locale loc = locales[i]; 941 if (!loc.getDisplayName(Locale.US).equals(englishDisplayNames[i])) 942 errln("English display-name mismatch: expected " + 943 englishDisplayNames[i] + ", got " + loc.getDisplayName()); 944 if (!loc.getDisplayName(loc).equals(norwegianDisplayNames[i])) 945 errln("Norwegian display-name mismatch: expected " + 946 norwegianDisplayNames[i] + ", got " + 947 loc.getDisplayName(loc)); 948 } 949 } 950 951 static String escapeUnicode(String s) { 952 StringBuffer buf = new StringBuffer(); 953 for (int i=0; i<s.length(); ++i) { 954 char c = s.charAt(i); 955 if (c >= 0x20 && c <= 0x7F) buf.append(c); 956 else { 957 buf.append("\\u"); 958 String h = "000" + Integer.toHexString(c); 959 if (h.length() > 4) h = h.substring(h.length() - 4); 960 buf.append(h); 961 } 962 } 963 return buf.toString(); 964 } 965 }