1 /*
2  *******************************************************************************
3  * Copyright (C) 2001-2012, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 
8 /**
9  * Port From:   ICU4C v1.8.1 : format : NumberFormatRegressionTest
10  * Source File: $ICU4CRoot/source/test/intltest/numrgts.cpp
11  **/
12 
13 package com.ibm.icu.dev.test.format;
14 
15 import java.io.ByteArrayInputStream;
16 import java.io.IOException;
17 import java.io.ObjectInputStream;
18 import java.text.ParseException;
19 import java.text.ParsePosition;
20 import java.util.Date;
21 import java.util.Locale;
22 
23 import com.ibm.icu.text.DateFormat;
24 import com.ibm.icu.text.DecimalFormat;
25 import com.ibm.icu.text.DecimalFormatSymbols;
26 import com.ibm.icu.text.NumberFormat;
27 import com.ibm.icu.util.Calendar;
28 import com.ibm.icu.util.ULocale;
29 
30 /**
31  * Performs regression test for MessageFormat
32  **/
33 public class NumberFormatRegressionTest extends com.ibm.icu.dev.test.TestFmwk {
34 
main(String[] args)35     public static void main(String[] args) throws Exception{
36         new NumberFormatRegressionTest().run(args);
37     }
38 
39     /**
40      * alphaWorks upgrade
41      */
Test4161100()42     public void Test4161100() {
43         NumberFormat nf = NumberFormat.getInstance(Locale.US);
44         nf.setMinimumFractionDigits(1);
45         nf.setMaximumFractionDigits(1);
46         double a = -0.09;
47         String s = nf.format(a);
48         logln(a + " x " +
49               ((DecimalFormat) nf).toPattern() + " = " + s);
50         if (!s.equals("-0.1")) {
51             errln("FAIL");
52         }
53     }
54 
55     /**
56      * DateFormat should call setIntegerParseOnly(TRUE) on adopted
57      * NumberFormat objects.
58      */
TestJ691()59     public void TestJ691() {
60 
61         Locale loc = new Locale("fr", "CH");
62 
63         // set up the input date string & expected output
64         String udt = "11.10.2000";
65         String exp = "11.10.00";
66 
67         // create a Calendar for this locale
68         Calendar cal = Calendar.getInstance(loc);
69 
70         // create a NumberFormat for this locale
71         NumberFormat nf = NumberFormat.getInstance(loc);
72 
73         // *** Here's the key: We don't want to have to do THIS:
74         //nf.setParseIntegerOnly(true);
75 
76         // create the DateFormat
77         DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, loc);
78 
79         df.setCalendar(cal);
80         df.setNumberFormat(nf);
81 
82         // set parsing to lenient & parse
83         Date ulocdat = new Date();
84         df.setLenient(true);
85         try {
86             ulocdat = df.parse(udt);
87         } catch (java.text.ParseException pe) {
88             errln(pe.getMessage());
89         }
90         // format back to a string
91         String outString = df.format(ulocdat);
92 
93         if (!outString.equals(exp)) {
94             errln("FAIL: " + udt + " => " + outString);
95         }
96     }
97 
98     /**
99      * Test getIntegerInstance();
100      */
Test4408066()101     public void Test4408066() {
102 
103         NumberFormat nf1 = NumberFormat.getIntegerInstance();
104         NumberFormat nf2 = NumberFormat.getIntegerInstance(Locale.CHINA);
105 
106         //test isParseIntegerOnly
107         if (!nf1.isParseIntegerOnly() || !nf2.isParseIntegerOnly()) {
108             errln("Failed : Integer Number Format Instance should set setParseIntegerOnly(true)");
109         }
110 
111         //Test format
112         {
113             double[] data = {
114                 -3.75, -2.5, -1.5,
115                 -1.25, 0,    1.0,
116                 1.25,  1.5,  2.5,
117                 3.75,  10.0, 255.5
118                 };
119             String[] expected = {
120                 "-4", "-2", "-2",
121                 "-1", "0",  "1",
122                 "1",  "2",  "2",
123                 "4",  "10", "256"
124                 };
125 
126             for (int i = 0; i < data.length; ++i) {
127                 String result = nf1.format(data[i]);
128                 if (!result.equals(expected[i])) {
129                     errln("Failed => Source: " + Double.toString(data[i])
130                         + ";Formatted : " + result
131                         + ";but expectted: " + expected[i]);
132                 }
133             }
134         }
135         //Test parse, Parsing should stop at "."
136         {
137             String data[] = {
138                 "-3.75", "-2.5", "-1.5",
139                 "-1.25", "0",    "1.0",
140                 "1.25",  "1.5",  "2.5",
141                 "3.75",  "10.0", "255.5"
142                 };
143             long[] expected = {
144                 -3, -2, -1,
145                 -1, 0,  1,
146                 1,  1,  2,
147                 3,  10, 255
148                 };
149 
150             for (int i = 0; i < data.length; ++i) {
151                 Number n = null;
152                 try {
153                     n = nf1.parse(data[i]);
154                 } catch (ParseException e) {
155                     errln("Failed: " + e.getMessage());
156                 }
157                 if (!(n instanceof Long) || (n instanceof Integer)) {
158                     errln("Failed: Integer Number Format should parse string to Long/Integer");
159                 }
160                 if (n.longValue() != expected[i]) {
161                     errln("Failed=> Source: " + data[i]
162                         + ";result : " + n.toString()
163                         + ";expected :" + Long.toString(expected[i]));
164                 }
165             }
166         }
167     }
168 
169     //Test New serialized DecimalFormat(2.0) read old serialized forms of DecimalFormat(1.3.1.1)
TestSerialization()170     public void TestSerialization() throws IOException{
171         byte[][] contents = NumberFormatSerialTestData.getContent();
172         double data = 1234.56;
173         String[] expected = {
174             "1,234.56", "$1,234.56", "123,456%", "1.23456E3"};
175         for (int i = 0; i < 4; ++i) {
176             ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(contents[i]));
177             try {
178                 NumberFormat format = (NumberFormat) ois.readObject();
179                 String result = format.format(data);
180                 if (result.equals(expected[i])) {
181                     logln("OK: Deserialized bogus NumberFormat(new version read old version)");
182                 } else {
183                     errln("FAIL: the test data formats are not euqal");
184                 }
185             } catch (Exception e) {
186                 warnln("FAIL: " + e.getMessage());
187             }
188         }
189     }
190 
191     /*
192      * Test case for JB#5509, strict parsing issue
193      */
TestJB5509()194     public void TestJB5509() {
195         String[] data = {
196                 "1,2",
197                 "1.2",
198                 "1,2.5",
199                 "1,23.5",
200                 "1,234.5",
201                 "1,234",
202                 "1,234,567",
203                 "1,234,567.8",
204                 "1,234,5",
205                 "1,234,5.6",
206                 "1,234,56.7"
207         };
208         boolean[] expected = { // false for expected parse failure
209                 false,
210                 true,
211                 false,
212                 false,
213                 true,
214                 true,
215                 true,
216                 true,
217                 false,
218                 false,
219                 false,
220                 false
221         };
222 
223         DecimalFormat df = new DecimalFormat("#,##0.###", new DecimalFormatSymbols(new ULocale("en_US")));
224         df.setParseStrict(true);
225         for (int i = 0; i < data.length; i++) {
226             try {
227                 df.parse(data[i]);
228                 if (!expected[i]) {
229                     errln("Failed: ParseException must be thrown for string " + data[i]);
230                 }
231             } catch (ParseException pe) {
232                 if (expected[i]) {
233                     errln("Failed: ParseException must not be thrown for string " + data[i]);
234                 }
235             }
236         }
237     }
238 
239     /*
240      * Test case for ticket#5698 - parsing extremely large/small values
241      */
TestT5698()242     public void TestT5698() {
243         final String[] data = {
244                 "12345679E66666666666666666",
245                 "-12345679E66666666666666666",
246                 ".1E2147483648", // exponent > max int
247                 ".1E2147483647", // exponent == max int
248                 ".1E-2147483648", // exponent == min int
249                 ".1E-2147483649", // exponent < min int
250                 "1.23E350", // value > max double
251                 "1.23E300", // value < max double
252                 "-1.23E350", // value < min double
253                 "-1.23E300", // value > min double
254                 "4.9E-324", // value = smallest non-zero double
255                 "1.0E-325", // 0 < value < smallest non-zero positive double0
256                 "-1.0E-325", // 0 > value > largest non-zero negative double
257         };
258         final double[] expected = {
259                 Double.POSITIVE_INFINITY,
260                 Double.NEGATIVE_INFINITY,
261                 Double.POSITIVE_INFINITY,
262                 Double.POSITIVE_INFINITY,
263                 0.0,
264                 0.0,
265                 Double.POSITIVE_INFINITY,
266                 1.23e300d,
267                 Double.NEGATIVE_INFINITY,
268                 -1.23e300d,
269                 4.9e-324d,
270                 0.0,
271                 -0.0,
272         };
273 
274         NumberFormat nfmt = NumberFormat.getInstance();
275 
276         for (int i = 0; i < data.length; i++) {
277             try {
278                 Number n = nfmt.parse(data[i]);
279                 if (expected[i] != n.doubleValue()) {
280                     errln("Failed: Parsed result for " + data[i] + ": "
281                             + n.doubleValue() + " / expected: " + expected[i]);
282                 }
283             } catch (ParseException pe) {
284                 errln("Failed: ParseException is thrown for " + data[i]);
285             }
286         }
287     }
TestSurrogatesParsing()288     public void TestSurrogatesParsing() { // Test parsing of numbers that use digits from the supplemental planes.
289         final String[] data = {
290                 "1\ud801\udca2,3\ud801\udca45.67", //
291                 "\ud801\udca1\ud801\udca2,\ud801\udca3\ud801\udca4\ud801\udca5.\ud801\udca6\ud801\udca7\ud801\udca8", //
292                 "\ud835\udfd2.\ud835\udfd7E-\ud835\udfd1",
293                 "\ud835\udfd3.8E-0\ud835\udfd0"
294                 };
295         final double[] expected = {
296                 12345.67,
297                 12345.678,
298                 0.0049,
299                 0.058
300         };
301 
302         NumberFormat nfmt = NumberFormat.getInstance();
303 
304         for (int i = 0; i < data.length; i++) {
305             try {
306                 Number n = nfmt.parse(data[i]);
307                 if (expected[i] != n.doubleValue()) {
308                     errln("Failed: Parsed result for " + data[i] + ": "
309                             + n.doubleValue() + " / expected: " + expected[i]);
310                 }
311             } catch (ParseException pe) {
312                 errln("Failed: ParseException is thrown for " + data[i]);
313             }
314         }
315     }
316 
checkNBSPPatternRtNum(String testcase, NumberFormat nf, double myNumber)317     void checkNBSPPatternRtNum(String testcase, NumberFormat nf, double myNumber) {
318         String myString = nf.format(myNumber);
319 
320             double aNumber;
321             try {
322                 aNumber = nf.parse(myString).doubleValue();
323             } catch (ParseException e) {
324                 // TODO Auto-generated catch block
325                 errln("FAIL: " + testcase +" - failed to parse. " + e.toString());
326                 return;
327             }
328             if(Math.abs(aNumber-myNumber)>.001) {
329             errln("FAIL: "+testcase+": formatted "+myNumber+", parsed into "+aNumber+"\n");
330         } else {
331             logln("PASS: "+testcase+": formatted "+myNumber+", parsed into "+aNumber+"\n");
332         }
333     }
334 
checkNBSPPatternRT(String testcase, NumberFormat nf)335     void checkNBSPPatternRT(String testcase, NumberFormat nf) {
336         checkNBSPPatternRtNum(testcase, nf, 12345.);
337         checkNBSPPatternRtNum(testcase, nf, -12345.);
338     }
339 
TestNBSPInPattern()340     public void TestNBSPInPattern() {
341     NumberFormat nf = null;
342     String testcase;
343 
344 
345     testcase="ar_AE UNUM_CURRENCY";
346     nf = NumberFormat.getCurrencyInstance(new ULocale("ar_AE"));
347     checkNBSPPatternRT(testcase, nf);
348     // if we don't have CLDR 1.6 data, bring out the problem anyways
349 
350     String SPECIAL_PATTERN = "\u00A4\u00A4'\u062f.\u0625.\u200f\u00a0'###0.00";
351     testcase = "ar_AE special pattern: " + SPECIAL_PATTERN;
352     nf = new DecimalFormat();
353     ((DecimalFormat)nf).applyPattern(SPECIAL_PATTERN);
354     checkNBSPPatternRT(testcase, nf);
355 
356     }
357 
358     /*
359      * Test case for #9293
360      * Parsing currency in strict mode
361      */
TestT9293()362     public void TestT9293() {
363         NumberFormat fmt = NumberFormat.getCurrencyInstance();
364         fmt.setParseStrict(true);
365 
366         final int val = 123456;
367         String txt = fmt.format(123456);
368 
369         ParsePosition pos = new ParsePosition(0);
370         Number num = fmt.parse(txt, pos);
371 
372         if (pos.getErrorIndex() >= 0) {
373             errln("FAIL: Parsing " + txt + " - error index: " + pos.getErrorIndex());
374         } else if (val != num.intValue()) {
375             errln("FAIL: Parsed result: " + num + " - expected: " + val);
376         }
377     }
378 }
379