1 /*
2  *******************************************************************************
3  * Copyright (C) 2001-2011, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 
8 /**
9  * Port From:   ICU4C v1.8.1 : format : IntlTestNumberFormat
10  * Source File: $ICU4CRoot/source/test/intltest/tsnmfmt.cpp
11  **/
12 
13 package com.ibm.icu.dev.test.format;
14 import java.util.Locale;
15 import java.util.Random;
16 
17 import com.ibm.icu.text.DecimalFormat;
18 import com.ibm.icu.text.NumberFormat;
19 
20 /**
21  * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
22  * NumberFormat.
23  */
24 public class IntlTestNumberFormat extends com.ibm.icu.dev.test.TestFmwk {
25 
26     public NumberFormat fNumberFormat;
27 
main(String[] args)28     public static void main(String[] args) throws Exception {
29         new IntlTestNumberFormat().run(args);
30     }
31 
32     /**
33      * Internal use
34      */
_testLocale(Locale locale)35     public void _testLocale(Locale locale) {
36         String localeName = locale + " (" + locale.getDisplayName() + ")";
37 
38         logln("Number test " + localeName);
39         fNumberFormat = NumberFormat.getInstance(locale);
40         _testFormat();
41 
42         logln("Currency test " + localeName);
43         fNumberFormat = NumberFormat.getCurrencyInstance(locale);
44         _testFormat();
45 
46         logln("Percent test " + localeName);
47         fNumberFormat = NumberFormat.getPercentInstance(locale);
48         _testFormat();
49 
50         if (locale.toString().compareTo("en_US_POSIX") != 0 ) {
51            logln("Scientific test " + localeName);
52            fNumberFormat = NumberFormat.getScientificInstance(locale);
53            _testFormat();
54         }
55     }
56 
57     /**
58      * call _testFormat for currency, percent and plain number instances
59      */
TestLocale()60     public void TestLocale() {
61         Locale locale = Locale.getDefault();
62         String localeName = locale + " (" + locale.getDisplayName() + ")";
63 
64         logln("Number test " + localeName);
65         fNumberFormat = NumberFormat.getInstance(locale);
66         _testFormat();
67 
68         logln("Currency test " + localeName);
69         fNumberFormat = NumberFormat.getCurrencyInstance(locale);
70         _testFormat();
71 
72         logln("Percent test " + localeName);
73         fNumberFormat = NumberFormat.getPercentInstance(locale);
74         _testFormat();
75     }
76 
77     /**
78      * call tryIt with many variations, called by testLocale
79      */
_testFormat()80     public void _testFormat() {
81 
82         if (fNumberFormat == null){
83             errln("**** FAIL: Null format returned by createXxxInstance.");
84              return;
85         }
86         DecimalFormat s = (DecimalFormat)fNumberFormat;
87         logln("pattern :" + s.toPattern());
88 
89         tryIt(-2.02147304840132e-68);
90         tryIt(3.88057859588817e-68);
91         tryIt(-2.64651110485945e+65);
92         tryIt(9.29526819488338e+64);
93 
94         tryIt(-2.02147304840132e-100);
95         tryIt(3.88057859588817e-096);
96         tryIt(-2.64651110485945e+306);
97         tryIt(9.29526819488338e+250);
98 
99         tryIt(-9.18228054496402e+64);
100         tryIt(-9.69413034454191e+64);
101 
102         tryIt(-9.18228054496402e+255);
103         tryIt(-9.69413034454191e+273);
104 
105 
106         tryIt(1.234e-200);
107         tryIt(-2.3e-168);
108 
109         tryIt(Double.NaN);
110         tryIt(Double.POSITIVE_INFINITY);
111         tryIt(Double.NEGATIVE_INFINITY);
112 
113         tryIt(251887531);
114         tryIt(5e-20 / 9);
115         tryIt(5e20 / 9);
116         tryIt(1.234e-50);
117         tryIt(9.99999999999996);
118         tryIt(9.999999999999996);
119 
120         tryIt(5.06e-27);
121 
122         tryIt(Integer.MIN_VALUE);
123         tryIt(Integer.MAX_VALUE);
124         tryIt((double)Integer.MIN_VALUE);
125         tryIt((double)Integer.MAX_VALUE);
126         tryIt((double)Integer.MIN_VALUE - 1.0);
127         tryIt((double)Integer.MAX_VALUE + 1.0);
128 
129         tryIt(5.0 / 9.0 * 1e-20);
130         tryIt(4.0 / 9.0 * 1e-20);
131         tryIt(5.0 / 9.0 * 1e+20);
132         tryIt(4.0 / 9.0 * 1e+20);
133 
134         tryIt(2147483647.);
135         tryIt(0);
136         tryIt(0.0);
137         tryIt(1);
138         tryIt(10);
139         tryIt(100);
140         tryIt(-1);
141         tryIt(-10);
142         tryIt(-100);
143         tryIt(-1913860352);
144 
145         Random random = createRandom(); // use test framework's random seed
146         for (int j = 0; j < 10; j++) {
147             double d = random.nextDouble()*2e10 - 1e10;
148             tryIt(d);
149 
150         }
151     }
152 
153     /**
154      * Perform tests using aNumber and fNumberFormat, called in many variations
155      */
tryIt(double aNumber)156     public void tryIt(double aNumber) {
157         final int DEPTH = 10;
158         double[] number = new double[DEPTH];
159         String[] string = new String[DEPTH];
160         int numberMatch = 0;
161         int stringMatch = 0;
162         boolean dump = false;
163         int i;
164 
165         for (i = 0; i < DEPTH; i++) {
166             if (i == 0) {
167                 number[i] = aNumber;
168             } else {
169                 try {
170                     number[i - 1] = fNumberFormat.parse(string[i - 1]).doubleValue();
171                 } catch(java.text.ParseException pe) {
172                     errln("**** FAIL: Parse of " + string[i-1] + " failed.");
173                     dump = true;
174                     break;
175                 }
176             }
177 
178             string[i] = fNumberFormat.format(number[i]);
179             if (i > 0)
180             {
181                 if (numberMatch == 0 && number[i] == number[i-1])
182                     numberMatch = i;
183                 else if (numberMatch > 0 && number[i] != number[i-1])
184                 {
185                     errln("**** FAIL: Numeric mismatch after match.");
186                     dump = true;
187                     break;
188                 }
189                 if (stringMatch == 0 && string[i] == string[i-1])
190                     stringMatch = i;
191                 else if (stringMatch > 0 && string[i] != string[i-1])
192                 {
193                     errln("**** FAIL: String mismatch after match.");
194                     dump = true;
195                     break;
196                 }
197             }
198             if (numberMatch > 0 && stringMatch > 0)
199                 break;
200 
201             if (i == DEPTH)
202             --i;
203 
204         if (stringMatch > 2 || numberMatch > 2)
205         {
206             errln("**** FAIL: No string and/or number match within 2 iterations.");
207             dump = true;
208         }
209 
210         if (dump)
211         {
212             for (int k=0; k<=i; ++k)
213             {
214                 logln(k + ": " + number[k] + " F> " +
215                       string[k] + " P> ");
216             }
217         }
218         }
219     }
220 
221     /**
222      *  perform tests using aNumber and fNumberFormat, called in many variations
223      **/
tryIt(int aNumber)224     public void tryIt(int aNumber) {
225         long number;
226 
227         String stringNum = fNumberFormat.format(aNumber);
228         try {
229             number = fNumberFormat.parse(stringNum).longValue();
230         } catch (java.text.ParseException pe) {
231             errln("**** FAIL: Parse of " + stringNum + " failed.");
232             return;
233         }
234 
235         if (number != aNumber) {
236             errln("**** FAIL: Parse of " + stringNum + " failed. Got:" + number
237                 + " Expected:" + aNumber);
238         }
239 
240     }
241 
242     /**
243      *  test NumberFormat::getAvailableLocales
244      **/
TestAvailableLocales()245     public void TestAvailableLocales() {
246         final Locale[] locales = NumberFormat.getAvailableLocales();
247         int count = locales.length;
248         logln(count + " available locales");
249         if (count != 0)
250         {
251             String all = "";
252             for (int i = 0; i< count; ++i)
253             {
254                 if (i!=0)
255                     all += ", ";
256                 all += locales[i].getDisplayName();
257             }
258             logln(all);
259         }
260         else
261             errln("**** FAIL: Zero available locales or null array pointer");
262     }
263 
264     /**
265      *  call testLocale for all locales
266      **/
TestMonster()267     public void TestMonster() {
268         final String SEP = "============================================================\n";
269         int count;
270         final Locale[] allLocales = NumberFormat.getAvailableLocales();
271         Locale[] locales = allLocales;
272         count = locales.length;
273         if (count != 0)
274         {
275             if (getInclusion() < 10 && count > 6) {
276                 count = 6;
277                 locales = new Locale[6];
278                 locales[0] = allLocales[0];
279                 locales[1] = allLocales[1];
280                 locales[2] = allLocales[2];
281                 // In a quick test, make sure we test locales that use
282                 // currency prefix, currency suffix, and choice currency
283                 // logic.  Otherwise bugs in these areas can slip through.
284                 locales[3] = new Locale("ar", "AE", "");
285                 locales[4] = new Locale("cs", "CZ", "");
286                 locales[5] = new Locale("en", "IN", "");
287             }
288             for (int i=0; i<count; ++i)
289             {
290                 logln(SEP);
291                 _testLocale(locales[i]);
292             }
293         }
294 
295         logln(SEP);
296     }
297 }
298