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