1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html#License
3/*
4 *******************************************************************************
5 * Copyright (C) 2007-2014, International Business Machines Corporation and    *
6 * others. All Rights Reserved.                                                *
7 *******************************************************************************
8 */
9package com.ibm.icu.dev.test.format;
10
11import java.util.HashMap;
12import java.util.Locale;
13import java.util.Map;
14
15import org.junit.Test;
16import org.junit.runner.RunWith;
17import org.junit.runners.JUnit4;
18
19import com.ibm.icu.dev.test.TestFmwk;
20import com.ibm.icu.impl.Utility;
21import com.ibm.icu.text.CurrencyPluralInfo;
22import com.ibm.icu.text.NumberFormat;
23import com.ibm.icu.text.PluralFormat;
24import com.ibm.icu.util.ULocale;
25
26/**
27 * @author tschumann (Tim Schumann)
28 *
29 */
30@RunWith(JUnit4.class)
31public class PluralFormatTest extends TestFmwk {
32  private void helperTestRules(String localeIDs, String testPattern, Map<Integer,String> changes) {
33    String[] locales = Utility.split(localeIDs, ',');
34
35    // Create example outputs for all supported locales.
36    /*
37    System.out.println("\n" + localeIDs);
38    String lastValue = (String) changes.get(new Integer(0));
39    int  lastNumber = 0;
40
41    for (int i = 1; i < 199; ++i) {
42        if (changes.get(new Integer(i)) != null) {
43            if (lastNumber == i-1) {
44                System.out.println(lastNumber + ": " + lastValue);
45            } else {
46                System.out.println(lastNumber + "... " + (i-1) + ": " + lastValue);
47            }
48            lastNumber = i;
49            lastValue = (String) changes.get(new Integer(i));
50        }
51    }
52    System.out.println(lastNumber + "..." + 199 + ": " + lastValue);
53    */
54    log("test pattern: '" + testPattern + "'");
55    for (int i = 0; i < locales.length; ++i) {
56      try {
57        PluralFormat plf = new PluralFormat(new ULocale(locales[i]), testPattern);
58        log("plf: " + plf);
59        String expected = changes.get(new Integer(0));
60        for (int n = 0; n < 200; ++n) {
61          String value = changes.get(n);
62          if (value != null) {
63            expected = value;
64          }
65          assertEquals("Locale: " + locales[i] + ", number: " + n,
66                       expected, plf.format(n));
67        }
68      } catch (IllegalArgumentException e) {
69        errln(e.getMessage() + " locale: " + locales[i] + " pattern: '" + testPattern + "' " + System.currentTimeMillis());
70      }
71    }
72  }
73
74  @Test
75  public void TestOneFormLocales() {
76    String localeIDs = "ja,ko,tr,vi";
77    String testPattern = "other{other}";
78    Map changes = new HashMap();
79    changes.put(new Integer(0), "other");
80    helperTestRules(localeIDs, testPattern, changes);
81  }
82
83  @Test
84  public void TestSingular1Locales() {
85    String localeIDs = "bem,da,de,el,en,eo,es,et,fi,fo,he,it,nb,nl,nn,no,pt_PT,sv,af,bg,ca,eu,fur,fy,ha,ku,lb,ml," +
86        "nah,ne,om,or,pap,ps,so,sq,sw,ta,te,tk,ur,mn,gsw,rm";
87    String testPattern = "one{one} other{other}";
88    Map changes = new HashMap();
89    changes.put(new Integer(0), "other");
90    changes.put(new Integer(1), "one");
91    changes.put(new Integer(2), "other");
92    helperTestRules(localeIDs, testPattern, changes);
93  }
94
95  @Test
96  public void TestSingular01Locales() {
97    String localeIDs = "ff,fr,kab,gu,mr,pa,pt,zu,bn";
98    String testPattern = "one{one} other{other}";
99    Map changes = new HashMap();
100    changes.put(new Integer(0), "one");
101    changes.put(new Integer(2), "other");
102    helperTestRules(localeIDs, testPattern, changes);
103  }
104
105  @Test
106  public void TestZeroSingularLocales() {
107    String localeIDs = "lv";
108    String testPattern = "zero{zero} one{one} other{other}";
109    Map changes = new HashMap();
110    changes.put(new Integer(0), "zero");
111    changes.put(new Integer(1), "one");
112    for (int i = 2; i < 20; ++i) {
113      if (i < 10) {
114        changes.put(new Integer(i), "other");
115      } else {
116        changes.put(new Integer(i), "zero");
117      }
118      changes.put(new Integer(i*10), "zero");
119      if (i == 11) {
120        changes.put(new Integer(i*10 + 1), "zero");
121        changes.put(new Integer(i*10 + 2), "zero");
122      } else {
123        changes.put(new Integer(i*10 + 1), "one");
124        changes.put(new Integer(i*10 + 2), "other");
125      }
126    }
127    helperTestRules(localeIDs, testPattern, changes);
128  }
129
130  @Test
131  public void TestSingularDual() {
132      String localeIDs = "ga";
133      String testPattern = "one{one} two{two} other{other}";
134      Map changes = new HashMap();
135      changes.put(new Integer(0), "other");
136      changes.put(new Integer(1), "one");
137      changes.put(new Integer(2), "two");
138      changes.put(new Integer(3), "other");
139      helperTestRules(localeIDs, testPattern, changes);
140  }
141
142  @Test
143  public void TestSingularZeroSome() {
144      String localeIDs = "ro";
145      String testPattern = "few{few} one{one} other{other}";
146      Map changes = new HashMap();
147      changes.put(new Integer(0), "few");
148      changes.put(new Integer(1), "one");
149      changes.put(new Integer(2), "few");
150      changes.put(new Integer(20), "other");
151      changes.put(new Integer(101), "few");
152      changes.put(new Integer(120), "other");
153      helperTestRules(localeIDs, testPattern, changes);
154  }
155
156  @Test
157  public void TestSpecial12_19() {
158      String localeIDs = "lt";
159      String testPattern = "one{one} few{few} other{other}";
160      Map changes = new HashMap();
161      changes.put(new Integer(0), "other");
162      changes.put(new Integer(1), "one");
163      changes.put(new Integer(2), "few");
164      changes.put(new Integer(10), "other");
165      for (int i = 2; i < 20; ++i) {
166        if (i == 11) {
167          continue;
168        }
169        changes.put(new Integer(i*10 + 1), "one");
170        changes.put(new Integer(i*10 + 2), "few");
171        changes.put(new Integer((i+1)*10), "other");
172      }
173      helperTestRules(localeIDs, testPattern, changes);
174  }
175
176  @Test
177  public void TestPaucalExcept11_14() {
178      String localeIDs = "hr,sr,uk";
179      String testPattern = "one{one} few{few} other{other}";
180      Map changes = new HashMap();
181      changes.put(new Integer(0), "other");
182      changes.put(new Integer(1), "one");
183      changes.put(new Integer(2), "few");
184      changes.put(new Integer(5), "other");
185      for (int i = 2; i < 20; ++i) {
186        if (i == 11) {
187          continue;
188        }
189        changes.put(new Integer(i*10 + 1), "one");
190        changes.put(new Integer(i*10 + 2), "few");
191        changes.put(new Integer(i*10 + 5), "other");
192      }
193      helperTestRules(localeIDs, testPattern, changes);
194  }
195
196  @Test
197  public void TestPaucalRu() {
198      String localeIDs = "ru";
199      String testPattern = "one{one} many{many} other{other}";
200      Map changes = new HashMap();
201      for (int i = 0; i < 200; i+=10) {
202          if (i == 10 || i == 110) {
203              put(i, 0, 9, "many", changes);
204              continue;
205          }
206          put(i, 0, "many", changes);
207          put(i, 1, "one", changes);
208          put(i, 2, 4, "other", changes);
209          put(i, 5, 9, "many", changes);
210      }
211      helperTestRules(localeIDs, testPattern, changes);
212  }
213
214  public <T> void put(int base, int start, int end, T value, Map<Integer, T> m) {
215      for (int i = start; i <= end; ++i) {
216          if (m.containsKey(base + i)) {
217              throw new IllegalArgumentException();
218          }
219          m.put(base + i, value);
220      }
221  }
222
223  public <T> void put(int base, int start, T value, Map<Integer, T> m) {
224      put(base, start, start, value, m);
225  }
226
227  @Test
228  public void TestSingularPaucal() {
229      String localeIDs = "cs,sk";
230      String testPattern = "one{one} few{few} other{other}";
231      Map changes = new HashMap();
232      changes.put(new Integer(0), "other");
233      changes.put(new Integer(1), "one");
234      changes.put(new Integer(2), "few");
235      changes.put(new Integer(5), "other");
236      helperTestRules(localeIDs, testPattern, changes);
237  }
238
239  @Test
240  public void TestPaucal1_234() {
241      String localeIDs = "pl";
242      String testPattern = "one{one} few{few} other{other}";
243      Map changes = new HashMap();
244      changes.put(new Integer(0), "other");
245      changes.put(new Integer(1), "one");
246      changes.put(new Integer(2), "few");
247      changes.put(new Integer(5), "other");
248      for (int i = 2; i < 20; ++i) {
249        if (i == 11) {
250          continue;
251        }
252        changes.put(new Integer(i*10 + 2), "few");
253        changes.put(new Integer(i*10 + 5), "other");
254      }
255      helperTestRules(localeIDs, testPattern, changes);
256  }
257
258  @Test
259  public void TestPaucal1_2_34() {
260      String localeIDs = "sl";
261      String testPattern = "one{one} two{two} few{few} other{other}";
262      Map changes = new HashMap();
263      changes.put(new Integer(0), "other");
264      changes.put(new Integer(1), "one");
265      changes.put(new Integer(2), "two");
266      changes.put(new Integer(3), "few");
267      changes.put(new Integer(5), "other");
268      changes.put(new Integer(101), "one");
269      changes.put(new Integer(102), "two");
270      changes.put(new Integer(103), "few");
271      changes.put(new Integer(105), "other");
272      helperTestRules(localeIDs, testPattern, changes);
273  }
274
275    /* Tests the method public PluralRules getPluralRules() */
276    @Test
277    public void TestGetPluralRules() {
278        CurrencyPluralInfo cpi = new CurrencyPluralInfo();
279        try {
280            cpi.getPluralRules();
281        } catch (Exception e) {
282            errln("CurrencyPluralInfo.getPluralRules() was not suppose to " + "return an exception.");
283        }
284    }
285
286    /* Tests the method public ULocale getLocale() */
287    @Test
288    public void TestGetLocale() {
289        CurrencyPluralInfo cpi = new CurrencyPluralInfo(new ULocale("en_US"));
290        if (!cpi.getLocale().equals(new ULocale("en_US"))) {
291            errln("CurrencyPluralInfo.getLocale() was suppose to return true " + "when passing the same ULocale");
292        }
293        if (cpi.getLocale().equals(new ULocale("jp_JP"))) {
294            errln("CurrencyPluralInfo.getLocale() was not suppose to return true " + "when passing a different ULocale");
295        }
296    }
297
298    /* Tests the method public void setLocale(ULocale loc) */
299    @Test
300    public void TestSetLocale() {
301        CurrencyPluralInfo cpi = new CurrencyPluralInfo();
302        cpi.setLocale(new ULocale("en_US"));
303        if (!cpi.getLocale().equals(new ULocale("en_US"))) {
304            errln("CurrencyPluralInfo.setLocale() was suppose to return true when passing the same ULocale");
305        }
306        if (cpi.getLocale().equals(new ULocale("jp_JP"))) {
307            errln("CurrencyPluralInfo.setLocale() was not suppose to return true when passing a different ULocale");
308        }
309    }
310
311    /* Tests the method public boolean equals(Object a) */
312    @Test
313    public void TestEquals(){
314        CurrencyPluralInfo cpi = new CurrencyPluralInfo();
315        if(cpi.equals(0)){
316            errln("CurrencyPluralInfo.equals(Object) was not suppose to return true when comparing to an invalid object for integer 0.");
317        }
318        if(cpi.equals(0.0)){
319            errln("CurrencyPluralInfo.equals(Object) was not suppose to return true when comparing to an invalid object for float 0.");
320        }
321        if(cpi.equals("0")){
322            errln("CurrencyPluralInfo.equals(Object) was not suppose to return true when comparing to an invalid object for string 0.");
323        }
324    }
325
326    /* Test for http://bugs.icu-project.org/trac/ticket/13151 */
327    @Test
328    public void TestFractionRounding() {
329        NumberFormat nf = NumberFormat.getInstance(Locale.ENGLISH);
330        nf.setMaximumFractionDigits(0);
331        PluralFormat pf = new PluralFormat(ULocale.ENGLISH, "one{#kg}other{#kgs}");
332        pf.setNumberFormat(nf);
333        assertEquals("1.2kg", "1kg", pf.format(1.2));
334    }
335}
336