1 /* 2 ******************************************************************************* 3 * Copyright (C) 2003-2015, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 package com.ibm.icu.dev.test.util; 8 9 import java.util.Arrays; 10 import java.util.HashSet; 11 12 import com.ibm.icu.dev.test.TestFmwk; 13 import com.ibm.icu.impl.ICUResourceBundle; 14 import com.ibm.icu.lang.UScript; 15 import com.ibm.icu.text.UnicodeSet; 16 import com.ibm.icu.text.UnicodeSetIterator; 17 import com.ibm.icu.util.ICUException; 18 import com.ibm.icu.util.LocaleData; 19 import com.ibm.icu.util.ULocale; 20 21 /** 22 * @author ram 23 * 24 * To change the template for this generated type comment go to 25 * Window>Preferences>Java>Code Generation>Code and Comments 26 */ 27 public class LocaleDataTest extends TestFmwk{ 28 main(String[] args)29 public static void main(String[] args) throws Exception{ 30 new LocaleDataTest().run(args); 31 } 32 33 private ULocale[] availableLocales = null; 34 LocaleDataTest()35 public LocaleDataTest(){ 36 } init()37 protected void init(){ 38 availableLocales = ICUResourceBundle.getAvailableULocales(); 39 } TestPaperSize()40 public void TestPaperSize(){ 41 for(int i = 0; i < availableLocales.length; i++){ 42 ULocale locale = availableLocales[i]; 43 LocaleData.PaperSize paperSize = LocaleData.getPaperSize(locale); 44 // skip testing of "in" .. deprecated code for Indonesian 45 String lang = locale.getLanguage(); 46 if(lang.equals("in")){ 47 continue; 48 } 49 ULocale fullLoc = ULocale.addLikelySubtags(locale); 50 if(fullLoc.toString().indexOf("_BZ") >= 0 || fullLoc.toString().indexOf("_CA") >= 0 || 51 fullLoc.toString().indexOf("_CL") >= 0 || fullLoc.toString().indexOf("_CO") >= 0 || 52 fullLoc.toString().indexOf("_CR") >= 0 || fullLoc.toString().indexOf("_GT") >= 0 || 53 fullLoc.toString().indexOf("_MX") >= 0 || fullLoc.toString().indexOf("_NI") >= 0 || 54 fullLoc.toString().indexOf("_PA") >= 0 || fullLoc.toString().indexOf("_PH") >= 0 || 55 fullLoc.toString().indexOf("_PR") >= 0 || fullLoc.toString().indexOf("_SV") >= 0 || 56 fullLoc.toString().indexOf("_US") >= 0 || fullLoc.toString().indexOf("_VE") >= 0 ){ 57 if(paperSize.getHeight()!= 279 || paperSize.getWidth() != 216 ){ 58 errln("PaperSize did not return the expected value for locale "+ locale+ 59 " Expected height: 279 width: 216."+ 60 " Got height: "+paperSize.getHeight()+" width: "+paperSize.getWidth() 61 ); 62 }else{ 63 logln("PaperSize returned the expected values for locale " + locale); 64 } 65 }else{ 66 if(paperSize.getHeight()!= 297 || paperSize.getWidth() != 210 ){ 67 errln("PaperSize did not return the expected value for locale "+ locale + 68 " Expected height: 297 width: 210."+ 69 " Got height: "+paperSize.getHeight() +" width: "+paperSize.getWidth() 70 ); 71 }else{ 72 logln("PaperSize returned the expected values for locale " + locale); 73 } 74 } 75 } 76 } TestMeasurementSystem()77 public void TestMeasurementSystem(){ 78 for(int i=0; i<availableLocales.length; i++){ 79 ULocale locale = availableLocales[i]; 80 LocaleData.MeasurementSystem ms = LocaleData.getMeasurementSystem(locale); 81 // skip testing of "in" .. deprecated code for Indonesian 82 String lang = locale.getLanguage(); 83 if(lang.equals("in")){ 84 continue; 85 } 86 ULocale fullLoc = ULocale.addLikelySubtags(locale); 87 if(fullLoc.toString().indexOf("_US") >= 0 || fullLoc.toString().indexOf("_MM") >= 0 || fullLoc.toString().indexOf("_LR") >= 0){ 88 if(ms == LocaleData.MeasurementSystem.US){ 89 logln("Got the expected measurement system for locale: " + locale); 90 }else{ 91 errln("Did not get the expected measurement system for locale: "+ locale); 92 } 93 } else if(fullLoc.toString().indexOf("_GB") >= 0){ 94 if(ms == LocaleData.MeasurementSystem.UK){ 95 logln("Got the expected measurement system for locale: " + locale); 96 }else{ 97 errln("Did not get the expected measurement system for locale: "+ locale); 98 } 99 }else{ 100 if(ms == LocaleData.MeasurementSystem.SI){ 101 logln("Got the expected measurement system for locale: " + locale); 102 }else{ 103 errln("Did not get the expected measurement system for locale: "+ locale); 104 } 105 } 106 } 107 } 108 109 // Simple test case for checking exemplar character type coverage TestEnglishExemplarCharacters()110 public void TestEnglishExemplarCharacters() { 111 final char[] testChars = { 112 0x61, // standard 113 0xE1, // auxiliary 114 0x41, // index 115 0, // filler for deprecated currency exemplar 116 0x2D, // punctuation 117 }; 118 LocaleData ld = LocaleData.getInstance(ULocale.ENGLISH); 119 for (int type = 0; type < LocaleData.ES_COUNT; type++) { 120 UnicodeSet exSet = ld.getExemplarSet(0, type); 121 if (exSet != null) { 122 if (testChars[type] > 0 && !exSet.contains(testChars[type])) { 123 errln("Character '" + testChars[type] + "' is not included in exemplar type " + type); 124 } 125 } 126 } 127 try { 128 ld.getExemplarSet(0, LocaleData.ES_COUNT); // out of bounds value 129 throw new ICUException("Test failure; should throw exception"); 130 } catch (IllegalArgumentException e) { 131 assertEquals("", "java.lang.ArrayIndexOutOfBoundsException", e.getCause().getClass().getName()); 132 } 133 134 } 135 136 // Bundle together a UnicodeSet (of expemplars) and ScriptCode combination. 137 // We keep a set of combinations that have already been tested, to 138 // avoid repeated (time consuming) retesting of the same data. 139 // Instances of this class must be well behaved as members of a set. 140 static class ExemplarGroup { 141 private int[] scs; 142 private UnicodeSet set; 143 ExemplarGroup(UnicodeSet s, int[] scriptCodes)144 ExemplarGroup(UnicodeSet s, int[] scriptCodes) { 145 set = s; 146 scs = scriptCodes; 147 } hashCode()148 public int hashCode() { 149 int hash = 0; 150 for (int i=0; i<scs.length && i<4; i++) { 151 hash = (hash<<8)+scs[i]; 152 } 153 return hash; 154 } equals(Object other)155 public boolean equals(Object other) { 156 ExemplarGroup o = (ExemplarGroup)other; 157 boolean r = Arrays.equals(scs, o.scs) && 158 set.equals(o.set); 159 return r; 160 } 161 } 162 TestExemplarSet()163 public void TestExemplarSet(){ 164 HashSet testedExemplars = new HashSet(); 165 int equalCount = 0; 166 for(int i=0; i<availableLocales.length; i++){ 167 ULocale locale = availableLocales[i]; 168 int[] scriptCodes = UScript.getCode(locale); 169 if (scriptCodes==null) { 170 // I hate the JDK's solution for deprecated language codes. 171 // Why does the Locale constructor change the string I passed to it ? 172 // such a broken hack !!!!! 173 // so in effect I can never test the script code for Indonesian :( 174 if(locale.toString().indexOf(("in"))<0){ 175 errln("UScript.getCode returned null for locale: " + locale); 176 } 177 continue; 178 } 179 UnicodeSet exemplarSets[] = new UnicodeSet[2]; 180 for (int k=0; k<2; ++k) { // for casing option in (normal, caseInsensitive) 181 int option = (k==0) ? 0 : UnicodeSet.CASE; 182 UnicodeSet exemplarSet = LocaleData.getExemplarSet(locale, option); 183 exemplarSets[k] = exemplarSet; 184 ExemplarGroup exGrp = new ExemplarGroup(exemplarSet, scriptCodes); 185 if (!testedExemplars.contains(exGrp)) { 186 testedExemplars.add(exGrp); 187 UnicodeSet[] sets = new UnicodeSet[scriptCodes.length]; 188 // create the UnicodeSets for the script 189 for(int j=0; j < scriptCodes.length; j++){ 190 sets[j] = new UnicodeSet("[:" + UScript.getShortName(scriptCodes[j]) + ":]"); 191 } 192 boolean existsInScript = false; 193 UnicodeSetIterator iter = new UnicodeSetIterator(exemplarSet); 194 // iterate over the 195 while (!existsInScript && iter.nextRange()) { 196 if (iter.codepoint != UnicodeSetIterator.IS_STRING) { 197 for(int j=0; j<sets.length; j++){ 198 if(sets[j].contains(iter.codepoint, iter.codepointEnd)){ 199 existsInScript = true; 200 break; 201 } 202 } 203 } else { 204 for(int j=0; j<sets.length; j++){ 205 if(sets[j].contains(iter.string)){ 206 existsInScript = true; 207 break; 208 } 209 } 210 } 211 } 212 if(existsInScript == false){ 213 errln("ExemplarSet containment failed for locale : "+ locale); 214 } 215 } 216 } 217 // This is expensive, so only do it if it will be visible 218 if (isVerbose()) { 219 logln(locale.toString() + " exemplar " + exemplarSets[0]); 220 logln(locale.toString() + " exemplar(case-folded) " + exemplarSets[1]); 221 } 222 assertTrue(locale.toString() + " case-folded is a superset", 223 exemplarSets[1].containsAll(exemplarSets[0])); 224 if (exemplarSets[1].equals(exemplarSets[0])) { 225 ++equalCount; 226 } 227 } 228 // Note: The case-folded set should sometimes be a strict superset 229 // and sometimes be equal. 230 assertTrue("case-folded is sometimes a strict superset, and sometimes equal", 231 equalCount > 0 && equalCount < availableLocales.length); 232 } TestExemplarSet2()233 public void TestExemplarSet2(){ 234 int equalCount = 0; 235 HashSet testedExemplars = new HashSet(); 236 for(int i=0; i<availableLocales.length; i++){ 237 ULocale locale = availableLocales[i]; 238 LocaleData ld = LocaleData.getInstance(locale); 239 int[] scriptCodes = UScript.getCode(locale); 240 if (scriptCodes==null) { 241 if(locale.toString().indexOf(("in"))<0){ 242 errln("UScript.getCode returned null for locale: "+ locale); 243 } 244 continue; 245 } 246 UnicodeSet exemplarSets[] = new UnicodeSet[4]; 247 248 for (int k=0; k<2; ++k) { // for casing option in (normal, uncased) 249 int option = (k==0) ? 0 : UnicodeSet.CASE; 250 for(int h=0; h<2; ++h){ 251 int type = (h==0) ? LocaleData.ES_STANDARD : LocaleData.ES_AUXILIARY; 252 253 UnicodeSet exemplarSet = ld.getExemplarSet(option, type); 254 exemplarSets[k*2+h] = exemplarSet; 255 256 ExemplarGroup exGrp = new ExemplarGroup(exemplarSet, scriptCodes); 257 if (!testedExemplars.contains(exGrp)) { 258 testedExemplars.add(exGrp); 259 UnicodeSet[] sets = new UnicodeSet[scriptCodes.length]; 260 // create the UnicodeSets for the script 261 for(int j=0; j < scriptCodes.length; j++){ 262 sets[j] = new UnicodeSet("[:" + UScript.getShortName(scriptCodes[j]) + ":]"); 263 } 264 boolean existsInScript = false; 265 UnicodeSetIterator iter = new UnicodeSetIterator(exemplarSet); 266 // iterate over the 267 while (!existsInScript && iter.nextRange()) { 268 if (iter.codepoint != UnicodeSetIterator.IS_STRING) { 269 for(int j=0; j<sets.length; j++){ 270 if(sets[j].contains(iter.codepoint, iter.codepointEnd)){ 271 existsInScript = true; 272 break; 273 } 274 } 275 } else { 276 for(int j=0; j<sets.length; j++){ 277 if(sets[j].contains(iter.string)){ 278 existsInScript = true; 279 break; 280 } 281 } 282 } 283 } 284 // TODO: How to verify LocaleData.ES_AUXILIARY ??? 285 if(existsInScript == false && h == 0){ 286 errln("ExemplarSet containment failed for locale,option,type : "+ locale + ", " + option + ", " + type); 287 } 288 } 289 } 290 } 291 // This is expensive, so only do it if it will be visible 292 if (isVerbose()) { 293 logln(locale.toString() + " exemplar(ES_STANDARD)" + exemplarSets[0]); 294 logln(locale.toString() + " exemplar(ES_AUXILIARY) " + exemplarSets[1]); 295 logln(locale.toString() + " exemplar(case-folded,ES_STANDARD) " + exemplarSets[2]); 296 logln(locale.toString() + " exemplar(case-folded,ES_AUXILIARY) " + exemplarSets[3]); 297 } 298 assertTrue(locale.toString() + " case-folded is a superset", 299 exemplarSets[2].containsAll(exemplarSets[0])); 300 assertTrue(locale.toString() + " case-folded is a superset", 301 exemplarSets[3].containsAll(exemplarSets[1])); 302 if (exemplarSets[2].equals(exemplarSets[0])) { 303 ++equalCount; 304 } 305 if (exemplarSets[3].equals(exemplarSets[1])) { 306 ++equalCount; 307 } 308 } 309 // Note: The case-folded set should sometimes be a strict superset 310 // and sometimes be equal. 311 assertTrue("case-folded is sometimes a strict superset, and sometimes equal", 312 equalCount > 0 && equalCount < availableLocales.length * 2); 313 } 314 315 // Test case created for checking type coverage of static getExemplarSet method. 316 // See #9785, #9794 and #9795 TestExemplarSetTypes()317 public void TestExemplarSetTypes() { 318 final String[] testLocales = { 319 "am", // No auxiliary / index exemplars as of ICU 50 320 "en", 321 "th", // #9785 322 "foo", // Bogus locale 323 }; 324 325 final int[] testTypes = { 326 LocaleData.ES_STANDARD, 327 LocaleData.ES_AUXILIARY, 328 LocaleData.ES_INDEX, 329 LocaleData.ES_CURRENCY, 330 LocaleData.ES_PUNCTUATION, 331 }; 332 333 final String[] testTypeNames = { 334 "ES_STANDARD", 335 "ES_AUXILIARY", 336 "ES_INDEX", 337 "ES_CURRENCY", 338 "ES_PUNCTUATION", 339 }; 340 341 for (String locstr : testLocales) { 342 ULocale loc = new ULocale(locstr); 343 for (int i = 0; i < testTypes.length; i++) { 344 try { 345 UnicodeSet set = LocaleData.getExemplarSet(loc, 0, testTypes[i]); 346 if (set == null) { 347 // Not sure null is really OK (#9795) 348 logln(loc + "(" + testTypeNames[i] + ") returned null"); 349 } else if (set.isEmpty()) { 350 // This is probably reasonable when data is absent 351 logln(loc + "(" + testTypeNames[i] + ") returned an empty set"); 352 } 353 } catch (Exception e) { 354 errln(loc + "(" + testTypeNames[i] + ") Exception:" + e.getMessage()); 355 } 356 } 357 } 358 } 359 TestCoverage()360 public void TestCoverage(){ 361 LocaleData ld = LocaleData.getInstance(); 362 boolean t = ld.getNoSubstitute(); 363 ld.setNoSubstitute(t); 364 assertEquals("LocaleData get/set NoSubstitute", 365 t, 366 ld.getNoSubstitute()); 367 368 logln(ld.getDelimiter(LocaleData.QUOTATION_START)); 369 logln(ld.getDelimiter(LocaleData.QUOTATION_END)); 370 logln(ld.getDelimiter(LocaleData.ALT_QUOTATION_START)); 371 logln(ld.getDelimiter(LocaleData.ALT_QUOTATION_END)); 372 } 373 TestFallback()374 public void TestFallback(){ 375 LocaleData fr_FR = LocaleData.getInstance(ULocale.FRANCE); 376 LocaleData fr_CH = LocaleData.getInstance(new ULocale("fr_CH")); 377 378 // This better not crash when only some values are overridden 379 assertEquals("Start quotes are not equal", fr_FR.getDelimiter(LocaleData.QUOTATION_START), fr_CH.getDelimiter(LocaleData.QUOTATION_START)); 380 assertEquals("End quotes are not equals", fr_FR.getDelimiter(LocaleData.QUOTATION_END), fr_CH.getDelimiter(LocaleData.QUOTATION_END)); 381 assertNotEquals("Alt start quotes are equal", fr_FR.getDelimiter(LocaleData.ALT_QUOTATION_START), fr_CH.getDelimiter(LocaleData.ALT_QUOTATION_START)); 382 assertNotEquals("Alt end quotes are equals", fr_FR.getDelimiter(LocaleData.ALT_QUOTATION_END), fr_CH.getDelimiter(LocaleData.ALT_QUOTATION_END)); 383 } 384 TestLocaleDisplayPattern()385 public void TestLocaleDisplayPattern(){ 386 ULocale locale = ULocale.ENGLISH; 387 LocaleData ld = LocaleData.getInstance(locale); 388 String pattern = ld.getLocaleDisplayPattern(); 389 String separator = ld.getLocaleSeparator(); 390 logln("LocaleDisplayPattern for locale " + locale + ": " + pattern); 391 if (!pattern.equals("{0} ({1})")) { 392 errln("Unexpected LocaleDisplayPattern for locale: "+ locale); 393 } 394 logln("LocaleSeparator for locale " + locale + ": " + separator); 395 if (!separator.equals(", ")) { 396 errln("Unexpected LocaleSeparator for locale: "+ locale); 397 } 398 399 locale = ULocale.CHINESE; 400 ld = LocaleData.getInstance(locale); 401 pattern = ld.getLocaleDisplayPattern(); 402 separator = ld.getLocaleSeparator(); 403 logln("LocaleDisplayPattern for locale " + locale + ": " + pattern); 404 if (!pattern.equals("{0}\uFF08{1}\uFF09")) { 405 errln("Unexpected LocaleDisplayPattern for locale: "+ locale); 406 } 407 logln("LocaleSeparator for locale " + locale + ": " + separator); 408 if (!separator.equals("\u3001")) { 409 errln("Unexpected LocaleSeparator for locale: "+ locale); 410 } 411 412 for(int i = 0; i < availableLocales.length; i++){ 413 locale = availableLocales[i]; 414 ld = LocaleData.getInstance(locale); 415 logln(locale.toString() + " LocaleDisplayPattern:" + ld.getLocaleDisplayPattern()); 416 logln(locale.toString() + " LocaleSeparator:" + ld.getLocaleSeparator()); 417 } 418 } 419 } 420