]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / tests / core / src / com / ibm / icu / dev / test / format / NumberFormatTest.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2001-2010, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 /**\r
9  * Port From:   ICU4C v1.8.1 : format : NumberFormatTest\r
10  * Source File: $ICU4CRoot/source/test/intltest/numfmtst.cpp\r
11  **/\r
12 \r
13 package com.ibm.icu.dev.test.format;\r
14 \r
15 import java.math.BigInteger;\r
16 import java.text.FieldPosition;\r
17 import java.text.ParseException;\r
18 import java.text.ParsePosition;\r
19 import java.util.ArrayList;\r
20 import java.util.Locale;\r
21 import java.util.Set;\r
22 \r
23 import com.ibm.icu.dev.test.TestUtil;\r
24 import com.ibm.icu.impl.LocaleUtility;\r
25 import com.ibm.icu.impl.Utility;\r
26 import com.ibm.icu.impl.data.ResourceReader;\r
27 import com.ibm.icu.impl.data.TokenIterator;\r
28 import com.ibm.icu.math.BigDecimal;\r
29 import com.ibm.icu.text.DecimalFormat;\r
30 import com.ibm.icu.text.DecimalFormatSymbols;\r
31 import com.ibm.icu.text.MeasureFormat;\r
32 import com.ibm.icu.text.NumberFormat;\r
33 import com.ibm.icu.text.NumberFormat.NumberFormatFactory;\r
34 import com.ibm.icu.text.NumberFormat.SimpleNumberFormatFactory;\r
35 import com.ibm.icu.util.Currency;\r
36 import com.ibm.icu.util.CurrencyAmount;\r
37 import com.ibm.icu.util.ULocale;\r
38 \r
39 public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {\r
40 \r
41     public static void main(String[] args) throws Exception {\r
42         new NumberFormatTest().run(args);\r
43     }\r
44 \r
45     // Test various patterns\r
46     public void TestPatterns() {\r
47 \r
48         DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);\r
49         final String pat[]    = { "#.#", "#.", ".#", "#" };\r
50         int pat_length = pat.length;\r
51         final String newpat[] = { "#0.#", "#0.", "#.0", "#" };\r
52         final String num[]    = { "0",   "0.", ".0", "0" };\r
53         for (int i=0; i<pat_length; ++i)\r
54         {\r
55             DecimalFormat fmt = new DecimalFormat(pat[i], sym);\r
56             String newp = fmt.toPattern();\r
57             if (!newp.equals(newpat[i]))\r
58                 errln("FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] +\r
59                       "; " + newp + " seen instead");\r
60 \r
61             String s = ((NumberFormat)fmt).format(0);\r
62             if (!s.equals(num[i]))\r
63             {\r
64                 errln("FAIL: Pattern " + pat[i] + " should format zero as " + num[i] +\r
65                       "; " + s + " seen instead");\r
66                 logln("Min integer digits = " + fmt.getMinimumIntegerDigits());\r
67             }\r
68             // BigInteger 0 - ticket#4731\r
69             s = ((NumberFormat)fmt).format(BigInteger.ZERO);\r
70             if (!s.equals(num[i]))\r
71             {\r
72                 errln("FAIL: Pattern " + pat[i] + " should format BigInteger zero as " + num[i] +\r
73                       "; " + s + " seen instead");\r
74                 logln("Min integer digits = " + fmt.getMinimumIntegerDigits());\r
75             }\r
76         }\r
77     }\r
78 \r
79     // Test exponential pattern\r
80     public void TestExponential() {\r
81 \r
82         DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);\r
83         final String pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };\r
84         int pat_length = pat.length;\r
85 \r
86         double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };\r
87         int val_length = val.length;\r
88         final String valFormat[] = {\r
89             // 0.####E0\r
90             "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",\r
91             // 00.000E00\r
92             "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",\r
93             // ##0.######E000\r
94             "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",\r
95             // 0.###E0;[0.###E0]\r
96             "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]" };\r
97         /*double valParse[] =\r
98             {\r
99                 0.01234, 123460000, 1.23E300, -3.1416E-271,\r
100                 0.01234, 123460000, 1.23E300, -3.1416E-271,\r
101                 0.01234, 123456800, 1.23E300, -3.141593E-271,\r
102                 0.01234, 123500000, 1.23E300, -3.142E-271,\r
103             };*/ //The variable is never used\r
104 \r
105         int lval[] = { 0, -1, 1, 123456789 };\r
106         int lval_length = lval.length;\r
107         final String lvalFormat[] = {\r
108             // 0.####E0\r
109             "0E0", "-1E0", "1E0", "1.2346E8",\r
110             // 00.000E00\r
111             "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",\r
112             // ##0.######E000\r
113             "0E000", "-1E000", "1E000", "123.4568E006",\r
114             // 0.###E0;[0.###E0]\r
115             "0E0", "[1E0]", "1E0", "1.235E8" };\r
116         int lvalParse[] =\r
117             {\r
118                 0, -1, 1, 123460000,\r
119                 0, -1, 1, 123460000,\r
120                 0, -1, 1, 123456800,\r
121                 0, -1, 1, 123500000,\r
122             };\r
123         int ival = 0, ilval = 0;\r
124         for (int p = 0; p < pat_length; ++p) {\r
125             DecimalFormat fmt = new DecimalFormat(pat[p], sym);\r
126             logln("Pattern \"" + pat[p] + "\" -toPattern-> \"" + fmt.toPattern() + "\"");\r
127             int v;\r
128             for (v = 0; v < val_length; ++v) {\r
129                 String s;\r
130                 s = ((NumberFormat) fmt).format(val[v]);\r
131                 logln(" " + val[v] + " -format-> " + s);\r
132                 if (!s.equals(valFormat[v + ival]))\r
133                     errln("FAIL: Expected " + valFormat[v + ival]);\r
134 \r
135                 ParsePosition pos = new ParsePosition(0);\r
136                 double a = fmt.parse(s, pos).doubleValue();\r
137                 if (pos.getIndex() == s.length()) {\r
138                     logln("  -parse-> " + Double.toString(a));\r
139                     // Use epsilon comparison as necessary\r
140                 } else\r
141                     errln("FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);\r
142             }\r
143             for (v = 0; v < lval_length; ++v) {\r
144                 String s;\r
145                 s = ((NumberFormat) fmt).format(lval[v]);\r
146                 logln(" " + lval[v] + "L -format-> " + s);\r
147                 if (!s.equals(lvalFormat[v + ilval]))\r
148                     errln("ERROR: Expected " + lvalFormat[v + ilval] + " Got: " + s);\r
149 \r
150                 ParsePosition pos = new ParsePosition(0);\r
151                 long a = 0;\r
152                 Number A = fmt.parse(s, pos);\r
153                 if (A != null) {\r
154                     a = A.longValue();\r
155                     if (pos.getIndex() == s.length()) {\r
156                         logln("  -parse-> " + a);\r
157                         if (a != lvalParse[v + ilval])\r
158                             errln("FAIL: Expected " + lvalParse[v + ilval]);\r
159                     } else\r
160                         errln("FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + Long.toString(a));\r
161                 } else {\r
162                     errln("Fail to parse the string: " + s);\r
163                 }\r
164             }\r
165             ival += val_length;\r
166             ilval += lval_length;\r
167         }\r
168     }\r
169 \r
170     // Test the handling of quotes\r
171     public void TestQuotes() {\r
172 \r
173         StringBuffer pat;\r
174         DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);\r
175         pat = new StringBuffer("a'fo''o'b#");\r
176         DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);\r
177         String s = ((NumberFormat)fmt).format(123);\r
178         logln("Pattern \"" + pat + "\"");\r
179         logln(" Format 123 . " + s);\r
180         if (!s.equals("afo'ob123"))\r
181             errln("FAIL: Expected afo'ob123");\r
182 \r
183         s ="";\r
184         pat = new StringBuffer("a''b#");\r
185         fmt = new DecimalFormat(pat.toString(), sym);\r
186         s = ((NumberFormat)fmt).format(123);\r
187         logln("Pattern \"" + pat + "\"");\r
188         logln(" Format 123 . " + s);\r
189         if (!s.equals("a'b123"))\r
190             errln("FAIL: Expected a'b123");\r
191     }\r
192 \r
193     public void TestParseCurrencyTrailingSymbol() {\r
194         // see sun bug 4709840\r
195         NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.GERMANY);\r
196         float val = 12345.67f;\r
197         String str = fmt.format(val);\r
198         logln("val: " + val + " str: " + str);\r
199         try {\r
200             Number num = fmt.parse(str);\r
201             logln("num: " + num);\r
202         } catch (ParseException e) {\r
203             errln("parse of '" + str + "' threw exception: " + e);\r
204         }\r
205     }\r
206 \r
207     /**\r
208      * Test the handling of the currency symbol in patterns.\r
209      **/\r
210     public void TestCurrencySign() {\r
211         DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);\r
212         StringBuffer pat = new StringBuffer("");\r
213         char currency = 0x00A4;\r
214         // "\xA4#,##0.00;-\xA4#,##0.00"\r
215         pat.append(currency).append("#,##0.00;-").append(currency).append("#,##0.00");\r
216         DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);\r
217         String s = ((NumberFormat) fmt).format(1234.56);\r
218         pat = new StringBuffer();\r
219         logln("Pattern \"" + fmt.toPattern() + "\"");\r
220         logln(" Format " + 1234.56 + " . " + s);\r
221         assertEquals("symbol, pos", "$1,234.56", s);\r
222         \r
223         s = ((NumberFormat) fmt).format(-1234.56);\r
224         logln(" Format " + Double.toString(-1234.56) + " . " + s);\r
225         assertEquals("symbol, neg", "-$1,234.56", s);\r
226 \r
227         pat.setLength(0);\r
228         // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"\r
229         pat.append(currency).append(currency).append(" #,##0.00;").append(currency).append(currency).append(" -#,##0.00");\r
230         fmt = new DecimalFormat(pat.toString(), sym);\r
231         s = ((NumberFormat) fmt).format(1234.56);\r
232         logln("Pattern \"" + fmt.toPattern() + "\"");\r
233         logln(" Format " + Double.toString(1234.56) + " . " + s);\r
234         assertEquals("name, pos", "USD 1,234.56", s);\r
235         \r
236         s = ((NumberFormat) fmt).format(-1234.56);\r
237         logln(" Format " + Double.toString(-1234.56) + " . " + s);\r
238         assertEquals("name, neg", "USD -1,234.56", s);\r
239     }\r
240 \r
241     public void TestSpaceParsing() {\r
242         // the data are:\r
243         // the string to be parsed, parsed position, parsed error index\r
244         String[][] DATA = {\r
245             {"$124", "4", "-1"},\r
246             {"$124 $124", "4", "-1"},\r
247             {"$124 ", "4", "-1"},\r
248             {"$ 124 ", "5", "-1"},\r
249             {"$\u00A0124 ", "5", "-1"},\r
250             {" $ 124 ", "0", "0"}, // TODO: need to handle space correctly\r
251             {"124$", "0", "3"}, // TODO: need to handle space correctly\r
252             // {"124 $", "5", "-1"}, TODO: OK or NOT?\r
253             {"124 $", "0", "3"}, \r
254         };\r
255         NumberFormat foo = NumberFormat.getCurrencyInstance();\r
256         for (int i = 0; i < DATA.length; ++i) {\r
257           ParsePosition parsePosition = new ParsePosition(0);\r
258           String stringToBeParsed = DATA[i][0];\r
259           int parsedPosition = Integer.parseInt(DATA[i][1]);\r
260           int errorIndex = Integer.parseInt(DATA[i][2]);\r
261           try {\r
262             Number result = foo.parse(stringToBeParsed, parsePosition);\r
263             if (parsePosition.getIndex() != parsedPosition ||\r
264                 parsePosition.getErrorIndex() != errorIndex) {\r
265                 errln("FAILED parse " + stringToBeParsed + "; parse position: " + parsePosition.getIndex() + "; error position: " + parsePosition.getErrorIndex());\r
266             }\r
267             if (parsePosition.getErrorIndex() == -1 &&\r
268                 result.doubleValue() != 124) {\r
269                 errln("FAILED parse " + stringToBeParsed + "; value " + result.doubleValue());\r
270             }\r
271           } catch (Exception e) {\r
272               errln("FAILED " + e.toString());\r
273           }\r
274         }\r
275     }\r
276 \r
277 \r
278     public void TestMultiCurrencySign() {\r
279         String[][] DATA = {\r
280             // the fields in the following test are:\r
281             // locale, \r
282             // currency pattern (with negative pattern), \r
283             // currency number to be formatted,\r
284             // currency format using currency symbol name, such as "$" for USD,\r
285             // currency format using currency ISO name, such as "USD",\r
286             // currency format using plural name, such as "US dollars".\r
287             // for US locale\r
288             {"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "1234.56", "$1,234.56", "USD1,234.56", "US dollars1,234.56"}, \r
289             {"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD1,234.56", "-US dollars1,234.56"}, \r
290             {"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "1", "$1.00", "USD1.00", "US dollar1.00"}, \r
291             // for CHINA locale\r
292             {"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "1234.56", "\uFFE51,234.56", "CNY1,234.56", "\u4EBA\u6C11\u5E011,234.56"},\r
293             {"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "-1234.56", "(\uFFE51,234.56)", "(CNY1,234.56)", "(\u4EBA\u6C11\u5E011,234.56)"},\r
294             {"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "1", "\uFFE51.00", "CNY1.00", "\u4EBA\u6C11\u5E011.00"}\r
295         };\r
296 \r
297         String doubleCurrencyStr = "\u00A4\u00A4";\r
298         String tripleCurrencyStr = "\u00A4\u00A4\u00A4";\r
299 \r
300         for (int i=0; i<DATA.length; ++i) {\r
301             String locale = DATA[i][0];\r
302             String pat = DATA[i][1];\r
303             Double numberToBeFormat = new Double(DATA[i][2]);\r
304             DecimalFormatSymbols sym = new DecimalFormatSymbols(new ULocale(locale));\r
305             for (int j=1; j<=3; ++j) {\r
306                 // j represents the number of currency sign in the pattern.\r
307                 if (j == 2) {\r
308                     pat = pat.replaceAll("\u00A4", doubleCurrencyStr);\r
309                 } else if (j == 3) {\r
310                     pat = pat.replaceAll("\u00A4\u00A4", tripleCurrencyStr);\r
311                 }\r
312                 DecimalFormat fmt = new DecimalFormat(pat, sym);\r
313                 String s = ((NumberFormat) fmt).format(numberToBeFormat);\r
314                 // DATA[i][3] is the currency format result using a\r
315                 // single currency sign.\r
316                 // DATA[i][4] is the currency format result using\r
317                 // double currency sign.\r
318                 // DATA[i][5] is the currency format result using\r
319                 // triple currency sign.\r
320                 // DATA[i][j+2] is the currency format result using\r
321                 // 'j' number of currency sign.\r
322                 String currencyFormatResult = DATA[i][2+j];\r
323                 if (!s.equals(currencyFormatResult)) {\r
324                     errln("FAIL format: Expected " + currencyFormatResult);\r
325                 }\r
326                 try {\r
327                     // mix style parsing\r
328                     for (int k=3; k<=5; ++k) {\r
329                       // DATA[i][3] is the currency format result using a\r
330                       // single currency sign.\r
331                       // DATA[i][4] is the currency format result using\r
332                       // double currency sign.\r
333                       // DATA[i][5] is the currency format result using\r
334                       // triple currency sign.\r
335                       String oneCurrencyFormat = DATA[i][k];\r
336                       if (fmt.parse(oneCurrencyFormat).doubleValue() != \r
337                           numberToBeFormat.doubleValue()) {\r
338                         errln("FAILED parse " + oneCurrencyFormat);\r
339                       }\r
340                     }\r
341                 } catch (ParseException e) {\r
342                     errln("FAILED, DecimalFormat parse currency: " + e.toString());\r
343                 }\r
344             }\r
345         }\r
346     }\r
347 \r
348     public void TestCurrencyFormatForMixParsing() {\r
349         MeasureFormat curFmt = MeasureFormat.getCurrencyFormat(new ULocale("en_US"));\r
350         String[] formats = {\r
351             "$1,234.56",  // string to be parsed\r
352             "USD1,234.56",\r
353             "US dollars1,234.56",\r
354             "1,234.56 US dollars"\r
355         };\r
356         try {\r
357           for (int i = 0; i < formats.length; ++i) {\r
358             String stringToBeParsed = formats[i];\r
359             CurrencyAmount parsedVal = (CurrencyAmount)curFmt.parseObject(stringToBeParsed);\r
360             Number val = parsedVal.getNumber();\r
361             if (!val.equals(new BigDecimal("1234.56"))) {\r
362                 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number. val=" + val);\r
363             }\r
364             if (!parsedVal.getCurrency().equals(Currency.getInstance("USD"))) {\r
365                 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the currency");\r
366             }\r
367           }\r
368         } catch (ParseException e) {\r
369             errln("parse FAILED: " + e.toString());\r
370         }\r
371     }\r
372 \r
373     public void TestDecimalFormatCurrencyParse() {\r
374         // Locale.US\r
375         DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);\r
376         StringBuffer pat = new StringBuffer("");\r
377         char currency = 0x00A4;\r
378         // "\xA4#,##0.00;-\xA4#,##0.00"\r
379         pat.append(currency).append(currency).append(currency).append("#,##0.00;-").append(currency).append(currency).append(currency).append("#,##0.00");\r
380         DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);\r
381         String[][] DATA = {\r
382             // the data are:\r
383             // string to be parsed, the parsed result (number)\r
384             {"$1.00", "1"},    \r
385             {"USD1.00", "1"},    \r
386             {"1.00 US dollar", "1"},    \r
387             {"$1,234.56", "1234.56"},    \r
388             {"USD1,234.56", "1234.56"},    \r
389             {"1,234.56 US dollar", "1234.56"},    \r
390         };\r
391         try {\r
392             for (int i = 0; i < DATA.length; ++i) {\r
393                 String stringToBeParsed = DATA[i][0];\r
394                 double parsedResult = Double.parseDouble(DATA[i][1]);\r
395                 Number num = fmt.parse(stringToBeParsed);\r
396                 if (num.doubleValue() != parsedResult) {\r
397                     errln("FAIL parse: Expected " + parsedResult);\r
398                 }\r
399             }\r
400         } catch (ParseException e) {\r
401             errln("FAILED, DecimalFormat parse currency: " + e.toString());\r
402         }\r
403     } \r
404 \r
405     /**\r
406      * Test localized currency patterns.\r
407      */\r
408     public void TestCurrency() {\r
409         String[] DATA = {\r
410             "fr", "CA", "", "1,50\u00a0$",\r
411             "de", "DE", "", "1,50\u00a0\u20AC",\r
412             "de", "DE", "PREEURO", "1,50\u00a0DM",\r
413             "fr", "FR", "", "1,50\u00a0\u20AC",\r
414             "fr", "FR", "PREEURO", "1,50\u00a0F",\r
415         };\r
416 \r
417         for (int i=0; i<DATA.length; i+=4) {\r
418             Locale locale = new Locale(DATA[i], DATA[i+1], DATA[i+2]);\r
419             NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);\r
420             String s = fmt.format(1.50);\r
421             if (s.equals(DATA[i+3])) {\r
422                 logln("Ok: 1.50 x " + locale + " => " + s);\r
423             } else {\r
424                 logln("FAIL: 1.50 x " + locale + " => " + s +\r
425                       ", expected " + DATA[i+3]);\r
426             }\r
427         }\r
428 \r
429         // format currency with CurrencyAmount\r
430         for (int i=0; i<DATA.length; i+=4) {\r
431             Locale locale = new Locale(DATA[i], DATA[i+1], DATA[i+2]);\r
432 \r
433             Currency curr = Currency.getInstance(locale);\r
434             logln("\nName of the currency is: " + curr.getName(locale, Currency.LONG_NAME, new boolean[] {false}));\r
435             CurrencyAmount cAmt = new CurrencyAmount(1.5, curr);\r
436             logln("CurrencyAmount object's hashCode is: " + cAmt.hashCode()); //cover hashCode\r
437 \r
438             NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);\r
439             String sCurr = fmt.format(cAmt);\r
440             if (sCurr.equals(DATA[i+3])) {\r
441                 logln("Ok: 1.50 x " + locale + " => " + sCurr);\r
442             } else {\r
443                 errln("FAIL: 1.50 x " + locale + " => " + sCurr +\r
444                       ", expected " + DATA[i+3]);\r
445             }\r
446         }\r
447 \r
448         //Cover MeasureFormat.getCurrencyFormat()\r
449         ULocale save = ULocale.getDefault();\r
450         ULocale.setDefault(ULocale.US);\r
451         MeasureFormat curFmt = MeasureFormat.getCurrencyFormat();\r
452         String strBuf = curFmt.format(new CurrencyAmount(new Float(1234.56), Currency.getInstance("USD")));\r
453 \r
454         try {\r
455             CurrencyAmount parsedVal = (CurrencyAmount)curFmt.parseObject(strBuf);\r
456             Number val = parsedVal.getNumber();\r
457             if (!val.equals(new BigDecimal("1234.56"))) {\r
458                 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number. val=" + val);\r
459             }\r
460             if (!parsedVal.getCurrency().equals(Currency.getInstance("USD"))) {\r
461                 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the currency");\r
462             }\r
463         }\r
464         catch (ParseException e) {\r
465             errln("FAIL: " + e.getMessage());\r
466         }\r
467         ULocale.setDefault(save);\r
468     }\r
469 \r
470     public void TestCurrencyIsoPluralFormat() {\r
471         String[][] DATA = {\r
472             // the data are:\r
473             // locale, \r
474             // currency amount to be formatted,\r
475             // currency ISO code to be formatted,\r
476             // format result using CURRENCYSTYLE,\r
477             // format result using ISOCURRENCYSTYLE,\r
478             // format result using PLURALCURRENCYSTYLE,\r
479             {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar"},\r
480             {"en_US", "1234.56", "USD", "$1,234.56", "USD1,234.56", "1,234.56 US dollars"},\r
481             {"en_US", "-1234.56", "USD", "($1,234.56)", "(USD1,234.56)", "-1,234.56 US dollars"},\r
482             {"zh_CN", "1", "USD", "US$1.00", "USD1.00", "1.00 \u7F8E\u5143"}, \r
483             {"zh_CN", "1234.56", "USD", "US$1,234.56", "USD1,234.56", "1,234.56 \u7F8E\u5143"},\r
484             //{"zh_CN", "1", "CHY", "CHY1.00", "CHY1.00", "1.00 CHY"},\r
485             //{"zh_CN", "1234.56", "CHY", "CHY1,234.56", "CHY1,234.56", "1,234.56 CHY"},\r
486             {"zh_CN", "1", "CNY", "\uFFE51.00", "CNY1.00", "1.00 \u4EBA\u6C11\u5E01"},\r
487             {"zh_CN", "1234.56", "CNY", "\uFFE51,234.56", "CNY1,234.56", "1,234.56 \u4EBA\u6C11\u5E01"}, \r
488             {"ru_RU", "1", "RUB", "1,00\u00A0\u0440\u0443\u0431.", "1,00\u00A0RUB", "1,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0439 \u0440\u0443\u0431\u043B\u044C"},\r
489             {"ru_RU", "2", "RUB", "2,00\u00A0\u0440\u0443\u0431.", "2,00\u00A0RUB", "2,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0440\u0443\u0431\u043B\u044F"},\r
490             {"ru_RU", "5", "RUB", "5,00\u00A0\u0440\u0443\u0431.", "5,00\u00A0RUB", "5,00 \u0420\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0440\u0443\u0431\u043B\u0435\u0439"},\r
491             // test locale without currency information\r
492             {"root", "-1.23", "USD", "-US$\u00a01.23", "-USD\u00a01.23", "-1.23 USD"},\r
493             // test choice format\r
494             {"es_AR", "1", "INR", "Rs\u00A01,00", "INR\u00A01,00", "1,00 rupia india"},\r
495             {"ar_EG", "1", "USD", "US$\u00A0\u0661\u066B\u0660\u0660", "USD\u00a0\u0661\u066b\u0660\u0660", "\u0661\u066b\u0660\u0660 \u062f\u0648\u0644\u0627\u0631 \u0623\u0645\u0631\u064a\u0643\u064a"},\r
496         };\r
497         \r
498         for (int i=0; i<DATA.length; ++i) {\r
499           for (int k = NumberFormat.CURRENCYSTYLE;\r
500                k <= NumberFormat.PLURALCURRENCYSTYLE;\r
501                ++k) {\r
502             // k represents currency format style.\r
503             if ( k != NumberFormat.CURRENCYSTYLE &&\r
504                  k != NumberFormat.ISOCURRENCYSTYLE &&\r
505                  k != NumberFormat.PLURALCURRENCYSTYLE ) {\r
506                 continue;\r
507             }\r
508             String localeString = DATA[i][0];\r
509             Double numberToBeFormat = new Double(DATA[i][1]);\r
510             String currencyISOCode = DATA[i][2];\r
511             ULocale locale = new ULocale(localeString);\r
512             NumberFormat numFmt = NumberFormat.getInstance(locale, k);\r
513             numFmt.setCurrency(Currency.getInstance(currencyISOCode));\r
514             String strBuf = numFmt.format(numberToBeFormat);\r
515             int resultDataIndex = k-1;\r
516             if ( k == NumberFormat.CURRENCYSTYLE ) {\r
517                 resultDataIndex = k+2;\r
518             }\r
519             // DATA[i][resultDataIndex] is the currency format result\r
520             // using 'k' currency style.\r
521             String formatResult = DATA[i][resultDataIndex];\r
522             if (!strBuf.equals(formatResult)) {\r
523                 errln("FAIL: Expected " + formatResult + " actual: " + Utility.escape(strBuf));\r
524             }\r
525             try {\r
526                 // test parsing, and test parsing for all currency formats.\r
527                 for (int j = 3; j < 6; ++j) {\r
528                     // DATA[i][3] is the currency format result using \r
529                     // CURRENCYSTYLE formatter.\r
530                     // DATA[i][4] is the currency format result using\r
531                     // ISOCURRENCYSTYLE formatter.\r
532                     // DATA[i][5] is the currency format result using\r
533                     // PLURALCURRENCYSTYLE formatter.\r
534                     String oneCurrencyFormatResult = DATA[i][j];\r
535                     Number val = numFmt.parse(oneCurrencyFormatResult);\r
536                     if (val.doubleValue() != numberToBeFormat.doubleValue()) {\r
537                         errln("FAIL: getCurrencyFormat of locale " + localeString + " failed roundtripping the number. val=" + val + "; expected: " + numberToBeFormat);\r
538                     }\r
539                 }\r
540             }\r
541             catch (ParseException e) {\r
542                 errln("FAIL: " + e.getMessage());\r
543             }\r
544           }  \r
545         }\r
546     }\r
547 \r
548 \r
549     public void TestMiscCurrencyParsing() {\r
550         String[][] DATA = {\r
551             // each has: string to be parsed, parsed position, error position\r
552             {"1.00 ", "0", "4"},\r
553             {"1.00 UAE dirha", "0", "4"},\r
554             {"1.00 us dollar", "14", "-1"},\r
555             {"1.00 US DOLLAR", "14", "-1"},\r
556             {"1.00 usd", "0", "4"},\r
557         };\r
558         ULocale locale = new ULocale("en_US");\r
559         for (int i=0; i<DATA.length; ++i) {\r
560             String stringToBeParsed = DATA[i][0];\r
561             int parsedPosition = Integer.parseInt(DATA[i][1]);\r
562             int errorIndex = Integer.parseInt(DATA[i][2]);\r
563             NumberFormat numFmt = NumberFormat.getInstance(locale, NumberFormat.CURRENCYSTYLE);\r
564             ParsePosition parsePosition = new ParsePosition(0);\r
565             Number val = numFmt.parse(stringToBeParsed, parsePosition);\r
566             if (parsePosition.getIndex() != parsedPosition ||\r
567                 parsePosition.getErrorIndex() != errorIndex) {\r
568                 errln("FAIL: parse failed. expected error position: " + errorIndex + "; actual: " + parsePosition.getErrorIndex());\r
569                 errln("FAIL: parse failed. expected position: " + parsedPosition +"; actual: " + parsePosition.getIndex());\r
570             }\r
571             if (parsePosition.getErrorIndex() == -1 &&\r
572                 val.doubleValue() != 1.00) {\r
573                 errln("FAIL: parse failed. expected 1.00, actual:" + val);\r
574             }\r
575         }\r
576     }\r
577 \r
578 \r
579     /**\r
580      * Test the Currency object handling, new as of ICU 2.2.\r
581      */\r
582     public void TestCurrencyObject() {\r
583         NumberFormat fmt =\r
584             NumberFormat.getCurrencyInstance(Locale.US);\r
585 \r
586         expectCurrency(fmt, null, 1234.56, "$1,234.56");\r
587 \r
588         expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),\r
589                        1234.56, "\u20AC1,234.56"); // Euro\r
590 \r
591         expectCurrency(fmt, Currency.getInstance(Locale.JAPAN),\r
592                        1234.56, "\u00A51,235"); // Yen\r
593 \r
594         expectCurrency(fmt, Currency.getInstance(new Locale("fr", "CH", "")),\r
595                        1234.56, "CHF1,234.55"); // 0.05 rounding\r
596 \r
597         expectCurrency(fmt, Currency.getInstance(Locale.US),\r
598                        1234.56, "$1,234.56");\r
599 \r
600         fmt = NumberFormat.getCurrencyInstance(Locale.FRANCE);\r
601 \r
602         expectCurrency(fmt, null, 1234.56, "1 234,56 \u20AC");\r
603 \r
604         expectCurrency(fmt, Currency.getInstance(Locale.JAPAN),\r
605                        1234.56, "1 235 \u00A5JP"); // Yen\r
606 \r
607         expectCurrency(fmt, Currency.getInstance(new Locale("fr", "CH", "")),\r
608                        1234.56, "1 234,55 CHF"); // 0.25 rounding\r
609 \r
610         expectCurrency(fmt, Currency.getInstance(Locale.US),\r
611                        1234.56, "1 234,56 $US");\r
612 \r
613         expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),\r
614                        1234.56, "1 234,56 \u20AC"); // Euro\r
615     }\r
616 \r
617     public void TestCurrencyPatterns() {\r
618         int i;\r
619         Locale[] locs = NumberFormat.getAvailableLocales();\r
620         for (i=0; i<locs.length; ++i) {\r
621             NumberFormat nf = NumberFormat.getCurrencyInstance(locs[i]);\r
622             // Make sure currency formats do not have a variable number\r
623             // of fraction digits\r
624             int min = nf.getMinimumFractionDigits();\r
625             int max = nf.getMaximumFractionDigits();\r
626             if (min != max) {\r
627                 String a = nf.format(1.0);\r
628                 String b = nf.format(1.125);\r
629                 errln("FAIL: " + locs[i] +\r
630                       " min fraction digits != max fraction digits; "+\r
631                       "x 1.0 => " + a +\r
632                       "; x 1.125 => " + b);\r
633             }\r
634 \r
635             // Make sure EURO currency formats have exactly 2 fraction digits\r
636             if (nf instanceof DecimalFormat) {\r
637                 Currency curr = ((DecimalFormat) nf).getCurrency();\r
638                 if (curr != null && "EUR".equals(curr.getCurrencyCode())) {\r
639                     if (min != 2 || max != 2) {\r
640                         String a = nf.format(1.0);\r
641                         errln("FAIL: " + locs[i] +\r
642                               " is a EURO format but it does not have 2 fraction digits; "+\r
643                               "x 1.0 => " +\r
644                               a);\r
645                     }\r
646                 }\r
647             }\r
648         }\r
649     }\r
650 \r
651     /**\r
652      * Do rudimentary testing of parsing.\r
653      */\r
654     public void TestParse() {\r
655         String arg = "0.0";\r
656         DecimalFormat format = new DecimalFormat("00");\r
657         double aNumber = 0l;\r
658         try {\r
659             aNumber = format.parse(arg).doubleValue();\r
660         } catch (ParseException e) {\r
661             System.out.println(e);\r
662         }\r
663         logln("parse(" + arg + ") = " + aNumber);\r
664     }\r
665 \r
666     /**\r
667      * Test proper rounding by the format method.\r
668      */\r
669     public void TestRounding487() {\r
670 \r
671         NumberFormat nf = NumberFormat.getInstance();\r
672         roundingTest(nf, 0.00159999, 4, "0.0016");\r
673         roundingTest(nf, 0.00995, 4, "0.01");\r
674 \r
675         roundingTest(nf, 12.3995, 3, "12.4");\r
676 \r
677         roundingTest(nf, 12.4999, 0, "12");\r
678         roundingTest(nf, - 19.5, 0, "-20");\r
679 \r
680     }\r
681 \r
682     /**\r
683      * Test the functioning of the secondary grouping value.\r
684      */\r
685     public void TestSecondaryGrouping() {\r
686 \r
687         DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);\r
688         DecimalFormat f = new DecimalFormat("#,##,###", US);\r
689 \r
690         expect(f, 123456789L, "12,34,56,789");\r
691         expectPat(f, "#,##,###");\r
692         f.applyPattern("#,###");\r
693 \r
694         f.setSecondaryGroupingSize(4);\r
695         expect(f, 123456789L, "12,3456,789");\r
696         expectPat(f, "#,####,###");\r
697         NumberFormat g = NumberFormat.getInstance(new Locale("hi", "IN"));\r
698 \r
699         String out = "";\r
700         long l = 1876543210L;\r
701         out = g.format(l);\r
702 \r
703         // expect "1,87,65,43,210", but with Hindi digits\r
704         //         01234567890123\r
705         boolean ok = true;\r
706         if (out.length() != 14) {\r
707             ok = false;\r
708         } else {\r
709             for (int i = 0; i < out.length(); ++i) {\r
710                 boolean expectGroup = false;\r
711                 switch (i) {\r
712                     case 1 :\r
713                     case 4 :\r
714                     case 7 :\r
715                     case 10 :\r
716                         expectGroup = true;\r
717                         break;\r
718                 }\r
719                 // Later -- fix this to get the actual grouping\r
720                 // character from the resource bundle.\r
721                 boolean isGroup = (out.charAt(i) == 0x002C);\r
722                 if (isGroup != expectGroup) {\r
723                     ok = false;\r
724                     break;\r
725                 }\r
726             }\r
727         }\r
728         if (!ok) {\r
729             errln("FAIL  Expected "+ l + " x hi_IN . \"1,87,65,43,210\" (with Hindi digits), got \""\r
730                     + out + "\"");\r
731         } else {\r
732             logln("Ok    " + l + " x hi_IN . \"" + out + "\"");\r
733         }\r
734     }\r
735 \r
736     public void roundingTest(NumberFormat nf, double x, int maxFractionDigits, final String expected) {\r
737         nf.setMaximumFractionDigits(maxFractionDigits);\r
738         String out = nf.format(x);\r
739         logln(x + " formats with " + maxFractionDigits + " fractional digits to " + out);\r
740         if (!out.equals(expected))\r
741             errln("FAIL: Expected " + expected);\r
742     }\r
743 \r
744     /**\r
745      * Upgrade to alphaWorks\r
746      */\r
747     public void TestExponent() {\r
748         DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);\r
749         DecimalFormat fmt1 = new DecimalFormat("0.###E0", US);\r
750         DecimalFormat fmt2 = new DecimalFormat("0.###E+0", US);\r
751         int n = 1234;\r
752         expect2(fmt1, n, "1.234E3");\r
753         expect2(fmt2, n, "1.234E+3");\r
754         expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"\r
755 \r
756     }\r
757 \r
758     /**\r
759      * Upgrade to alphaWorks\r
760      */\r
761     public void TestScientific() {\r
762 \r
763         DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);\r
764 \r
765         // Test pattern round-trip\r
766         final String PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000", "0.###E0;[0.###E0]" };\r
767         int PAT_length = PAT.length;\r
768         int DIGITS[] = {\r
769             // min int, max int, min frac, max frac\r
770             0, 1, 0, 0, // "#E0"\r
771             1, 1, 0, 4, // "0.####E0"\r
772             2, 2, 3, 3, // "00.000E00"\r
773             1, 3, 0, 4, // "##0.####E000"\r
774             1, 1, 0, 3, // "0.###E0;[0.###E0]"\r
775         };\r
776         for (int i = 0; i < PAT_length; ++i) {\r
777             String pat = PAT[i];\r
778             DecimalFormat df = new DecimalFormat(pat, US);\r
779             String pat2 = df.toPattern();\r
780             if (pat.equals(pat2)) {\r
781                 logln("Ok   Pattern rt \"" + pat + "\" . \"" + pat2 + "\"");\r
782             } else {\r
783                 errln("FAIL Pattern rt \"" + pat + "\" . \"" + pat2 + "\"");\r
784             }\r
785             // Make sure digit counts match what we expect\r
786             if (df.getMinimumIntegerDigits() != DIGITS[4 * i]\r
787                 || df.getMaximumIntegerDigits() != DIGITS[4 * i + 1]\r
788                 || df.getMinimumFractionDigits() != DIGITS[4 * i + 2]\r
789                 || df.getMaximumFractionDigits() != DIGITS[4 * i + 3]) {\r
790                 errln("FAIL \""+ pat+ "\" min/max int; min/max frac = "\r
791                         + df.getMinimumIntegerDigits() + "/"\r
792                         + df.getMaximumIntegerDigits() + ";"\r
793                         + df.getMinimumFractionDigits() + "/"\r
794                         + df.getMaximumFractionDigits() + ", expect "\r
795                         + DIGITS[4 * i] + "/"\r
796                         + DIGITS[4 * i + 1] + ";"\r
797                         + DIGITS[4 * i + 2] + "/"\r
798                         + DIGITS[4 * i + 3]);\r
799             }\r
800         }\r
801 \r
802         expect2(new DecimalFormat("#E0", US), 12345.0, "1.2345E4");\r
803         expect(new DecimalFormat("0E0", US), 12345.0, "1E4");\r
804 \r
805         // pattern of NumberFormat.getScientificInstance(Locale.US) = "0.######E0" not "#E0"\r
806         // so result = 1.234568E4 not 1.2345678901E4\r
807         //when the pattern problem is finalized, delete comment mark'//'\r
808         //of the following code\r
809         expect2(NumberFormat.getScientificInstance(Locale.US), 12345.678901, "1.2345678901E4");\r
810         logln("Testing NumberFormat.getScientificInstance(ULocale) ...");\r
811         expect2(NumberFormat.getScientificInstance(ULocale.US), 12345.678901, "1.2345678901E4");\r
812 \r
813         expect(new DecimalFormat("##0.###E0", US), 12345.0, "12.34E3");\r
814         expect(new DecimalFormat("##0.###E0", US), 12345.00001, "12.35E3");\r
815         expect2(new DecimalFormat("##0.####E0", US), 12345, "12.345E3");\r
816 \r
817         // pattern of NumberFormat.getScientificInstance(Locale.US) = "0.######E0" not "#E0"\r
818         // so result = 1.234568E4 not 1.2345678901E4\r
819         expect2(NumberFormat.getScientificInstance(Locale.FRANCE), 12345.678901, "1,2345678901E4");\r
820         logln("Testing NumberFormat.getScientificInstance(ULocale) ...");\r
821         expect2(NumberFormat.getScientificInstance(ULocale.FRANCE), 12345.678901, "1,2345678901E4");\r
822 \r
823         expect(new DecimalFormat("##0.####E0", US), 789.12345e-9, "789.12E-9");\r
824         expect2(new DecimalFormat("##0.####E0", US), 780.e-9, "780E-9");\r
825         expect(new DecimalFormat(".###E0", US), 45678.0, ".457E5");\r
826         expect2(new DecimalFormat(".###E0", US), 0, ".0E0");\r
827         /*\r
828         expect(new DecimalFormat[] { new DecimalFormat("#E0", US),\r
829                                      new DecimalFormat("##E0", US),\r
830                                      new DecimalFormat("####E0", US),\r
831                                      new DecimalFormat("0E0", US),\r
832                                      new DecimalFormat("00E0", US),\r
833                                      new DecimalFormat("000E0", US),\r
834                                    },\r
835                new Long(45678000),\r
836                new String[] { "4.5678E7",\r
837                               "45.678E6",\r
838                               "4567.8E4",\r
839                               "5E7",\r
840                               "46E6",\r
841                               "457E5",\r
842                             }\r
843                );\r
844         !\r
845         ! Unroll this test into individual tests below...\r
846         !\r
847         */\r
848         expect2(new DecimalFormat("#E0", US), 45678000, "4.5678E7");\r
849         expect2(new DecimalFormat("##E0", US), 45678000, "45.678E6");\r
850         expect2(new DecimalFormat("####E0", US), 45678000, "4567.8E4");\r
851         expect(new DecimalFormat("0E0", US), 45678000, "5E7");\r
852         expect(new DecimalFormat("00E0", US), 45678000, "46E6");\r
853         expect(new DecimalFormat("000E0", US), 45678000, "457E5");\r
854         /*\r
855         expect(new DecimalFormat("###E0", US, status),\r
856                new Object[] { new Double(0.0000123), "12.3E-6",\r
857                               new Double(0.000123), "123E-6",\r
858                               new Double(0.00123), "1.23E-3",\r
859                               new Double(0.0123), "12.3E-3",\r
860                               new Double(0.123), "123E-3",\r
861                               new Double(1.23), "1.23E0",\r
862                               new Double(12.3), "12.3E0",\r
863                               new Double(123), "123E0",\r
864                               new Double(1230), "1.23E3",\r
865                              });\r
866         !\r
867         ! Unroll this test into individual tests below...\r
868         !\r
869         */\r
870         expect2(new DecimalFormat("###E0", US), 0.0000123, "12.3E-6");\r
871         expect2(new DecimalFormat("###E0", US), 0.000123, "123E-6");\r
872         expect2(new DecimalFormat("###E0", US), 0.00123, "1.23E-3");\r
873         expect2(new DecimalFormat("###E0", US), 0.0123, "12.3E-3");\r
874         expect2(new DecimalFormat("###E0", US), 0.123, "123E-3");\r
875         expect2(new DecimalFormat("###E0", US), 1.23, "1.23E0");\r
876         expect2(new DecimalFormat("###E0", US), 12.3, "12.3E0");\r
877         expect2(new DecimalFormat("###E0", US), 123.0, "123E0");\r
878         expect2(new DecimalFormat("###E0", US), 1230.0, "1.23E3");\r
879         /*\r
880         expect(new DecimalFormat("0.#E+00", US, status),\r
881                new Object[] { new Double(0.00012), "1.2E-04",\r
882                               new Long(12000),     "1.2E+04",\r
883                              });\r
884         !\r
885         ! Unroll this test into individual tests below...\r
886         !\r
887         */\r
888         expect2(new DecimalFormat("0.#E+00", US), 0.00012, "1.2E-04");\r
889         expect2(new DecimalFormat("0.#E+00", US), 12000, "1.2E+04");\r
890     }\r
891 \r
892     /**\r
893      * Upgrade to alphaWorks\r
894      */\r
895     public void TestPad() {\r
896 \r
897         DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);\r
898         expect2(new DecimalFormat("*^##.##", US), 0, "^^^^0");\r
899         expect2(new DecimalFormat("*^##.##", US), -1.3, "^-1.3");\r
900         expect2(\r
901             new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US),\r
902             0,\r
903             "0.0E0______ g-m/s^2");\r
904         expect(\r
905             new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US),\r
906             1.0 / 3,\r
907             "333.333E-3_ g-m/s^2");\r
908         expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US), 0, "0.0______ g-m/s^2");\r
909         expect(\r
910             new DecimalFormat("##0.0####*_ 'g-m/s^2'", US),\r
911             1.0 / 3,\r
912             "0.33333__ g-m/s^2");\r
913 \r
914         // Test padding before a sign\r
915         final String formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)";\r
916         expect2(new DecimalFormat(formatStr, US), -10, "xxxxxxxxxx(10.0)");\r
917         expect2(new DecimalFormat(formatStr, US), -1000, "xxxxxxx(1,000.0)");\r
918         expect2(new DecimalFormat(formatStr, US), -1000000, "xxx(1,000,000.0)");\r
919         expect2(new DecimalFormat(formatStr, US), -100.37, "xxxxxxxx(100.37)");\r
920         expect2(new DecimalFormat(formatStr, US), -10456.37, "xxxxx(10,456.37)");\r
921         expect2(new DecimalFormat(formatStr, US), -1120456.37, "xx(1,120,456.37)");\r
922         expect2(new DecimalFormat(formatStr, US), -112045600.37, "(112,045,600.37)");\r
923         expect2(new DecimalFormat(formatStr, US), -1252045600.37, "(1,252,045,600.37)");\r
924 \r
925         expect2(new DecimalFormat(formatStr, US), 10, "xxxxxxxxxxxx10.0");\r
926         expect2(new DecimalFormat(formatStr, US), 1000, "xxxxxxxxx1,000.0");\r
927         expect2(new DecimalFormat(formatStr, US), 1000000, "xxxxx1,000,000.0");\r
928         expect2(new DecimalFormat(formatStr, US), 100.37, "xxxxxxxxxx100.37");\r
929         expect2(new DecimalFormat(formatStr, US), 10456.37, "xxxxxxx10,456.37");\r
930         expect2(new DecimalFormat(formatStr, US), 1120456.37, "xxxx1,120,456.37");\r
931         expect2(new DecimalFormat(formatStr, US), 112045600.37, "xx112,045,600.37");\r
932         expect2(new DecimalFormat(formatStr, US), 10252045600.37, "10,252,045,600.37");\r
933 \r
934         // Test padding between a sign and a number\r
935         final String formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)";\r
936         expect2(new DecimalFormat(formatStr2, US), -10, "(10.0xxxxxxxxxx)");\r
937         expect2(new DecimalFormat(formatStr2, US), -1000, "(1,000.0xxxxxxx)");\r
938         expect2(new DecimalFormat(formatStr2, US), -1000000, "(1,000,000.0xxx)");\r
939         expect2(new DecimalFormat(formatStr2, US), -100.37, "(100.37xxxxxxxx)");\r
940         expect2(new DecimalFormat(formatStr2, US), -10456.37, "(10,456.37xxxxx)");\r
941         expect2(new DecimalFormat(formatStr2, US), -1120456.37, "(1,120,456.37xx)");\r
942         expect2(new DecimalFormat(formatStr2, US), -112045600.37, "(112,045,600.37)");\r
943         expect2(new DecimalFormat(formatStr2, US), -1252045600.37, "(1,252,045,600.37)");\r
944 \r
945         expect2(new DecimalFormat(formatStr2, US), 10, "10.0xxxxxxxxxxxx");\r
946         expect2(new DecimalFormat(formatStr2, US), 1000, "1,000.0xxxxxxxxx");\r
947         expect2(new DecimalFormat(formatStr2, US), 1000000, "1,000,000.0xxxxx");\r
948         expect2(new DecimalFormat(formatStr2, US), 100.37, "100.37xxxxxxxxxx");\r
949         expect2(new DecimalFormat(formatStr2, US), 10456.37, "10,456.37xxxxxxx");\r
950         expect2(new DecimalFormat(formatStr2, US), 1120456.37, "1,120,456.37xxxx");\r
951         expect2(new DecimalFormat(formatStr2, US), 112045600.37, "112,045,600.37xx");\r
952         expect2(new DecimalFormat(formatStr2, US), 10252045600.37, "10,252,045,600.37");\r
953 \r
954         //testing the setPadCharacter(UnicodeString) and getPadCharacterString()\r
955         DecimalFormat fmt = new DecimalFormat("#", US);\r
956         char padString = 'P';\r
957         fmt.setPadCharacter(padString);\r
958         expectPad(fmt, "*P##.##", DecimalFormat.PAD_BEFORE_PREFIX, 5, padString);\r
959         fmt.setPadCharacter('^');\r
960         expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, '^');\r
961         //commented untill implementation is complete\r
962         /*  fmt.setPadCharacter((UnicodeString)"^^^");\r
963           expectPad(fmt, "*^^^#", DecimalFormat.kPadBeforePrefix, 3, (UnicodeString)"^^^");\r
964           padString.remove();\r
965           padString.append((UChar)0x0061);\r
966           padString.append((UChar)0x0302);\r
967           fmt.setPadCharacter(padString);\r
968           UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};\r
969           UnicodeString pattern(patternChars);\r
970           expectPad(fmt, pattern , DecimalFormat.kPadBeforePrefix, 4, padString);\r
971           */\r
972     }\r
973 \r
974     /**\r
975      * Upgrade to alphaWorks\r
976      */\r
977     public void TestPatterns2() {\r
978         DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);\r
979         DecimalFormat fmt = new DecimalFormat("#", US);\r
980 \r
981         char hat = 0x005E; /*^*/\r
982 \r
983         expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, hat);\r
984         expectPad(fmt, "$*^#", DecimalFormat.PAD_AFTER_PREFIX, 2, hat);\r
985         expectPad(fmt, "#*^", DecimalFormat.PAD_BEFORE_SUFFIX, 1, hat);\r
986         expectPad(fmt, "#$*^", DecimalFormat.PAD_AFTER_SUFFIX, 2, hat);\r
987         expectPad(fmt, "$*^$#", -1);\r
988         expectPad(fmt, "#$*^$", -1);\r
989         expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat.PAD_BEFORE_SUFFIX, 12, (char) 0x0078 /*x*/);\r
990         expectPad(fmt, "''#0*x", DecimalFormat.PAD_BEFORE_SUFFIX, 3, (char) 0x0078 /*x*/);\r
991         expectPad(fmt, "'I''ll'*a###.##", DecimalFormat.PAD_AFTER_PREFIX, 10, (char) 0x0061 /*a*/);\r
992 \r
993         fmt.applyPattern("AA#,##0.00ZZ");\r
994         fmt.setPadCharacter(hat);\r
995 \r
996         fmt.setFormatWidth(10);\r
997 \r
998         fmt.setPadPosition(DecimalFormat.PAD_BEFORE_PREFIX);\r
999         expectPat(fmt, "*^AA#,##0.00ZZ");\r
1000 \r
1001         fmt.setPadPosition(DecimalFormat.PAD_BEFORE_SUFFIX);\r
1002         expectPat(fmt, "AA#,##0.00*^ZZ");\r
1003 \r
1004         fmt.setPadPosition(DecimalFormat.PAD_AFTER_SUFFIX);\r
1005         expectPat(fmt, "AA#,##0.00ZZ*^");\r
1006 \r
1007         //            12  3456789012\r
1008         String exp = "AA*^#,##0.00ZZ";\r
1009         fmt.setFormatWidth(12);\r
1010         fmt.setPadPosition(DecimalFormat.PAD_AFTER_PREFIX);\r
1011         expectPat(fmt, exp);\r
1012 \r
1013         fmt.setFormatWidth(13);\r
1014         //              12  34567890123\r
1015         expectPat(fmt, "AA*^##,##0.00ZZ");\r
1016 \r
1017         fmt.setFormatWidth(14);\r
1018         //              12  345678901234\r
1019         expectPat(fmt, "AA*^###,##0.00ZZ");\r
1020 \r
1021         fmt.setFormatWidth(15);\r
1022         //              12  3456789012345\r
1023         expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case\r
1024 \r
1025         fmt.setFormatWidth(16);\r
1026         //              12  34567890123456\r
1027         expectPat(fmt, "AA*^#,###,##0.00ZZ");\r
1028     }\r
1029 \r
1030     public void TestRegistration() {\r
1031         final ULocale SRC_LOC = ULocale.FRANCE;\r
1032         final ULocale SWAP_LOC = ULocale.US;\r
1033 \r
1034         class TestFactory extends SimpleNumberFormatFactory {\r
1035             NumberFormat currencyStyle;\r
1036 \r
1037             TestFactory() {\r
1038                 super(SRC_LOC, true);\r
1039                 currencyStyle = NumberFormat.getIntegerInstance(SWAP_LOC);\r
1040             }\r
1041 \r
1042             public NumberFormat createFormat(ULocale loc, int formatType) {\r
1043                 if (formatType == FORMAT_CURRENCY) {\r
1044                     return currencyStyle;\r
1045                 }\r
1046                 return null;\r
1047             }\r
1048         }\r
1049 \r
1050         NumberFormat f0 = NumberFormat.getIntegerInstance(SWAP_LOC);\r
1051         NumberFormat f1 = NumberFormat.getIntegerInstance(SRC_LOC);\r
1052         NumberFormat f2 = NumberFormat.getCurrencyInstance(SRC_LOC);\r
1053         Object key = NumberFormat.registerFactory(new TestFactory());\r
1054         NumberFormat f3 = NumberFormat.getCurrencyInstance(SRC_LOC);\r
1055         NumberFormat f4 = NumberFormat.getIntegerInstance(SRC_LOC);\r
1056         NumberFormat.unregister(key); // restore for other tests\r
1057         NumberFormat f5 = NumberFormat.getCurrencyInstance(SRC_LOC);\r
1058 \r
1059         float n = 1234.567f;\r
1060         logln("f0 swap int: " + f0.format(n));\r
1061         logln("f1 src int: " + f1.format(n));\r
1062         logln("f2 src cur: " + f2.format(n));\r
1063         logln("f3 reg cur: " + f3.format(n));\r
1064         logln("f4 reg int: " + f4.format(n));\r
1065         logln("f5 unreg cur: " + f5.format(n));\r
1066 \r
1067         if (!f3.format(n).equals(f0.format(n))) {\r
1068             errln("registered service did not match");\r
1069         }\r
1070         if (!f4.format(n).equals(f1.format(n))) {\r
1071             errln("registered service did not inherit");\r
1072         }\r
1073         if (!f5.format(n).equals(f2.format(n))) {\r
1074             errln("unregistered service did not match original");\r
1075         }\r
1076     }\r
1077 \r
1078     public void TestScientific2() {\r
1079         // jb 2552\r
1080         DecimalFormat fmt = (DecimalFormat)NumberFormat.getCurrencyInstance();\r
1081         Number num = new Double(12.34);\r
1082         expect(fmt, num, "$12.34");\r
1083         fmt.setScientificNotation(true);\r
1084         expect(fmt, num, "$1.23E1");\r
1085         fmt.setScientificNotation(false);\r
1086         expect(fmt, num, "$12.34");\r
1087     }\r
1088 \r
1089     public void TestScientificGrouping() {\r
1090         // jb 2552\r
1091         DecimalFormat fmt = new DecimalFormat("###.##E0");\r
1092         expect(fmt, .01234, "12.3E-3");\r
1093         expect(fmt, .1234, "123E-3");\r
1094         expect(fmt, 1.234, "1.23E0");\r
1095         expect(fmt, 12.34, "12.3E0");\r
1096         expect(fmt, 123.4, "123E0");\r
1097         expect(fmt, 1234, "1.23E3");\r
1098     }\r
1099 \r
1100     // additional coverage tests\r
1101 \r
1102     // sigh, can't have static inner classes, why not?\r
1103 \r
1104     static final class PI extends Number {\r
1105         /**\r
1106          * For serialization\r
1107          */\r
1108         private static final long serialVersionUID = -305601227915602172L;\r
1109 \r
1110         private PI() {}\r
1111         public int intValue() { return (int)Math.PI; }\r
1112         public long longValue() { return (long)Math.PI; }\r
1113         public float  floatValue() { return (float)Math.PI; }\r
1114         public double doubleValue() { return (double)Math.PI; }\r
1115         public byte byteValue() { return (byte)Math.PI; }\r
1116         public short shortValue() { return (short)Math.PI; }\r
1117 \r
1118         public static final Number INSTANCE = new PI();\r
1119     }\r
1120 \r
1121     public void TestCoverage() {\r
1122         NumberFormat fmt = NumberFormat.getNumberInstance(); // default locale\r
1123         logln(fmt.format(new BigInteger("1234567890987654321234567890987654321", 10)));\r
1124 \r
1125         fmt = NumberFormat.getScientificInstance(); // default locale\r
1126 \r
1127         logln(fmt.format(PI.INSTANCE));\r
1128 \r
1129         try {\r
1130             logln(fmt.format("12345"));\r
1131             errln("numberformat of string did not throw exception");\r
1132         }\r
1133         catch (Exception e) {\r
1134             logln("PASS: numberformat of string failed as expected");\r
1135         }\r
1136 \r
1137         int hash = fmt.hashCode();\r
1138         logln("hash code " + hash);\r
1139 \r
1140         logln("compare to string returns: " + fmt.equals(""));\r
1141 \r
1142         // For ICU 2.6 - alan\r
1143         DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);\r
1144         DecimalFormat df = new DecimalFormat("'*&'' '\u00A4' ''&*' #,##0.00", US);\r
1145         df.setCurrency(Currency.getInstance("INR"));\r
1146         expect2(df, 1.0, "*&' Rs '&* 1.00");\r
1147         expect2(df, -2.0, "-*&' Rs '&* 2.00");\r
1148         df.applyPattern("#,##0.00 '*&'' '\u00A4' ''&*'");\r
1149         expect2(df, 2.0, "2.00 *&' Rs '&*");\r
1150         expect2(df, -1.0, "-1.00 *&' Rs '&*");\r
1151 \r
1152         java.math.BigDecimal r = df.getRoundingIncrement();\r
1153         if (r != null) {\r
1154             errln("FAIL: rounding = " + r + ", expect null");\r
1155         }\r
1156 \r
1157         if (df.isScientificNotation()) {\r
1158             errln("FAIL: isScientificNotation = true, expect false");\r
1159         }\r
1160 \r
1161         df.applyPattern("0.00000");\r
1162         df.setScientificNotation(true);\r
1163         if (!df.isScientificNotation()) {\r
1164             errln("FAIL: isScientificNotation = false, expect true");\r
1165         }\r
1166         df.setMinimumExponentDigits((byte)2);\r
1167         if (df.getMinimumExponentDigits() != 2) {\r
1168             errln("FAIL: getMinimumExponentDigits = " +\r
1169                   df.getMinimumExponentDigits() + ", expect 2");\r
1170         }\r
1171         df.setExponentSignAlwaysShown(true);\r
1172         if (!df.isExponentSignAlwaysShown()) {\r
1173             errln("FAIL: isExponentSignAlwaysShown = false, expect true");\r
1174         }\r
1175         df.setSecondaryGroupingSize(0);\r
1176         if (df.getSecondaryGroupingSize() != 0) {\r
1177             errln("FAIL: getSecondaryGroupingSize = " +\r
1178                   df.getSecondaryGroupingSize() + ", expect 0");\r
1179         }\r
1180         expect2(df, 3.14159, "3.14159E+00");\r
1181 \r
1182         // DecimalFormatSymbols#getInstance\r
1183         DecimalFormatSymbols decsym1 = DecimalFormatSymbols.getInstance();\r
1184         DecimalFormatSymbols decsym2 = new DecimalFormatSymbols();\r
1185         if (!decsym1.equals(decsym2)) {\r
1186             errln("FAIL: DecimalFormatSymbols returned by getInstance()" +\r
1187             "does not match new DecimalFormatSymbols().");\r
1188         }\r
1189         decsym1 = DecimalFormatSymbols.getInstance(Locale.JAPAN);\r
1190         decsym2 = DecimalFormatSymbols.getInstance(ULocale.JAPAN);\r
1191         if (!decsym1.equals(decsym2)) {\r
1192             errln("FAIL: DecimalFormatSymbols returned by getInstance(Locale.JAPAN)" +\r
1193             "does not match the one returned by getInstance(ULocale.JAPAN).");\r
1194         }\r
1195 \r
1196         // DecimalFormatSymbols#getAvailableLocales/#getAvailableULocales\r
1197         Locale[] allLocales = DecimalFormatSymbols.getAvailableLocales();\r
1198         if (allLocales.length == 0) {\r
1199             errln("FAIL: Got a empty list for DecimalFormatSymbols.getAvailableLocales");\r
1200         } else {\r
1201             logln("PASS: " + allLocales.length +\r
1202                     " available locales returned by DecimalFormatSymbols.getAvailableLocales");\r
1203         }\r
1204         ULocale[] allULocales = DecimalFormatSymbols.getAvailableULocales();\r
1205         if (allULocales.length == 0) {\r
1206             errln("FAIL: Got a empty list for DecimalFormatSymbols.getAvailableLocales");\r
1207         } else {\r
1208             logln("PASS: " + allULocales.length +\r
1209                     " available locales returned by DecimalFormatSymbols.getAvailableULocales");\r
1210         }\r
1211     }\r
1212 \r
1213     public void TestWhiteSpaceParsing() {\r
1214         DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);\r
1215         DecimalFormat fmt = new DecimalFormat("a  b#0c  ", US);\r
1216         int n = 1234;\r
1217         expect(fmt, "a b1234c ", n);\r
1218         expect(fmt, "a   b1234c   ", n);\r
1219     }\r
1220 \r
1221     /**\r
1222      * Test currencies whose display name is a ChoiceFormat.\r
1223      */\r
1224     public void TestComplexCurrency() {\r
1225 //  CLDR No Longer uses complex currency symbols.\r
1226 //  Skipping this test.\r
1227 //        Locale loc = new Locale("kn", "IN", "");\r
1228 //        NumberFormat fmt = NumberFormat.getCurrencyInstance(loc);\r
1229 \r
1230 //        expect2(fmt, 1.0, "Re.\u00a01.00");\r
1231 //        expect(fmt, 1.001, "Re.\u00a01.00"); // tricky\r
1232 //        expect2(fmt, 12345678.0, "Rs.\u00a01,23,45,678.00");\r
1233 //        expect2(fmt, 0.5, "Rs.\u00a00.50");\r
1234 //        expect2(fmt, -1.0, "-Re.\u00a01.00");\r
1235 //        expect2(fmt, -10.0, "-Rs.\u00a010.00");\r
1236     }\r
1237 \r
1238     public void TestCurrencyKeyword() {\r
1239     ULocale locale = new ULocale("th_TH@currency=QQQ");\r
1240     NumberFormat format = NumberFormat.getCurrencyInstance(locale);\r
1241     String result = format.format(12.34f);\r
1242     if (!"QQQ12.34".equals(result)) {\r
1243         errln("got unexpected currency: " + result);\r
1244     }\r
1245     }\r
1246 \r
1247     /**\r
1248      * Test alternate numbering systems\r
1249      */\r
1250     public void TestNumberingSystems() {\r
1251 \r
1252         ULocale loc1 = new ULocale("en_US@numbers=thai");\r
1253         ULocale loc2 = new ULocale("en_US@numbers=hebr");\r
1254         ULocale loc3 = new ULocale("en_US@numbers=arabext");\r
1255         ULocale loc4 = new ULocale("hi_IN@numbers=foobar");\r
1256         \r
1257         NumberFormat fmt1 = NumberFormat.getInstance(loc1);\r
1258         NumberFormat fmt2 = NumberFormat.getInstance(loc2);\r
1259         NumberFormat fmt3 = NumberFormat.getInstance(loc3);\r
1260         NumberFormat fmt4 = NumberFormat.getInstance(loc4);\r
1261         \r
1262         expect2(fmt1,1234.567,"\u0e51,\u0e52\u0e53\u0e54.\u0e55\u0e56\u0e57");\r
1263         expect3(fmt2,5678.0,"\u05d4\u05f3\u05ea\u05e8\u05e2\u05f4\u05d7");\r
1264         expect2(fmt3,1234.567,"\u06f1,\u06f2\u06f3\u06f4.\u06f5\u06f6\u06f7");\r
1265         expect2(fmt4,1234.567,"\u0967,\u0968\u0969\u096a.\u096b\u096c\u096d");\r
1266 \r
1267     }\r
1268 \r
1269     public void TestThreadedFormat() {\r
1270 \r
1271         class FormatTask implements Runnable {\r
1272             DecimalFormat fmt;\r
1273             StringBuffer buf;\r
1274             boolean inc;\r
1275             float num;\r
1276 \r
1277             FormatTask(DecimalFormat fmt, int index) {\r
1278                 this.fmt = fmt;\r
1279                 this.buf = new StringBuffer();\r
1280                 this.inc = (index & 0x1) == 0;\r
1281                 this.num = inc ? 0 : 10000;\r
1282             }\r
1283 \r
1284             public void run() {\r
1285         if (inc) {\r
1286             while (num < 10000) {\r
1287             buf.append(fmt.format(num) + "\n");\r
1288             num += 3.14159;\r
1289             }\r
1290         } else {\r
1291             while (num > 0) {\r
1292             buf.append(fmt.format(num) + "\n");\r
1293             num -= 3.14159;\r
1294             }\r
1295         }\r
1296         }\r
1297 \r
1298         String result() {\r
1299         return buf.toString();\r
1300         }\r
1301     }\r
1302 \r
1303         DecimalFormat fmt = new DecimalFormat("0.####");\r
1304         FormatTask[] tasks = new FormatTask[8];\r
1305         for (int i = 0; i < tasks.length; ++i) {\r
1306         tasks[i] = new FormatTask(fmt, i);\r
1307     }\r
1308 \r
1309     TestUtil.runUntilDone(tasks);\r
1310 \r
1311         for (int i = 2; i < tasks.length; i++) {\r
1312         String str1 = tasks[i].result();\r
1313         String str2 = tasks[i-2].result();\r
1314             if (!str1.equals(str2)) {\r
1315                 System.out.println("mismatch at " + i);\r
1316                 System.out.println(str1);\r
1317                 System.out.println(str2);\r
1318                 errln("decimal format thread mismatch");\r
1319 \r
1320                 break;\r
1321             }\r
1322             str1 = str2;\r
1323         }\r
1324     }\r
1325 \r
1326     public void TestPerMill() {\r
1327         DecimalFormat fmt = new DecimalFormat("###.###\u2030");\r
1328         assertEquals("0.4857 x ###.###\u2030",\r
1329                      "485.7\u2030", fmt.format(0.4857));\r
1330 \r
1331         DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.ENGLISH);\r
1332         sym.setPerMill('m');\r
1333         DecimalFormat fmt2 = new DecimalFormat("", sym);\r
1334         fmt2.applyLocalizedPattern("###.###m");\r
1335         assertEquals("0.4857 x ###.###m",\r
1336                      "485.7m", fmt2.format(0.4857));\r
1337     }\r
1338 \r
1339     public void TestIllegalPatterns() {\r
1340         // Test cases:\r
1341         // Prefix with "-:" for illegal patterns\r
1342         // Prefix with "+:" for legal patterns\r
1343         String DATA[] = {\r
1344             // Unquoted special characters in the suffix are illegal\r
1345             "-:000.000|###",\r
1346             "+:000.000'|###'",\r
1347         };\r
1348         for (int i=0; i<DATA.length; ++i) {\r
1349             String pat=DATA[i];\r
1350             boolean valid = pat.charAt(0) == '+';\r
1351             pat = pat.substring(2);\r
1352             Exception e = null;\r
1353             try {\r
1354                 // locale doesn't matter here\r
1355                 new DecimalFormat(pat);\r
1356             } catch (IllegalArgumentException e1) {\r
1357                 e = e1;\r
1358             } catch (IndexOutOfBoundsException e1) {\r
1359                 e = e1;\r
1360             }\r
1361             String msg = (e==null) ? "success" : e.getMessage();\r
1362             if ((e==null) == valid) {\r
1363                 logln("Ok: pattern \"" + pat + "\": " + msg);\r
1364             } else {\r
1365                 errln("FAIL: pattern \"" + pat + "\" should have " +\r
1366                       (valid?"succeeded":"failed") + "; got " + msg);\r
1367             }\r
1368         }\r
1369     }\r
1370 \r
1371     /**\r
1372      * Parse a CurrencyAmount using the given NumberFormat, with\r
1373      * the 'delim' character separating the number and the currency.\r
1374      */\r
1375     private static CurrencyAmount parseCurrencyAmount(String str, NumberFormat fmt,\r
1376                                                       char delim)\r
1377         throws ParseException {\r
1378         int i = str.indexOf(delim);\r
1379         return new CurrencyAmount(fmt.parse(str.substring(0,i)),\r
1380                                   Currency.getInstance(str.substring(i+1)));\r
1381     }\r
1382 \r
1383     /**\r
1384      * Return an integer representing the next token from this\r
1385      * iterator.  The integer will be an index into the given list, or\r
1386      * -1 if there are no more tokens, or -2 if the token is not on\r
1387      * the list.\r
1388      */\r
1389     private static int keywordIndex(String tok) {\r
1390         for (int i=0; i<KEYWORDS.length; ++i) {\r
1391             if (tok.equals(KEYWORDS[i])) {\r
1392                 return i;\r
1393             }\r
1394         }\r
1395         return -1;\r
1396     }\r
1397 \r
1398     private static final String KEYWORDS[] = {\r
1399         /*0*/ "ref=", // <reference pattern to parse numbers>\r
1400         /*1*/ "loc=", // <locale for formats>\r
1401         /*2*/ "f:",   // <pattern or '-'> <number> <exp. string>\r
1402         /*3*/ "fp:",  // <pattern or '-'> <number> <exp. string> <exp. number>\r
1403         /*4*/ "rt:",  // <pattern or '-'> <(exp.) number> <(exp.) string>\r
1404         /*5*/ "p:",   // <pattern or '-'> <string> <exp. number>\r
1405         /*6*/ "perr:", // <pattern or '-'> <invalid string>\r
1406         /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>\r
1407         /*8*/ "fpc:", // <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>\r
1408         /*9*/ "strict=", // true or false\r
1409     };\r
1410 \r
1411     public void TestCases() {\r
1412         String caseFileName = "NumberFormatTestCases.txt";\r
1413         java.io.InputStream is = NumberFormatTest.class.getResourceAsStream(caseFileName);\r
1414 \r
1415         ResourceReader reader = new ResourceReader(is, caseFileName, "utf-8");\r
1416         TokenIterator tokens = new TokenIterator(reader);\r
1417 \r
1418         Locale loc = new Locale("en", "US", "");\r
1419         DecimalFormat ref = null, fmt = null;\r
1420         MeasureFormat mfmt = null;\r
1421         String pat = null, str = null, mloc = null;\r
1422         boolean strict = false;\r
1423 \r
1424         try {\r
1425             for (;;) {\r
1426                 String tok = tokens.next();\r
1427                 if (tok == null) {\r
1428                     break;\r
1429                 }\r
1430                 String where = "(" + tokens.getLineNumber() + ") ";\r
1431                 int cmd = keywordIndex(tok);\r
1432                 switch (cmd) {\r
1433                 case 0:\r
1434                     // ref= <reference pattern>\r
1435                     ref = new DecimalFormat(tokens.next(),\r
1436                                             new DecimalFormatSymbols(Locale.US));\r
1437                     ref.setParseStrict(strict);\r
1438                     logln("Setting reference pattern to:\t" + ref);\r
1439                     break;\r
1440                 case 1:\r
1441                     // loc= <locale>\r
1442                     loc = LocaleUtility.getLocaleFromName(tokens.next());\r
1443                     pat = ((DecimalFormat) NumberFormat.getInstance(loc)).toPattern();\r
1444                     logln("Setting locale to:\t" + loc + ", \tand pattern to:\t" + pat);\r
1445                     break;\r
1446                 case 2: // f:\r
1447                 case 3: // fp:\r
1448                 case 4: // rt:\r
1449                 case 5: // p:\r
1450                     tok = tokens.next();\r
1451                     if (!tok.equals("-")) {\r
1452                         pat = tok;\r
1453                     }\r
1454                     try {\r
1455                         fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc));\r
1456                         fmt.setParseStrict(strict);\r
1457                     } catch (IllegalArgumentException iae) {\r
1458                         errln(where + "Pattern \"" + pat + '"');\r
1459                         iae.printStackTrace();\r
1460                         tokens.next(); // consume remaining tokens\r
1461                         //tokens.next();\r
1462                         if (cmd == 3) tokens.next();\r
1463                         continue;\r
1464                     }\r
1465                    str = null;\r
1466                     try {\r
1467                         if (cmd == 2 || cmd == 3 || cmd == 4) {\r
1468                             // f: <pattern or '-'> <number> <exp. string>\r
1469                             // fp: <pattern or '-'> <number> <exp. string> <exp. number>\r
1470                             // rt: <pattern or '-'> <number> <string>\r
1471                             String num = tokens.next();\r
1472                             str = tokens.next();\r
1473                             Number n = (Number) ref.parse(num);\r
1474                             assertEquals(where + '"' + pat + "\".format(" + num + ")",\r
1475                                          str, fmt.format(n));\r
1476                             if (cmd == 3) { // fp:\r
1477                                 n = (Number) ref.parse(tokens.next());\r
1478                             }\r
1479                             if (cmd != 2) { // != f:\r
1480                                 assertEquals(where + '"' + pat + "\".parse(\"" + str + "\")",\r
1481                                              n, fmt.parse(str));\r
1482                             }\r
1483                         }\r
1484                         // p: <pattern or '-'> <string to parse> <exp. number>\r
1485                         else {\r
1486                             str = tokens.next();\r
1487                             String expstr = tokens.next();\r
1488                             Number parsed = fmt.parse(str);\r
1489                             Number exp = (Number) ref.parse(expstr);\r
1490                             assertEquals(where + '"' + pat + "\".parse(\"" + str + "\")",\r
1491                                          exp, parsed);\r
1492                         }\r
1493                     } catch (ParseException e) {\r
1494                         errln(where + '"' + pat + "\".parse(\"" + str +\r
1495                               "\") threw an exception");\r
1496                         e.printStackTrace();\r
1497                     }\r
1498                     break;\r
1499                 case 6:\r
1500                     // perr: <pattern or '-'> <invalid string>\r
1501                     errln("Under construction");\r
1502                     return;\r
1503                 case 7:\r
1504                     // pat: <pattern> <exp. toPattern, or '-' or 'err'>\r
1505                     String testpat = tokens.next();\r
1506                     String exppat  = tokens.next();\r
1507                     boolean err    = exppat.equals("err");\r
1508                     if (testpat.equals("-")) {\r
1509                         if (err) {\r
1510                             errln("Invalid command \"pat: - err\" at " +  tokens.describePosition());\r
1511                             continue;\r
1512                         }\r
1513                         testpat = pat;\r
1514                     }\r
1515                     if (exppat.equals("-")) exppat = testpat;\r
1516                     try {\r
1517                         DecimalFormat f = null;\r
1518                         if (testpat == pat) { // [sic]\r
1519                             f = fmt;\r
1520                         } else {\r
1521                             f = new DecimalFormat(testpat);\r
1522                             f.setParseStrict(strict);\r
1523                         }\r
1524                         if (err) {\r
1525                             errln(where + "Invalid pattern \"" + testpat +\r
1526                                   "\" was accepted");\r
1527                         } else {\r
1528                             assertEquals(where + '"' + testpat + "\".toPattern()",\r
1529                                          exppat, f.toPattern());\r
1530                         }\r
1531                     } catch (IllegalArgumentException iae2) {\r
1532                         if (err) {\r
1533                             logln("Ok: " + where + "Invalid pattern \"" + testpat +\r
1534                                   "\" threw an exception");\r
1535                         } else {\r
1536                             errln(where + "Valid pattern \"" + testpat +\r
1537                                   "\" threw an exception");\r
1538                             iae2.printStackTrace();\r
1539                         }\r
1540                     }\r
1541                     break;\r
1542                 case 8: // fpc:\r
1543                     tok = tokens.next();\r
1544                     if (!tok.equals("-")) {\r
1545                         mloc = tok;\r
1546                         ULocale l = new ULocale(mloc);\r
1547                         try {\r
1548                             mfmt = MeasureFormat.getCurrencyFormat(l);\r
1549                         } catch (IllegalArgumentException iae) {\r
1550                             errln(where + "Loc \"" + tok + '"');\r
1551                             iae.printStackTrace();\r
1552                             tokens.next(); // consume remaining tokens\r
1553                             tokens.next();\r
1554                             tokens.next();\r
1555                             continue;\r
1556                         }\r
1557                     }\r
1558                     str = null;\r
1559                     try {\r
1560                         // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>\r
1561                         String currAmt = tokens.next();\r
1562                         str = tokens.next();\r
1563                         CurrencyAmount target = parseCurrencyAmount(currAmt, ref, '/');\r
1564                         String formatResult = mfmt.format(target);\r
1565                         assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")",\r
1566                                      str, formatResult);\r
1567                         target = parseCurrencyAmount(tokens.next(), ref, '/');\r
1568                         CurrencyAmount parseResult = (CurrencyAmount) mfmt.parseObject(str);\r
1569                         assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",\r
1570                                      target, parseResult);\r
1571                     } catch (ParseException e) {\r
1572                         errln(where + '"' + pat + "\".parse(\"" + str +\r
1573                               "\") threw an exception");\r
1574                         e.printStackTrace();\r
1575                     }\r
1576                     break;\r
1577                 case 9: // strict= true or false\r
1578                     strict = "true".equalsIgnoreCase(tokens.next());\r
1579                     logln("Setting strict to:\t" + strict);\r
1580                     break;\r
1581                 case -1:\r
1582                     errln("Unknown command \"" + tok + "\" at " + tokens.describePosition());\r
1583                     return;\r
1584                 }\r
1585             }\r
1586         } catch (java.io.IOException e) {\r
1587             throw new RuntimeException(e);\r
1588         }\r
1589     }\r
1590 \r
1591     public void TestRounding() {\r
1592         DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getInstance(ULocale.ENGLISH);\r
1593         if (false) { // for debugging specific value\r
1594             nf.setRoundingMode(BigDecimal.ROUND_HALF_UP);\r
1595             checkRounding(nf, new BigDecimal("300.0300000000"), 0, new BigDecimal("0.020000000"));\r
1596         }\r
1597         // full tests\r
1598         int[] roundingIncrements = {1, 2, 5, 20, 50, 100};\r
1599         int[] testValues = {0, 300};\r
1600         for (int j = 0; j < testValues.length; ++j) {\r
1601             for (int mode = BigDecimal.ROUND_UP; mode < BigDecimal.ROUND_HALF_EVEN; ++mode) {\r
1602                 nf.setRoundingMode(mode);\r
1603                 for (int increment = 0; increment < roundingIncrements.length; ++increment) {\r
1604                     BigDecimal base = new BigDecimal(testValues[j]);\r
1605                     BigDecimal rInc = new BigDecimal(roundingIncrements[increment]);\r
1606                     checkRounding(nf,  base, 20, rInc);\r
1607                     rInc = new BigDecimal("1.000000000").divide(rInc);\r
1608                     checkRounding(nf,  base, 20, rInc);\r
1609                 }\r
1610             }\r
1611         }\r
1612     }\r
1613 \r
1614     void checkRounding(DecimalFormat nf, BigDecimal base, int iterations, BigDecimal increment) {\r
1615         nf.setRoundingIncrement(increment.toBigDecimal());\r
1616         BigDecimal lastParsed = new BigDecimal(Integer.MIN_VALUE); // used to make sure that rounding is monotonic\r
1617         for (int i = -iterations; i <= iterations; ++i) {\r
1618             BigDecimal iValue = base.add(increment.multiply(new BigDecimal(i)).movePointLeft(1));\r
1619             BigDecimal smallIncrement = new BigDecimal("0.00000001");\r
1620             if (iValue.signum() != 0) {\r
1621                 smallIncrement.multiply(iValue); // scale unless zero\r
1622             }\r
1623             // we not only test the value, but some values in a small range around it.\r
1624             lastParsed = checkRound(nf, iValue.subtract(smallIncrement), lastParsed);\r
1625             lastParsed = checkRound(nf, iValue, lastParsed);\r
1626             lastParsed = checkRound(nf, iValue.add(smallIncrement), lastParsed);\r
1627         }\r
1628     }\r
1629 \r
1630     private BigDecimal checkRound(DecimalFormat nf, BigDecimal iValue, BigDecimal lastParsed) {\r
1631         String formatedBigDecimal = nf.format(iValue);\r
1632         String formattedDouble = nf.format(iValue.doubleValue());\r
1633         if (!equalButForTrailingZeros(formatedBigDecimal, formattedDouble)) {\r
1634             errln("Failure at: " + iValue + " (" + iValue.doubleValue() + ")"\r
1635                   + ",\tRounding-mode: " + roundingModeNames[nf.getRoundingMode()]\r
1636                   + ",\tRounding-increment: " + nf.getRoundingIncrement()\r
1637                   + ",\tdouble: " + formattedDouble\r
1638                   + ",\tBigDecimal: " + formatedBigDecimal);\r
1639         } else {\r
1640             logln("Value: " + iValue\r
1641                   + ",\tRounding-mode: " + roundingModeNames[nf.getRoundingMode()]\r
1642                   + ",\tRounding-increment: " + nf.getRoundingIncrement()\r
1643                   + ",\tdouble: " + formattedDouble\r
1644                   + ",\tBigDecimal: " + formatedBigDecimal);\r
1645         }\r
1646         try {\r
1647             // Number should have compareTo(...)\r
1648             BigDecimal parsed = toBigDecimal(nf.parse(formatedBigDecimal));\r
1649             if (lastParsed.compareTo(parsed) > 0) {\r
1650                 errln("Rounding wrong direction!: " + lastParsed + " > " + parsed);\r
1651             }\r
1652             lastParsed = parsed;\r
1653         } catch (ParseException e) {\r
1654             errln("Parse Failure with: " + formatedBigDecimal);\r
1655         }\r
1656         return lastParsed;\r
1657     }\r
1658 \r
1659     static BigDecimal toBigDecimal(Number number) {\r
1660         return number instanceof BigDecimal ? (BigDecimal) number\r
1661             : number instanceof BigInteger ? new BigDecimal((BigInteger)number)\r
1662             : number instanceof java.math.BigDecimal ? new BigDecimal((java.math.BigDecimal)number)\r
1663             : number instanceof Double ? new BigDecimal(number.doubleValue())\r
1664             : number instanceof Float ? new BigDecimal(number.floatValue())\r
1665             : new BigDecimal(number.longValue());\r
1666     }\r
1667 \r
1668     static String[] roundingModeNames = {\r
1669         "ROUND_UP", "ROUND_DOWN", "ROUND_CEILING", "ROUND_FLOOR",\r
1670         "ROUND_HALF_UP", "ROUND_HALF_DOWN", "ROUND_HALF_EVEN",\r
1671         "ROUND_UNNECESSARY"\r
1672     };\r
1673 \r
1674     private static boolean equalButForTrailingZeros(String formatted1, String formatted2) {\r
1675         if (formatted1.length() == formatted2.length()) return formatted1.equals(formatted2);\r
1676         return stripFinalZeros(formatted1).equals(stripFinalZeros(formatted2));\r
1677     }\r
1678 \r
1679     private static String stripFinalZeros(String formatted) {\r
1680         int len1 = formatted.length();\r
1681         char ch;\r
1682         while (len1 > 0 && ((ch = formatted.charAt(len1-1)) == '0' || ch == '.')) --len1;\r
1683         return formatted.substring(0,len1);\r
1684     }\r
1685 \r
1686     //------------------------------------------------------------------\r
1687     // Support methods\r
1688     //------------------------------------------------------------------\r
1689 \r
1690     // Format-Parse test\r
1691     public void expect2(NumberFormat fmt, Number n, String exp) {\r
1692         // Don't round-trip format test, since we explicitly do it\r
1693         expect(fmt, n, exp, false);\r
1694         expect(fmt, exp, n);\r
1695     }\r
1696     // Format-Parse test\r
1697     public void expect3(NumberFormat fmt, Number n, String exp) {\r
1698         // Don't round-trip format test, since we explicitly do it\r
1699         expect_rbnf(fmt, n, exp, false);\r
1700         expect_rbnf(fmt, exp, n);\r
1701     }\r
1702 \r
1703     // Format-Parse test (convenience)\r
1704     public void expect2(NumberFormat fmt, double n, String exp) {\r
1705         expect2(fmt, new Double(n), exp);\r
1706     }\r
1707     // Format-Parse test (convenience)\r
1708     public void expect3(NumberFormat fmt, double n, String exp) {\r
1709         expect3(fmt, new Double(n), exp);\r
1710     }\r
1711 \r
1712     // Format-Parse test (convenience)\r
1713     public void expect2(NumberFormat fmt, long n, String exp) {\r
1714         expect2(fmt, new Long(n), exp);\r
1715     }\r
1716     // Format-Parse test (convenience)\r
1717     public void expect3(NumberFormat fmt, long n, String exp) {\r
1718         expect3(fmt, new Long(n), exp);\r
1719     }\r
1720 \r
1721     // Format test\r
1722     public void expect(NumberFormat fmt, Number n, String exp, boolean rt) {\r
1723         StringBuffer saw = new StringBuffer();\r
1724         FieldPosition pos = new FieldPosition(0);\r
1725         fmt.format(n, saw, pos);\r
1726         String pat = ((DecimalFormat)fmt).toPattern();\r
1727         if (saw.toString().equals(exp)) {\r
1728             logln("Ok   " + n + " x " +\r
1729                   pat + " = \"" +\r
1730                   saw + "\"");\r
1731             // We should be able to round-trip the formatted string =>\r
1732             // number => string (but not the other way around: number\r
1733             // => string => number2, might have number2 != number):\r
1734             if (rt) {\r
1735                 try {\r
1736                     Number n2 = fmt.parse(exp);\r
1737                     StringBuffer saw2 = new StringBuffer();\r
1738                     fmt.format(n2, saw2, pos);\r
1739                     if (!saw2.toString().equals(exp)) {\r
1740                         errln("FAIL \"" + exp + "\" => " + n2 +\r
1741                               " => \"" + saw2 + '"');\r
1742                     }\r
1743                 } catch (ParseException e) {\r
1744                     errln(e.getMessage());\r
1745                     return;\r
1746                 }\r
1747             }\r
1748         } else {\r
1749             errln("FAIL " + n + " x " +\r
1750                   pat + " = \"" +\r
1751                   saw + "\", expected \"" + exp + "\"");\r
1752         }\r
1753     }\r
1754     // Format test\r
1755     public void expect_rbnf(NumberFormat fmt, Number n, String exp, boolean rt) {\r
1756         StringBuffer saw = new StringBuffer();\r
1757         FieldPosition pos = new FieldPosition(0);\r
1758         fmt.format(n, saw, pos);\r
1759         if (saw.toString().equals(exp)) {\r
1760             logln("Ok   " + n + " = \"" +\r
1761                   saw + "\"");\r
1762             // We should be able to round-trip the formatted string =>\r
1763             // number => string (but not the other way around: number\r
1764             // => string => number2, might have number2 != number):\r
1765             if (rt) {\r
1766                 try {\r
1767                     Number n2 = fmt.parse(exp);\r
1768                     StringBuffer saw2 = new StringBuffer();\r
1769                     fmt.format(n2, saw2, pos);\r
1770                     if (!saw2.toString().equals(exp)) {\r
1771                         errln("FAIL \"" + exp + "\" => " + n2 +\r
1772                               " => \"" + saw2 + '"');\r
1773                     }\r
1774                 } catch (ParseException e) {\r
1775                     errln(e.getMessage());\r
1776                     return;\r
1777                 }\r
1778             }\r
1779         } else {\r
1780             errln("FAIL " + n + " = \"" +\r
1781                   saw + "\", expected \"" + exp + "\"");\r
1782         }\r
1783     }\r
1784 \r
1785     // Format test (convenience)\r
1786     public void expect(NumberFormat fmt, Number n, String exp) {\r
1787         expect(fmt, n, exp, true);\r
1788     }\r
1789 \r
1790     // Format test (convenience)\r
1791     public void expect(NumberFormat fmt, double n, String exp) {\r
1792         expect(fmt, new Double(n), exp);\r
1793     }\r
1794 \r
1795     // Format test (convenience)\r
1796     public void expect(NumberFormat fmt, long n, String exp) {\r
1797         expect(fmt, new Long(n), exp);\r
1798     }\r
1799 \r
1800     // Parse test\r
1801     public void expect(NumberFormat fmt, String str, Number n) {\r
1802         Number num = null;\r
1803         try {\r
1804             num = (Number) fmt.parse(str);\r
1805         } catch (ParseException e) {\r
1806             errln(e.getMessage());\r
1807             return;\r
1808         }\r
1809         String pat = ((DecimalFormat)fmt).toPattern();\r
1810         // A little tricky here -- make sure Double(12345.0) and\r
1811         // Long(12345) match.\r
1812         if (num.equals(n) || num.doubleValue() == n.doubleValue()) {\r
1813             logln("Ok   \"" + str + "\" x " +\r
1814                   pat + " = " +\r
1815                   num);\r
1816         } else {\r
1817             errln("FAIL \"" + str + "\" x " +\r
1818                   pat + " = " +\r
1819                   num + ", expected " + n);\r
1820         }\r
1821     }\r
1822 \r
1823     // Parse test\r
1824     public void expect_rbnf(NumberFormat fmt, String str, Number n) {\r
1825         Number num = null;\r
1826         try {\r
1827             num = (Number) fmt.parse(str);\r
1828         } catch (ParseException e) {\r
1829             errln(e.getMessage());\r
1830             return;\r
1831         }\r
1832         // A little tricky here -- make sure Double(12345.0) and\r
1833         // Long(12345) match.\r
1834         if (num.equals(n) || num.doubleValue() == n.doubleValue()) {\r
1835             logln("Ok   \"" + str + " = " +\r
1836                   num);\r
1837         } else {\r
1838             errln("FAIL \"" + str + " = " +\r
1839                   num + ", expected " + n);\r
1840         }\r
1841     }\r
1842 \r
1843     // Parse test (convenience)\r
1844     public void expect(NumberFormat fmt, String str, double n) {\r
1845         expect(fmt, str, new Double(n));\r
1846     }\r
1847 \r
1848     // Parse test (convenience)\r
1849     public void expect(NumberFormat fmt, String str, long n) {\r
1850         expect(fmt, str, new Long(n));\r
1851     }\r
1852 \r
1853     private void expectCurrency(NumberFormat nf, Currency curr,\r
1854                                 double value, String string) {\r
1855         DecimalFormat fmt = (DecimalFormat) nf;\r
1856         if (curr != null) {\r
1857             fmt.setCurrency(curr);\r
1858         }\r
1859         String s = fmt.format(value).replace('\u00A0', ' ');\r
1860 \r
1861         if (s.equals(string)) {\r
1862             logln("Ok: " + value + " x " + curr + " => " + s);\r
1863         } else {\r
1864             errln("FAIL: " + value + " x " + curr + " => " + s +\r
1865                   ", expected " + string);\r
1866         }\r
1867     }\r
1868 \r
1869     public void expectPad(DecimalFormat fmt, String pat, int pos) {\r
1870         expectPad(fmt, pat, pos, 0, (char)0);\r
1871     }\r
1872 \r
1873     public void expectPad(DecimalFormat fmt, final String pat, int pos, int width, final char pad) {\r
1874         int apos = 0, awidth = 0;\r
1875         char apadStr;\r
1876         try {\r
1877             fmt.applyPattern(pat);\r
1878             apos = fmt.getPadPosition();\r
1879             awidth = fmt.getFormatWidth();\r
1880             apadStr = fmt.getPadCharacter();\r
1881         } catch (Exception e) {\r
1882             apos = -1;\r
1883             awidth = width;\r
1884             apadStr = pad;\r
1885         }\r
1886 \r
1887         if (apos == pos && awidth == width && apadStr == pad) {\r
1888             logln("Ok   \"" + pat + "\" pos="\r
1889                     + apos + ((pos == -1) ? "" : " width=" + awidth + " pad=" + apadStr));\r
1890         } else {\r
1891             errln("FAIL \"" + pat + "\" pos=" + apos + " width="\r
1892                     + awidth + " pad=" + apadStr + ", expected "\r
1893                     + pos + " " + width + " " + pad);\r
1894         }\r
1895     }\r
1896 \r
1897     public void expectPat(DecimalFormat fmt, final String exp) {\r
1898         String pat = fmt.toPattern();\r
1899         if (pat.equals(exp)) {\r
1900             logln("Ok   \"" + pat + "\"");\r
1901         } else {\r
1902             errln("FAIL \"" + pat + "\", expected \"" + exp + "\"");\r
1903         }\r
1904     }\r
1905 \r
1906     public void TestJB3832(){\r
1907         ULocale locale = new ULocale("pt_PT@currency=PTE");\r
1908         NumberFormat format = NumberFormat.getCurrencyInstance(locale);\r
1909         Currency curr = Currency.getInstance(locale);\r
1910         logln("\nName of the currency is: " + curr.getName(locale, Currency.LONG_NAME, new boolean[] {false}));\r
1911         CurrencyAmount cAmt = new CurrencyAmount(1150.50, curr);\r
1912         logln("CurrencyAmount object's hashCode is: " + cAmt.hashCode()); //cover hashCode\r
1913         String str = format.format(cAmt);\r
1914         String expected = "1,150$50\u00a0Esc.";\r
1915         if(!expected.equals(str)){\r
1916             errln("Did not get the expected output Expected: "+expected+" Got: "+ str);\r
1917         }\r
1918     }\r
1919 \r
1920     public void TestStrictParse() {\r
1921         String[] pass = {\r
1922             "0",           // single zero before end of text is not leading\r
1923             "0 ",          // single zero at end of number is not leading\r
1924             "0.",          // single zero before period (or decimal, it's ambiguous) is not leading\r
1925             "0,",          // single zero before comma (not group separator) is not leading\r
1926             "0.0",         // single zero before decimal followed by digit is not leading\r
1927             "0. ",         // same as above before period (or decimal) is not leading\r
1928             "0.100,5",     // comma stops parse of decimal (no grouping)\r
1929             ".00",         // leading decimal is ok, even with zeros\r
1930             "1234567",     // group separators are not required\r
1931             "12345, ",     // comma not followed by digit is not a group separator, but end of number\r
1932             "1,234, ",     // if group separator is present, group sizes must be appropriate\r
1933             "1,234,567",   // ...secondary too\r
1934             "0E",          // an exponnent not followed by zero or digits is not an exponent\r
1935         };\r
1936         String[] fail = {\r
1937             "00",        // leading zero before zero\r
1938             "012",       // leading zero before digit\r
1939             "0,456",     // leading zero before group separator\r
1940             "1,2",       // wrong number of digits after group separator\r
1941             ",0",        // leading group separator before zero\r
1942             ",1",        // leading group separator before digit\r
1943             ",.02",      // leading group separator before decimal\r
1944             "1,.02",     // group separator before decimal\r
1945             "1,,200",    // multiple group separators\r
1946             "1,45",      // wrong number of digits in primary group\r
1947             "1,45 that", // wrong number of digits in primary group\r
1948             "1,45.34",   // wrong number of digits in primary group\r
1949             "1234,567",  // wrong number of digits in secondary group\r
1950             "12,34,567", // wrong number of digits in secondary group\r
1951             "1,23,456,7890", // wrong number of digits in primary and secondary groups\r
1952         };\r
1953 \r
1954         DecimalFormat nf = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);\r
1955         runStrictParseBatch(nf, pass, fail);\r
1956 \r
1957         String[] scientificPass = {\r
1958             "0E2",      // single zero before exponent is ok\r
1959             "1234E2",   // any number of digits before exponent is ok\r
1960             "1,234E",   // an exponent string not followed by zero or digits is not an exponent\r
1961         };\r
1962         String[] scientificFail = {\r
1963             "00E2",     // double zeros fail\r
1964             "1,234E2",  // group separators with exponent fail\r
1965         };\r
1966 \r
1967         nf = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);\r
1968         runStrictParseBatch(nf, scientificPass, scientificFail);\r
1969 \r
1970         String[] mixedPass = {\r
1971             "12,34,567",\r
1972             "12,34,567,",\r
1973             "12,34,567, that",\r
1974             "12,34,567 that",\r
1975         };\r
1976         String[] mixedFail = {\r
1977             "12,34,56",\r
1978             "12,34,56,",\r
1979             "12,34,56, that ",\r
1980             "12,34,56 that",\r
1981         };\r
1982 \r
1983         nf = new DecimalFormat("#,##,##0.#");\r
1984         runStrictParseBatch(nf, mixedPass, mixedFail);\r
1985     }\r
1986 \r
1987     void runStrictParseBatch(DecimalFormat nf, String[] pass, String[] fail) {\r
1988         nf.setParseStrict(false);\r
1989         runStrictParseTests("should pass", nf, pass, true);\r
1990         runStrictParseTests("should also pass", nf, fail, true);\r
1991         nf.setParseStrict(true);\r
1992         runStrictParseTests("should still pass", nf, pass, true);\r
1993         runStrictParseTests("should fail", nf, fail, false);\r
1994     }\r
1995 \r
1996     void runStrictParseTests(String msg, DecimalFormat nf, String[] tests, boolean pass) {\r
1997         logln("");\r
1998         logln("pattern: '" + nf.toPattern() + "'");\r
1999         logln(msg);\r
2000         for (int i = 0; i < tests.length; ++i) {\r
2001             String str = tests[i];\r
2002             ParsePosition pp = new ParsePosition(0);\r
2003             Number n = nf.parse(str, pp);\r
2004             String formatted = n != null ? nf.format(n) : "null";\r
2005             String err = pp.getErrorIndex() == -1 ? "" : "(error at " + pp.getErrorIndex() + ")";\r
2006             if ((err.length() == 0) != pass) {\r
2007                 errln("'" + str + "' parsed '" +\r
2008                       str.substring(0, pp.getIndex()) +\r
2009                       "' returned " + n + " formats to '" +\r
2010                       formatted + "' " + err);\r
2011             } else {\r
2012                 if (err.length() > 0) {\r
2013                     err = "got expected " + err;\r
2014                 }\r
2015                 logln("'" + str + "' parsed '" +\r
2016                       str.substring(0, pp.getIndex()) +\r
2017                       "' returned " + n + " formats to '" +\r
2018                       formatted + "' " + err);\r
2019             }\r
2020         }\r
2021     }\r
2022     public void TestJB5251(){\r
2023         //save default locale\r
2024         ULocale defaultLocale = ULocale.getDefault();\r
2025         ULocale.setDefault(new ULocale("qr_QR"));\r
2026         try {\r
2027             NumberFormat.getInstance();\r
2028         }\r
2029         catch (Exception e) {\r
2030             errln("Numberformat threw exception for non-existent locale. It should use the default.");\r
2031         }\r
2032         //reset default locale\r
2033         ULocale.setDefault(defaultLocale);\r
2034     }\r
2035 \r
2036     public void TestParseReturnType() {\r
2037         String[] defaultNonBigDecimals = {\r
2038             "123",      // Long\r
2039             "123.0",    // Long\r
2040             "0.0",      // Long\r
2041             "12345678901234567890"      // BigInteger\r
2042         };\r
2043 \r
2044         String[] doubles = {\r
2045             "-0.0",\r
2046             "NaN",\r
2047             "\u221E"    // Infinity\r
2048         };\r
2049 \r
2050         DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);\r
2051         DecimalFormat nf = new DecimalFormat("#.#", sym);\r
2052 \r
2053         if (nf.isParseBigDecimal()) {\r
2054             errln("FAIL: isParseDecimal() must return false by default");\r
2055         }\r
2056 \r
2057         // isParseBigDecimal() is false\r
2058         for (int i = 0; i < defaultNonBigDecimals.length; i++) {\r
2059             try {\r
2060                 Number n = nf.parse(defaultNonBigDecimals[i]);\r
2061                 if (n instanceof BigDecimal) {\r
2062                     errln("FAIL: parse returns BigDecimal instance");\r
2063                 }\r
2064             } catch (ParseException e) {\r
2065                 errln("parse of '" + defaultNonBigDecimals[i] + "' threw exception: " + e);\r
2066             }\r
2067         }\r
2068         // parse results for doubls must be always Double\r
2069         for (int i = 0; i < doubles.length; i++) {\r
2070             try {\r
2071                 Number n = nf.parse(doubles[i]);\r
2072                 if (!(n instanceof Double)) {\r
2073                     errln("FAIL: parse does not return Double instance");\r
2074                 }\r
2075             } catch (ParseException e) {\r
2076                 errln("parse of '" + doubles[i] + "' threw exception: " + e);\r
2077             }\r
2078         }\r
2079 \r
2080         // force this DecimalFormat to return BigDecimal\r
2081         nf.setParseBigDecimal(true);\r
2082         if (!nf.isParseBigDecimal()) {\r
2083             errln("FAIL: isParseBigDecimal() must return true");\r
2084         }\r
2085 \r
2086         // isParseBigDecimal() is true\r
2087         for (int i = 0; i < defaultNonBigDecimals.length; i++) {\r
2088             try {\r
2089                 Number n = nf.parse(defaultNonBigDecimals[i]);\r
2090                 if (!(n instanceof BigDecimal)) {\r
2091                     errln("FAIL: parse does not return BigDecimal instance");\r
2092                 }\r
2093             } catch (ParseException e) {\r
2094                 errln("parse of '" + defaultNonBigDecimals[i] + "' threw exception: " + e);\r
2095             }\r
2096         }\r
2097         // parse results for doubls must be always Double\r
2098         for (int i = 0; i < doubles.length; i++) {\r
2099             try {\r
2100                 Number n = nf.parse(doubles[i]);\r
2101                 if (!(n instanceof Double)) {\r
2102                     errln("FAIL: parse does not return Double instance");\r
2103                 }\r
2104             } catch (ParseException e) {\r
2105                 errln("parse of '" + doubles[i] + "' threw exception: " + e);\r
2106             }\r
2107         }\r
2108     }\r
2109 \r
2110     public void TestNonpositiveMultiplier() {\r
2111         DecimalFormat df = new DecimalFormat("0");\r
2112 \r
2113         // test zero multiplier\r
2114 \r
2115         try {\r
2116             df.setMultiplier(0);\r
2117 \r
2118             // bad\r
2119             errln("DecimalFormat.setMultiplier(0) did not throw an IllegalArgumentException");\r
2120         } catch (IllegalArgumentException ex) {\r
2121             // good\r
2122         }\r
2123 \r
2124         // test negative multiplier\r
2125 \r
2126         try {\r
2127             df.setMultiplier(-1);\r
2128 \r
2129             if (df.getMultiplier() != -1) {\r
2130                 errln("DecimalFormat.setMultiplier(-1) did not change the multiplier to -1");\r
2131                 return;\r
2132             }\r
2133 \r
2134             // good\r
2135         } catch (IllegalArgumentException ex) {\r
2136             // bad\r
2137             errln("DecimalFormat.setMultiplier(-1) threw an IllegalArgumentException");\r
2138             return;\r
2139         }\r
2140 \r
2141         expect(df, "1122.123", -1122.123);\r
2142         expect(df, "-1122.123", 1122.123);\r
2143         expect(df, "1.2", -1.2);\r
2144         expect(df, "-1.2", 1.2);\r
2145 \r
2146         expect2(df, Long.MAX_VALUE, BigInteger.valueOf(Long.MAX_VALUE).negate().toString());\r
2147         expect2(df, Long.MIN_VALUE, BigInteger.valueOf(Long.MIN_VALUE).negate().toString());\r
2148         expect2(df, Long.MAX_VALUE / 2, BigInteger.valueOf(Long.MAX_VALUE / 2).negate().toString());\r
2149         expect2(df, Long.MIN_VALUE / 2, BigInteger.valueOf(Long.MIN_VALUE / 2).negate().toString());\r
2150 \r
2151         expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());\r
2152         expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());\r
2153 \r
2154         expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());\r
2155         expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());\r
2156     }\r
2157 \r
2158     public void TestJB5358() {\r
2159         int numThreads = 10;\r
2160         String numstr = "12345";\r
2161         double expected = 12345;\r
2162         DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);\r
2163         DecimalFormat fmt = new DecimalFormat("#.#", sym);\r
2164         ArrayList errors = new ArrayList();\r
2165 \r
2166         ParseThreadJB5358[] threads = new ParseThreadJB5358[numThreads];\r
2167         for (int i = 0; i < numThreads; i++) {\r
2168             threads[i] = new ParseThreadJB5358((DecimalFormat)fmt.clone(), numstr, expected, errors);\r
2169             threads[i].start();\r
2170         }\r
2171         for (int i = 0; i < numThreads; i++) {\r
2172             try {\r
2173                 threads[i].join();\r
2174             } catch (InterruptedException ie) {\r
2175                 ie.printStackTrace();\r
2176             }\r
2177         }\r
2178         if (errors.size() != 0) {\r
2179             StringBuffer errBuf = new StringBuffer();\r
2180             for (int i = 0; i < errors.size(); i++) {\r
2181                 errBuf.append((String)errors.get(i));\r
2182                 errBuf.append("\n");\r
2183             }\r
2184             errln("FAIL: " + errBuf);\r
2185         }\r
2186     }\r
2187 \r
2188     static private class ParseThreadJB5358 extends Thread {\r
2189         private DecimalFormat decfmt;\r
2190         private String numstr;\r
2191         private double expect;\r
2192         private ArrayList errors;\r
2193 \r
2194         public ParseThreadJB5358(DecimalFormat decfmt, String numstr, double expect, ArrayList errors) {\r
2195             this.decfmt = decfmt;\r
2196             this.numstr = numstr;\r
2197             this.expect = expect;\r
2198             this.errors = errors;\r
2199         }\r
2200 \r
2201         public void run() {\r
2202             for (int i = 0; i < 10000; i++) {\r
2203                 try {\r
2204                     Number n = decfmt.parse(numstr);\r
2205                     if (n.doubleValue() != expect) {\r
2206                         synchronized(errors) {\r
2207                             errors.add(new String("Bad parse result - expected:" + expect + " actual:" + n.doubleValue()));\r
2208                         }\r
2209                     }\r
2210                 } catch (Throwable t) {\r
2211                     synchronized(errors) {\r
2212                         errors.add(new String(t.getClass().getName() + " - " + t.getMessage()));\r
2213                     }\r
2214                 }\r
2215             }\r
2216         }\r
2217     }\r
2218     \r
2219     public void TestSetCurrency() {\r
2220         DecimalFormatSymbols decf1 = DecimalFormatSymbols.getInstance(ULocale.US);\r
2221         DecimalFormatSymbols decf2 = DecimalFormatSymbols.getInstance(ULocale.US);\r
2222         decf2.setCurrencySymbol("UKD");\r
2223         DecimalFormat format1 = new DecimalFormat("000.000", decf1);\r
2224         DecimalFormat format2 = new DecimalFormat("000.000", decf2);\r
2225         Currency euro = Currency.getInstance("EUR");\r
2226         format1.setCurrency(euro);\r
2227         format2.setCurrency(euro);\r
2228         assertEquals("Reset with currency symbol", format1, format2);\r
2229     }\r
2230     \r
2231     /*\r
2232      * Testing the method public StringBuffer format(Object number, ...)\r
2233      */\r
2234     public void TestFormat() {\r
2235         NumberFormat nf = NumberFormat.getInstance();\r
2236         StringBuffer sb = new StringBuffer("dummy");\r
2237         FieldPosition fp = new FieldPosition(0);\r
2238 \r
2239         // Tests when "if (number instanceof Long)" is true\r
2240         try {\r
2241             nf.format((Object)new Long("0"), sb, fp);\r
2242         } catch (Exception e) {\r
2243             errln("NumberFormat.format(Object number, ...) was not suppose to "\r
2244                     + "return an exception for a Long object. Error: " + e);\r
2245         }\r
2246 \r
2247         // Tests when "else if (number instanceof BigInteger)" is true\r
2248         try {\r
2249             nf.format((Object)new BigInteger("0"), sb, fp);\r
2250         } catch (Exception e) {\r
2251             errln("NumberFormat.format(Object number, ...) was not suppose to "\r
2252                     + "return an exception for a BigInteger object. Error: " + e);\r
2253         }\r
2254 \r
2255         // Tests when "else if (number instanceof java.math.BigDecimal)" is true\r
2256         try {\r
2257             nf.format((Object)new java.math.BigDecimal("0"), sb, fp);\r
2258         } catch (Exception e) {\r
2259             errln("NumberFormat.format(Object number, ...) was not suppose to "\r
2260                     + "return an exception for a java.math.BigDecimal object. Error: " + e);\r
2261         }\r
2262 \r
2263         // Tests when "else if (number instanceof com.ibm.icu.math.BigDecimal)" is true\r
2264         try {\r
2265             nf.format((Object)new com.ibm.icu.math.BigDecimal("0"), sb, fp);\r
2266         } catch (Exception e) {\r
2267             errln("NumberFormat.format(Object number, ...) was not suppose to "\r
2268                     + "return an exception for a com.ibm.icu.math.BigDecimal object. Error: " + e);\r
2269         }\r
2270 \r
2271         // Tests when "else if (number instanceof CurrencyAmount)" is true\r
2272         try {\r
2273             CurrencyAmount ca = new CurrencyAmount(0.0, Currency.getInstance(new ULocale("en_US")));\r
2274             nf.format((Object)ca, sb, fp);\r
2275         } catch (Exception e) {\r
2276             errln("NumberFormat.format(Object number, ...) was not suppose to "\r
2277                     + "return an exception for a CurrencyAmount object. Error: " + e);\r
2278         }\r
2279 \r
2280         // Tests when "else if (number instanceof Number)" is true\r
2281         try {\r
2282             nf.format((Object)(Number) 0.0, sb, fp);\r
2283         } catch (Exception e) {\r
2284             errln("NumberFormat.format(Object number, ...) was not suppose to "\r
2285                     + "to return an exception for a Number object. Error: " + e);\r
2286         }\r
2287 \r
2288         // Tests when "else" is true\r
2289         try {\r
2290             nf.format(new Object(), sb, fp);\r
2291             errln("NumberFormat.format(Object number, ...) was suppose to "\r
2292                     + "return an exception for an invalid object.");\r
2293         } catch (Exception e) {\r
2294         }\r
2295 \r
2296         try {\r
2297             nf.format(new String("dummy"), sb, fp);\r
2298             errln("NumberFormat.format(Object number, ...) was suppose to "\r
2299                     + "return an exception for an invalid object.");\r
2300         } catch (Exception e) {\r
2301         }\r
2302     }\r
2303 \r
2304     /*\r
2305      * Tests the method public final static NumberFormat getInstance(int style) public static NumberFormat\r
2306      * getInstance(Locale inLocale, int style) public static NumberFormat getInstance(ULocale desiredLocale, int choice)\r
2307      */\r
2308     public void TestGetInstance() {\r
2309         // Tests "public final static NumberFormat getInstance(int style)"\r
2310 \r
2311         int[] invalid_cases = { NumberFormat.NUMBERSTYLE - 1, NumberFormat.NUMBERSTYLE - 2,\r
2312                 NumberFormat.PLURALCURRENCYSTYLE + 1, NumberFormat.PLURALCURRENCYSTYLE + 2 };\r
2313 \r
2314         for (int i = NumberFormat.NUMBERSTYLE; i < NumberFormat.PLURALCURRENCYSTYLE; i++) {\r
2315             try {\r
2316                 NumberFormat.getInstance(i);\r
2317             } catch (Exception e) {\r
2318                 errln("NumberFormat.getInstance(int style) was not suppose to "\r
2319                         + "return an exception for passing value of " + i);\r
2320             }\r
2321         }\r
2322 \r
2323         for (int i = 0; i < invalid_cases.length; i++) {\r
2324             try {\r
2325                 NumberFormat.getInstance(invalid_cases[i]);\r
2326                 errln("NumberFormat.getInstance(int style) was suppose to "\r
2327                         + "return an exception for passing value of " + invalid_cases[i]);\r
2328             } catch (Exception e) {\r
2329             }\r
2330         }\r
2331 \r
2332         // Tests "public static NumberFormat getInstance(Locale inLocale, int style)"\r
2333         String[] localeCases = { "en_US", "fr_FR", "de_DE", "jp_JP" };\r
2334 \r
2335         for (int i = NumberFormat.NUMBERSTYLE; i < NumberFormat.PLURALCURRENCYSTYLE; i++) {\r
2336             for (int j = 0; j < localeCases.length; j++) {\r
2337                 try {\r
2338                     NumberFormat.getInstance(new Locale(localeCases[j]), i);\r
2339                 } catch (Exception e) {\r
2340                     errln("NumberFormat.getInstance(Locale inLocale, int style) was not suppose to "\r
2341                             + "return an exception for passing value of " + localeCases[j] + ", " + i);\r
2342                 }\r
2343             }\r
2344         }\r
2345 \r
2346         // Tests "public static NumberFormat getInstance(ULocale desiredLocale, int choice)"\r
2347         // Tests when "if (choice < NUMBERSTYLE || choice > PLURALCURRENCYSTYLE)" is true\r
2348         for (int i = 0; i < invalid_cases.length; i++) {\r
2349             try {\r
2350                 NumberFormat.getInstance((ULocale) null, invalid_cases[i]);\r
2351                 errln("NumberFormat.getInstance(ULocale inLocale, int choice) was not suppose to "\r
2352                         + "return an exception for passing value of " + invalid_cases[i]);\r
2353             } catch (Exception e) {\r
2354             }\r
2355         }\r
2356     }\r
2357 \r
2358     /*\r
2359      * Tests the class public static abstract class NumberFormatFactory\r
2360      */\r
2361     public void TestNumberFormatFactory() {\r
2362         /*\r
2363          * The following class allows the method public NumberFormat createFormat(Locale loc, int formatType) to be\r
2364          * tested.\r
2365          */\r
2366         class TestFactory extends NumberFormatFactory {\r
2367             public Set<String> getSupportedLocaleNames() {\r
2368                 return null;\r
2369             }\r
2370 \r
2371             public NumberFormat createFormat(ULocale loc, int formatType) {\r
2372                 return null;\r
2373             }\r
2374         }\r
2375 \r
2376         /*\r
2377          * The following class allows the method public NumberFormat createFormat(ULocale loc, int formatType) to be\r
2378          * tested.\r
2379          */\r
2380         class TestFactory1 extends NumberFormatFactory {\r
2381             public Set<String> getSupportedLocaleNames() {\r
2382                 return null;\r
2383             }\r
2384 \r
2385             public NumberFormat createFormat(Locale loc, int formatType) {\r
2386                 return null;\r
2387             }\r
2388         }\r
2389 \r
2390         TestFactory tf = new TestFactory();\r
2391         TestFactory1 tf1 = new TestFactory1();\r
2392 \r
2393         /*\r
2394          * Tests the method public boolean visible()\r
2395          */\r
2396         if (tf.visible() != true) {\r
2397             errln("NumberFormatFactor.visible() was suppose to return true.");\r
2398         }\r
2399 \r
2400         /*\r
2401          * Tests the method public NumberFormat createFormat(Locale loc, int formatType)\r
2402          */\r
2403         if (tf.createFormat(new Locale(""), 0) != null) {\r
2404             errln("NumberFormatFactor.createFormat(Locale loc, int formatType) " + "was suppose to return null");\r
2405         }\r
2406 \r
2407         /*\r
2408          * Tests the method public NumberFormat createFormat(ULocale loc, int formatType)\r
2409          */\r
2410         if (tf1.createFormat(new ULocale(""), 0) != null) {\r
2411             errln("NumberFormatFactor.createFormat(ULocale loc, int formatType) " + "was suppose to return null");\r
2412         }\r
2413     }\r
2414 \r
2415     /*\r
2416      * Tests the class public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory\r
2417      */\r
2418     public void TestSimpleNumberFormatFactory() {\r
2419         class TestSimpleNumberFormatFactory extends SimpleNumberFormatFactory {\r
2420             /*\r
2421              * Tests the method public SimpleNumberFormatFactory(Locale locale)\r
2422              */\r
2423             TestSimpleNumberFormatFactory() {\r
2424                 super(new Locale(""));\r
2425             }\r
2426         }\r
2427         @SuppressWarnings("unused")\r
2428         TestSimpleNumberFormatFactory tsnff = new TestSimpleNumberFormatFactory();\r
2429     }\r
2430 \r
2431     /*\r
2432      * Tests the method public static ULocale[] getAvailableLocales()\r
2433      */\r
2434     @SuppressWarnings("static-access")\r
2435     public void TestGetAvailableLocales() {\r
2436         // Tests when "if (shim == null)" is true\r
2437         @SuppressWarnings("serial")\r
2438         class TestGetAvailableLocales extends NumberFormat {\r
2439             public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {\r
2440                 return null;\r
2441             }\r
2442 \r
2443             public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {\r
2444                 return null;\r
2445             }\r
2446 \r
2447             public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {\r
2448                 return null;\r
2449             }\r
2450 \r
2451             public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {\r
2452                 return null;\r
2453             }\r
2454 \r
2455             public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {\r
2456                 return null;\r
2457             }\r
2458 \r
2459             public Number parse(String text, ParsePosition parsePosition) {\r
2460                 return null;\r
2461             }\r
2462         }\r
2463 \r
2464         try {\r
2465             TestGetAvailableLocales test = new TestGetAvailableLocales();\r
2466             test.getAvailableLocales();\r
2467         } catch (Exception e) {\r
2468             errln("NumberFormat.getAvailableLocales() was not suppose to "\r
2469                     + "return an exception when getting getting available locales.");\r
2470         }\r
2471     }\r
2472 \r
2473     /*\r
2474      * Tests the method public void setMinimumIntegerDigits(int newValue)\r
2475      */\r
2476     public void TestSetMinimumIntegerDigits() {\r
2477         NumberFormat nf = NumberFormat.getInstance();\r
2478         // For valid array, it is displayed as {min value, max value}\r
2479         // Tests when "if (minimumIntegerDigits > maximumIntegerDigits)" is true\r
2480         int[][] cases = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 2, 0 }, { 2, 1 }, { 10, 0 } };\r
2481         int[] expectedMax = { 0, 1, 1, 2, 2, 10 };\r
2482         if (cases.length != expectedMax.length) {\r
2483             errln("Can't continue test case method TestSetMinimumIntegerDigits "\r
2484                     + "since the test case arrays are unequal.");\r
2485         } else {\r
2486             for (int i = 0; i < cases.length; i++) {\r
2487                 nf.setMaximumIntegerDigits(cases[i][1]);\r
2488                 nf.setMinimumIntegerDigits(cases[i][0]);\r
2489                 if (nf.getMaximumIntegerDigits() != expectedMax[i]) {\r
2490                     errln("NumberFormat.setMinimumIntegerDigits(int newValue "\r
2491                             + "did not return an expected result for parameter " + cases[i][1] + " and " + cases[i][0]\r
2492                             + " and expected " + expectedMax[i] + " but got " + nf.getMaximumIntegerDigits());\r
2493                 }\r
2494             }\r
2495         }\r
2496     }\r
2497 \r
2498     /*\r
2499      * Tests the method protected Currency getEffectiveCurrency()\r
2500      */\r
2501     public void TestGetEffectiveCurrency() {\r
2502         // TODO: Tests the method\r
2503     }\r
2504 \r
2505     /*\r
2506      * Tests the method public int getRoundingMode() public void setRoundingMode(int roundingMode)\r
2507      */\r
2508     public void TestRoundingMode() {\r
2509         @SuppressWarnings("serial")\r
2510         class TestRoundingMode extends NumberFormat {\r
2511             public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {\r
2512                 return null;\r
2513             }\r
2514 \r
2515             public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {\r
2516                 return null;\r
2517             }\r
2518 \r
2519             public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {\r
2520                 return null;\r
2521             }\r
2522 \r
2523             public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {\r
2524                 return null;\r
2525             }\r
2526 \r
2527             public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {\r
2528                 return null;\r
2529             }\r
2530 \r
2531             public Number parse(String text, ParsePosition parsePosition) {\r
2532                 return null;\r
2533             }\r
2534         }\r
2535         TestRoundingMode tgrm = new TestRoundingMode();\r
2536 \r
2537         // Tests the function 'public void setRoundingMode(int roundingMode)'\r
2538         try {\r
2539             tgrm.setRoundingMode(0);\r
2540             errln("NumberFormat.setRoundingMode(int) was suppose to return an exception");\r
2541         } catch (Exception e) {\r
2542         }\r
2543 \r
2544         // Tests the function 'public int getRoundingMode()'\r
2545         try {\r
2546             tgrm.getRoundingMode();\r
2547             errln("NumberFormat.getRoundingMode() was suppose to return an exception");\r
2548         } catch (Exception e) {\r
2549         }\r
2550     }\r
2551 \r
2552     /*\r
2553      * Testing lenient decimal/grouping separator parsing\r
2554      */\r
2555     public void TestLenientSymbolParsing() {\r
2556         DecimalFormat fmt = new DecimalFormat();\r
2557         DecimalFormatSymbols sym = new DecimalFormatSymbols();\r
2558 \r
2559         expect(fmt, "12\u300234", 12.34);\r
2560 \r
2561         // Ticket#7345 - case 1\r
2562         // Even strict parsing, the decimal separator set in the symbols\r
2563         // should be successfully parsed.\r
2564 \r
2565         sym.setDecimalSeparator('\u3002');\r
2566 \r
2567         // non-strict\r
2568         fmt.setDecimalFormatSymbols(sym);\r
2569 \r
2570         // strict - failed before the fix for #7345\r
2571         fmt.setParseStrict(true);\r
2572         expect(fmt, "23\u300245", 23.45);\r
2573         fmt.setParseStrict(false);\r
2574 \r
2575 \r
2576         // Ticket#7345 - case 2\r
2577         // Decimal separator variants other than DecimalFormatSymbols.decimalSeparator\r
2578         // should not hide the grouping separator DecimalFormatSymbols.groupingSeparator.\r
2579         sym.setDecimalSeparator('.');\r
2580         sym.setGroupingSeparator(',');\r
2581         fmt.setDecimalFormatSymbols(sym);\r
2582 \r
2583         expect(fmt, "1,234.56", 1234.56);\r
2584 \r
2585         sym.setGroupingSeparator('\uFF61');\r
2586         fmt.setDecimalFormatSymbols(sym);\r
2587 \r
2588         expect(fmt, "2\uFF61345.67", 2345.67);\r
2589 \r
2590         // Ticket#7218\r
2591         //\r
2592         // Lenient separator parsing is enabled by default.\r
2593         // A space character below is interpreted as a\r
2594         // group separator, even ',' is used as grouping\r
2595         // separator in the symbols.\r
2596         sym.setGroupingSeparator(',');\r
2597         fmt.setDecimalFormatSymbols(sym);\r
2598 \r
2599         expect(fmt, "12 345", 12345);\r
2600 \r
2601         // When the property SkipExtendedSeparatorParsing is true,\r
2602         // DecimalFormat does not use the extended equivalent separator\r
2603         // data and only uses the one in DecimalFormatSymbols.\r
2604         System.setProperty("com.ibm.icu.text.DecimalFormat.SkipExtendedSeparatorParsing", "true");\r
2605 \r
2606         expect(fmt, "23 456", 23);\r
2607 \r
2608         // Set the configuration back to the default\r
2609         System.setProperty("com.ibm.icu.text.DecimalFormat.SkipExtendedSeparatorParsing", "false");\r
2610     }\r
2611 }\r