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