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