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