2 *******************************************************************************
\r
3 * Copyright (C) 2001-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
9 * Port From: ICU4C v1.8.1 : format : NumberFormatTest
\r
10 * Source File: $ICU4CRoot/source/test/intltest/numfmtst.cpp
\r
13 package com.ibm.icu.dev.test.format;
\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
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
39 public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
\r
41 public static void main(String[] args) throws Exception {
\r
42 new NumberFormatTest().run(args);
\r
45 // Test various patterns
\r
46 public void TestPatterns() {
\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
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
61 String s = ((NumberFormat)fmt).format(0);
\r
62 if (!s.equals(num[i]))
\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
68 // BigInteger 0 - ticket#4731
\r
69 s = ((NumberFormat)fmt).format(BigInteger.ZERO);
\r
70 if (!s.equals(num[i]))
\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
79 // Test exponential pattern
\r
80 public void TestExponential() {
\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
86 double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
\r
87 int val_length = val.length;
\r
88 final String valFormat[] = {
\r
90 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
\r
92 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
\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
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
105 int lval[] = { 0, -1, 1, 123456789 };
\r
106 int lval_length = lval.length;
\r
107 final String lvalFormat[] = {
\r
109 "0E0", "-1E0", "1E0", "1.2346E8",
\r
111 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
\r
113 "0E000", "-1E000", "1E000", "123.4568E006",
\r
114 // 0.###E0;[0.###E0]
\r
115 "0E0", "[1E0]", "1E0", "1.235E8" };
\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
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
128 for (v = 0; v < val_length; ++v) {
\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
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
141 errln("FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
\r
143 for (v = 0; v < lval_length; ++v) {
\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
150 ParsePosition pos = new ParsePosition(0);
\r
152 Number A = fmt.parse(s, pos);
\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
160 errln("FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + Long.toString(a));
\r
162 errln("Fail to parse the string: " + s);
\r
165 ival += val_length;
\r
166 ilval += lval_length;
\r
170 // Test the handling of quotes
\r
171 public void TestQuotes() {
\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
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
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
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
208 * Test the handling of the currency symbol in patterns.
\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
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
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
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
241 public void TestSpaceParsing() {
\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
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
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
267 if (parsePosition.getErrorIndex() == -1 &&
\r
268 result.doubleValue() != 124) {
\r
269 errln("FAILED parse " + stringToBeParsed + "; value " + result.doubleValue());
\r
271 } catch (Exception e) {
\r
272 errln("FAILED " + e.toString());
\r
278 public void TestMultiCurrencySign() {
\r
279 String[][] DATA = {
\r
280 // the fields in the following test are:
\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
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
297 String doubleCurrencyStr = "\u00A4\u00A4";
\r
298 String tripleCurrencyStr = "\u00A4\u00A4\u00A4";
\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
308 pat = pat.replaceAll("\u00A4", doubleCurrencyStr);
\r
309 } else if (j == 3) {
\r
310 pat = pat.replaceAll("\u00A4\u00A4", tripleCurrencyStr);
\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
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
341 } catch (ParseException e) {
\r
342 errln("FAILED, DecimalFormat parse currency: " + e.toString());
\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
353 "US dollars1,234.56",
\r
354 "1,234.56 US dollars"
\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
364 if (!parsedVal.getCurrency().equals(Currency.getInstance("USD"))) {
\r
365 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the currency");
\r
368 } catch (ParseException e) {
\r
369 errln("parse FAILED: " + e.toString());
\r
373 public void TestDecimalFormatCurrencyParse() {
\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
383 // string to be parsed, the parsed result (number)
\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
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
400 } catch (ParseException e) {
\r
401 errln("FAILED, DecimalFormat parse currency: " + e.toString());
\r
406 * Test localized currency patterns.
\r
408 public void TestCurrency() {
\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
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
424 logln("FAIL: 1.50 x " + locale + " => " + s +
\r
425 ", expected " + DATA[i+3]);
\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
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
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
443 errln("FAIL: 1.50 x " + locale + " => " + sCurr +
\r
444 ", expected " + DATA[i+3]);
\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
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
460 if (!parsedVal.getCurrency().equals(Currency.getInstance("USD"))) {
\r
461 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the currency");
\r
464 catch (ParseException e) {
\r
465 errln("FAIL: " + e.getMessage());
\r
467 ULocale.setDefault(save);
\r
470 public void TestCurrencyIsoPluralFormat() {
\r
471 String[][] DATA = {
\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
498 for (int i=0; i<DATA.length; ++i) {
\r
499 for (int k = NumberFormat.CURRENCYSTYLE;
\r
500 k <= NumberFormat.PLURALCURRENCYSTYLE;
\r
502 // k represents currency format style.
\r
503 if ( k != NumberFormat.CURRENCYSTYLE &&
\r
504 k != NumberFormat.ISOCURRENCYSTYLE &&
\r
505 k != NumberFormat.PLURALCURRENCYSTYLE ) {
\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
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
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
541 catch (ParseException e) {
\r
542 errln("FAIL: " + e.getMessage());
\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
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
571 if (parsePosition.getErrorIndex() == -1 &&
\r
572 val.doubleValue() != 1.00) {
\r
573 errln("FAIL: parse failed. expected 1.00, actual:" + val);
\r
580 * Test the Currency object handling, new as of ICU 2.2.
\r
582 public void TestCurrencyObject() {
\r
584 NumberFormat.getCurrencyInstance(Locale.US);
\r
586 expectCurrency(fmt, null, 1234.56, "$1,234.56");
\r
588 expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),
\r
589 1234.56, "\u20AC1,234.56"); // Euro
\r
591 expectCurrency(fmt, Currency.getInstance(Locale.JAPAN),
\r
592 1234.56, "\u00A51,235"); // Yen
\r
594 expectCurrency(fmt, Currency.getInstance(new Locale("fr", "CH", "")),
\r
595 1234.56, "CHF1,234.55"); // 0.05 rounding
\r
597 expectCurrency(fmt, Currency.getInstance(Locale.US),
\r
598 1234.56, "$1,234.56");
\r
600 fmt = NumberFormat.getCurrencyInstance(Locale.FRANCE);
\r
602 expectCurrency(fmt, null, 1234.56, "1 234,56 \u20AC");
\r
604 expectCurrency(fmt, Currency.getInstance(Locale.JAPAN),
\r
605 1234.56, "1 235 \u00A5JP"); // Yen
\r
607 expectCurrency(fmt, Currency.getInstance(new Locale("fr", "CH", "")),
\r
608 1234.56, "1 234,55 CHF"); // 0.25 rounding
\r
610 expectCurrency(fmt, Currency.getInstance(Locale.US),
\r
611 1234.56, "1 234,56 $US");
\r
613 expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),
\r
614 1234.56, "1 234,56 \u20AC"); // Euro
\r
617 public void TestCurrencyPatterns() {
\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
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
632 "; x 1.125 => " + b);
\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
652 * Do rudimentary testing of parsing.
\r
654 public void TestParse() {
\r
655 String arg = "0.0";
\r
656 DecimalFormat format = new DecimalFormat("00");
\r
657 double aNumber = 0l;
\r
659 aNumber = format.parse(arg).doubleValue();
\r
660 } catch (ParseException e) {
\r
661 System.out.println(e);
\r
663 logln("parse(" + arg + ") = " + aNumber);
\r
667 * Test proper rounding by the format method.
\r
669 public void TestRounding487() {
\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
675 roundingTest(nf, 12.3995, 3, "12.4");
\r
677 roundingTest(nf, 12.4999, 0, "12");
\r
678 roundingTest(nf, - 19.5, 0, "-20");
\r
683 * Test the functioning of the secondary grouping value.
\r
685 public void TestSecondaryGrouping() {
\r
687 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
688 DecimalFormat f = new DecimalFormat("#,##,###", US);
\r
690 expect(f, 123456789L, "12,34,56,789");
\r
691 expectPat(f, "#,##,###");
\r
692 f.applyPattern("#,###");
\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
700 long l = 1876543210L;
\r
703 // expect "1,87,65,43,210", but with Hindi digits
\r
706 if (out.length() != 14) {
\r
709 for (int i = 0; i < out.length(); ++i) {
\r
710 boolean expectGroup = false;
\r
716 expectGroup = true;
\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
729 errln("FAIL Expected "+ l + " x hi_IN . \"1,87,65,43,210\" (with Hindi digits), got \""
\r
732 logln("Ok " + l + " x hi_IN . \"" + out + "\"");
\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
745 * Upgrade to alphaWorks
\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
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
759 * Upgrade to alphaWorks
\r
761 public void TestScientific() {
\r
763 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\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
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
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
783 errln("FAIL Pattern rt \"" + pat + "\" . \"" + pat2 + "\"");
\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
802 expect2(new DecimalFormat("#E0", US), 12345.0, "1.2345E4");
\r
803 expect(new DecimalFormat("0E0", US), 12345.0, "1E4");
\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
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
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
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
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
835 new Long(45678000),
\r
836 new String[] { "4.5678E7",
\r
845 ! Unroll this test into individual tests below...
\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
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
867 ! Unroll this test into individual tests below...
\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
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
885 ! Unroll this test into individual tests below...
\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
893 * Upgrade to alphaWorks
\r
895 public void TestPad() {
\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
901 new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US),
\r
903 "0.0E0______ g-m/s^2");
\r
905 new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US),
\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
910 new DecimalFormat("##0.0####*_ 'g-m/s^2'", US),
\r
912 "0.33333__ g-m/s^2");
\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
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
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
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
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
975 * Upgrade to alphaWorks
\r
977 public void TestPatterns2() {
\r
978 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
979 DecimalFormat fmt = new DecimalFormat("#", US);
\r
981 char hat = 0x005E; /*^*/
\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
993 fmt.applyPattern("AA#,##0.00ZZ");
\r
994 fmt.setPadCharacter(hat);
\r
996 fmt.setFormatWidth(10);
\r
998 fmt.setPadPosition(DecimalFormat.PAD_BEFORE_PREFIX);
\r
999 expectPat(fmt, "*^AA#,##0.00ZZ");
\r
1001 fmt.setPadPosition(DecimalFormat.PAD_BEFORE_SUFFIX);
\r
1002 expectPat(fmt, "AA#,##0.00*^ZZ");
\r
1004 fmt.setPadPosition(DecimalFormat.PAD_AFTER_SUFFIX);
\r
1005 expectPat(fmt, "AA#,##0.00ZZ*^");
\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
1013 fmt.setFormatWidth(13);
\r
1015 expectPat(fmt, "AA*^##,##0.00ZZ");
\r
1017 fmt.setFormatWidth(14);
\r
1018 // 12 345678901234
\r
1019 expectPat(fmt, "AA*^###,##0.00ZZ");
\r
1021 fmt.setFormatWidth(15);
\r
1022 // 12 3456789012345
\r
1023 expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
\r
1025 fmt.setFormatWidth(16);
\r
1026 // 12 34567890123456
\r
1027 expectPat(fmt, "AA*^#,###,##0.00ZZ");
\r
1030 public void TestRegistration() {
\r
1031 final ULocale SRC_LOC = ULocale.FRANCE;
\r
1032 final ULocale SWAP_LOC = ULocale.US;
\r
1034 class TestFactory extends SimpleNumberFormatFactory {
\r
1035 NumberFormat currencyStyle;
\r
1038 super(SRC_LOC, true);
\r
1039 currencyStyle = NumberFormat.getIntegerInstance(SWAP_LOC);
\r
1042 public NumberFormat createFormat(ULocale loc, int formatType) {
\r
1043 if (formatType == FORMAT_CURRENCY) {
\r
1044 return currencyStyle;
\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
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
1067 if (!f3.format(n).equals(f0.format(n))) {
\r
1068 errln("registered service did not match");
\r
1070 if (!f4.format(n).equals(f1.format(n))) {
\r
1071 errln("registered service did not inherit");
\r
1073 if (!f5.format(n).equals(f2.format(n))) {
\r
1074 errln("unregistered service did not match original");
\r
1078 public void TestScientific2() {
\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
1089 public void TestScientificGrouping() {
\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
1100 // additional coverage tests
\r
1102 // sigh, can't have static inner classes, why not?
\r
1104 static final class PI extends Number {
\r
1106 * For serialization
\r
1108 private static final long serialVersionUID = -305601227915602172L;
\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
1118 public static final Number INSTANCE = new PI();
\r
1121 public void TestCoverage() {
\r
1122 NumberFormat fmt = NumberFormat.getNumberInstance(); // default locale
\r
1123 logln(fmt.format(new BigInteger("1234567890987654321234567890987654321", 10)));
\r
1125 fmt = NumberFormat.getScientificInstance(); // default locale
\r
1127 logln(fmt.format(PI.INSTANCE));
\r
1130 logln(fmt.format("12345"));
\r
1131 errln("numberformat of string did not throw exception");
\r
1133 catch (Exception e) {
\r
1134 logln("PASS: numberformat of string failed as expected");
\r
1137 int hash = fmt.hashCode();
\r
1138 logln("hash code " + hash);
\r
1140 logln("compare to string returns: " + fmt.equals(""));
\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
1152 java.math.BigDecimal r = df.getRoundingIncrement();
\r
1154 errln("FAIL: rounding = " + r + ", expect null");
\r
1157 if (df.isScientificNotation()) {
\r
1158 errln("FAIL: isScientificNotation = true, expect false");
\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
1166 df.setMinimumExponentDigits((byte)2);
\r
1167 if (df.getMinimumExponentDigits() != 2) {
\r
1168 errln("FAIL: getMinimumExponentDigits = " +
\r
1169 df.getMinimumExponentDigits() + ", expect 2");
\r
1171 df.setExponentSignAlwaysShown(true);
\r
1172 if (!df.isExponentSignAlwaysShown()) {
\r
1173 errln("FAIL: isExponentSignAlwaysShown = false, expect true");
\r
1175 df.setSecondaryGroupingSize(0);
\r
1176 if (df.getSecondaryGroupingSize() != 0) {
\r
1177 errln("FAIL: getSecondaryGroupingSize = " +
\r
1178 df.getSecondaryGroupingSize() + ", expect 0");
\r
1180 expect2(df, 3.14159, "3.14159E+00");
\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
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
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
1201 logln("PASS: " + allLocales.length +
\r
1202 " available locales returned by DecimalFormatSymbols.getAvailableLocales");
\r
1204 ULocale[] allULocales = DecimalFormatSymbols.getAvailableULocales();
\r
1205 if (allULocales.length == 0) {
\r
1206 errln("FAIL: Got a empty list for DecimalFormatSymbols.getAvailableLocales");
\r
1208 logln("PASS: " + allULocales.length +
\r
1209 " available locales returned by DecimalFormatSymbols.getAvailableULocales");
\r
1213 public void TestWhiteSpaceParsing() {
\r
1214 DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
\r
1215 DecimalFormat fmt = new DecimalFormat("a b#0c ", US);
\r
1217 expect(fmt, "a b1234c ", n);
\r
1218 expect(fmt, "a b1234c ", n);
\r
1222 * Test currencies whose display name is a ChoiceFormat.
\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
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
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
1248 * Test alternate numbering systems
\r
1250 public void TestNumberingSystems() {
\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
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
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
1269 public void TestThreadedFormat() {
\r
1271 class FormatTask implements Runnable {
\r
1272 DecimalFormat fmt;
\r
1277 FormatTask(DecimalFormat fmt, int index) {
\r
1279 this.buf = new StringBuffer();
\r
1280 this.inc = (index & 0x1) == 0;
\r
1281 this.num = inc ? 0 : 10000;
\r
1284 public void run() {
\r
1286 while (num < 10000) {
\r
1287 buf.append(fmt.format(num) + "\n");
\r
1292 buf.append(fmt.format(num) + "\n");
\r
1299 return buf.toString();
\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
1309 TestUtil.runUntilDone(tasks);
\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
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
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
1339 public void TestIllegalPatterns() {
\r
1341 // Prefix with "-:" for illegal patterns
\r
1342 // Prefix with "+:" for legal patterns
\r
1344 // Unquoted special characters in the suffix are illegal
\r
1346 "+:000.000'|###'",
\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
1354 // locale doesn't matter here
\r
1355 new DecimalFormat(pat);
\r
1356 } catch (IllegalArgumentException e1) {
\r
1358 } catch (IndexOutOfBoundsException e1) {
\r
1361 String msg = (e==null) ? "success" : e.getMessage();
\r
1362 if ((e==null) == valid) {
\r
1363 logln("Ok: pattern \"" + pat + "\": " + msg);
\r
1365 errln("FAIL: pattern \"" + pat + "\" should have " +
\r
1366 (valid?"succeeded":"failed") + "; got " + msg);
\r
1372 * Parse a CurrencyAmount using the given NumberFormat, with
\r
1373 * the 'delim' character separating the number and the currency.
\r
1375 private static CurrencyAmount parseCurrencyAmount(String str, NumberFormat fmt,
\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
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
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
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
1411 public void TestCases() {
\r
1412 String caseFileName = "NumberFormatTestCases.txt";
\r
1413 java.io.InputStream is = NumberFormatTest.class.getResourceAsStream(caseFileName);
\r
1415 ResourceReader reader = new ResourceReader(is, caseFileName, "utf-8");
\r
1416 TokenIterator tokens = new TokenIterator(reader);
\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
1426 String tok = tokens.next();
\r
1427 if (tok == null) {
\r
1430 String where = "(" + tokens.getLineNumber() + ") ";
\r
1431 int cmd = keywordIndex(tok);
\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
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
1450 tok = tokens.next();
\r
1451 if (!tok.equals("-")) {
\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
1462 if (cmd == 3) tokens.next();
\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
1479 if (cmd != 2) { // != f:
\r
1480 assertEquals(where + '"' + pat + "\".parse(\"" + str + "\")",
\r
1481 n, fmt.parse(str));
\r
1484 // p: <pattern or '-'> <string to parse> <exp. number>
\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
1493 } catch (ParseException e) {
\r
1494 errln(where + '"' + pat + "\".parse(\"" + str +
\r
1495 "\") threw an exception");
\r
1496 e.printStackTrace();
\r
1500 // perr: <pattern or '-'> <invalid string>
\r
1501 errln("Under construction");
\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
1510 errln("Invalid command \"pat: - err\" at " + tokens.describePosition());
\r
1515 if (exppat.equals("-")) exppat = testpat;
\r
1517 DecimalFormat f = null;
\r
1518 if (testpat == pat) { // [sic]
\r
1521 f = new DecimalFormat(testpat);
\r
1522 f.setParseStrict(strict);
\r
1525 errln(where + "Invalid pattern \"" + testpat +
\r
1526 "\" was accepted");
\r
1528 assertEquals(where + '"' + testpat + "\".toPattern()",
\r
1529 exppat, f.toPattern());
\r
1531 } catch (IllegalArgumentException iae2) {
\r
1533 logln("Ok: " + where + "Invalid pattern \"" + testpat +
\r
1534 "\" threw an exception");
\r
1536 errln(where + "Valid pattern \"" + testpat +
\r
1537 "\" threw an exception");
\r
1538 iae2.printStackTrace();
\r
1543 tok = tokens.next();
\r
1544 if (!tok.equals("-")) {
\r
1546 ULocale l = new ULocale(mloc);
\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
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
1577 case 9: // strict= true or false
\r
1578 strict = "true".equalsIgnoreCase(tokens.next());
\r
1579 logln("Setting strict to:\t" + strict);
\r
1582 errln("Unknown command \"" + tok + "\" at " + tokens.describePosition());
\r
1586 } catch (java.io.IOException e) {
\r
1587 throw new RuntimeException(e);
\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
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
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
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
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
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
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
1652 lastParsed = parsed;
\r
1653 } catch (ParseException e) {
\r
1654 errln("Parse Failure with: " + formatedBigDecimal);
\r
1656 return lastParsed;
\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
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
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
1679 private static String stripFinalZeros(String formatted) {
\r
1680 int len1 = formatted.length();
\r
1682 while (len1 > 0 && ((ch = formatted.charAt(len1-1)) == '0' || ch == '.')) --len1;
\r
1683 return formatted.substring(0,len1);
\r
1686 //------------------------------------------------------------------
\r
1687 // Support methods
\r
1688 //------------------------------------------------------------------
\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
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
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
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
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
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
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
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
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
1743 } catch (ParseException e) {
\r
1744 errln(e.getMessage());
\r
1749 errln("FAIL " + n + " x " +
\r
1751 saw + "\", expected \"" + exp + "\"");
\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
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
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
1774 } catch (ParseException e) {
\r
1775 errln(e.getMessage());
\r
1780 errln("FAIL " + n + " = \"" +
\r
1781 saw + "\", expected \"" + exp + "\"");
\r
1785 // Format test (convenience)
\r
1786 public void expect(NumberFormat fmt, Number n, String exp) {
\r
1787 expect(fmt, n, exp, true);
\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
1795 // Format test (convenience)
\r
1796 public void expect(NumberFormat fmt, long n, String exp) {
\r
1797 expect(fmt, new Long(n), exp);
\r
1801 public void expect(NumberFormat fmt, String str, Number n) {
\r
1802 Number num = null;
\r
1804 num = (Number) fmt.parse(str);
\r
1805 } catch (ParseException e) {
\r
1806 errln(e.getMessage());
\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
1817 errln("FAIL \"" + str + "\" x " +
\r
1819 num + ", expected " + n);
\r
1824 public void expect_rbnf(NumberFormat fmt, String str, Number n) {
\r
1825 Number num = null;
\r
1827 num = (Number) fmt.parse(str);
\r
1828 } catch (ParseException e) {
\r
1829 errln(e.getMessage());
\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
1838 errln("FAIL \"" + str + " = " +
\r
1839 num + ", expected " + n);
\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
1848 // Parse test (convenience)
\r
1849 public void expect(NumberFormat fmt, String str, long n) {
\r
1850 expect(fmt, str, new Long(n));
\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
1859 String s = fmt.format(value).replace('\u00A0', ' ');
\r
1861 if (s.equals(string)) {
\r
1862 logln("Ok: " + value + " x " + curr + " => " + s);
\r
1864 errln("FAIL: " + value + " x " + curr + " => " + s +
\r
1865 ", expected " + string);
\r
1869 public void expectPad(DecimalFormat fmt, String pat, int pos) {
\r
1870 expectPad(fmt, pat, pos, 0, (char)0);
\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
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
1887 if (apos == pos && awidth == width && apadStr == pad) {
\r
1888 logln("Ok \"" + pat + "\" pos="
\r
1889 + apos + ((pos == -1) ? "" : " width=" + awidth + " pad=" + apadStr));
\r
1891 errln("FAIL \"" + pat + "\" pos=" + apos + " width="
\r
1892 + awidth + " pad=" + apadStr + ", expected "
\r
1893 + pos + " " + width + " " + pad);
\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
1902 errln("FAIL \"" + pat + "\", expected \"" + exp + "\"");
\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
1920 public void TestStrictParse() {
\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
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
1954 DecimalFormat nf = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
\r
1955 runStrictParseBatch(nf, pass, fail);
\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
1962 String[] scientificFail = {
\r
1963 "00E2", // double zeros fail
\r
1964 "1,234E2", // group separators with exponent fail
\r
1967 nf = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
\r
1968 runStrictParseBatch(nf, scientificPass, scientificFail);
\r
1970 String[] mixedPass = {
\r
1973 "12,34,567, that",
\r
1976 String[] mixedFail = {
\r
1979 "12,34,56, that ",
\r
1983 nf = new DecimalFormat("#,##,##0.#");
\r
1984 runStrictParseBatch(nf, mixedPass, mixedFail);
\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
1996 void runStrictParseTests(String msg, DecimalFormat nf, String[] tests, boolean pass) {
\r
1998 logln("pattern: '" + nf.toPattern() + "'");
\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
2012 if (err.length() > 0) {
\r
2013 err = "got expected " + err;
\r
2015 logln("'" + str + "' parsed '" +
\r
2016 str.substring(0, pp.getIndex()) +
\r
2017 "' returned " + n + " formats to '" +
\r
2018 formatted + "' " + err);
\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
2027 NumberFormat.getInstance();
\r
2029 catch (Exception e) {
\r
2030 errln("Numberformat threw exception for non-existent locale. It should use the default.");
\r
2032 //reset default locale
\r
2033 ULocale.setDefault(defaultLocale);
\r
2036 public void TestParseReturnType() {
\r
2037 String[] defaultNonBigDecimals = {
\r
2041 "12345678901234567890" // BigInteger
\r
2044 String[] doubles = {
\r
2047 "\u221E" // Infinity
\r
2050 DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
\r
2051 DecimalFormat nf = new DecimalFormat("#.#", sym);
\r
2053 if (nf.isParseBigDecimal()) {
\r
2054 errln("FAIL: isParseDecimal() must return false by default");
\r
2057 // isParseBigDecimal() is false
\r
2058 for (int i = 0; i < defaultNonBigDecimals.length; i++) {
\r
2060 Number n = nf.parse(defaultNonBigDecimals[i]);
\r
2061 if (n instanceof BigDecimal) {
\r
2062 errln("FAIL: parse returns BigDecimal instance");
\r
2064 } catch (ParseException e) {
\r
2065 errln("parse of '" + defaultNonBigDecimals[i] + "' threw exception: " + e);
\r
2068 // parse results for doubls must be always Double
\r
2069 for (int i = 0; i < doubles.length; i++) {
\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
2075 } catch (ParseException e) {
\r
2076 errln("parse of '" + doubles[i] + "' threw exception: " + e);
\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
2086 // isParseBigDecimal() is true
\r
2087 for (int i = 0; i < defaultNonBigDecimals.length; i++) {
\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
2093 } catch (ParseException e) {
\r
2094 errln("parse of '" + defaultNonBigDecimals[i] + "' threw exception: " + e);
\r
2097 // parse results for doubls must be always Double
\r
2098 for (int i = 0; i < doubles.length; i++) {
\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
2104 } catch (ParseException e) {
\r
2105 errln("parse of '" + doubles[i] + "' threw exception: " + e);
\r
2110 public void TestNonpositiveMultiplier() {
\r
2111 DecimalFormat df = new DecimalFormat("0");
\r
2113 // test zero multiplier
\r
2116 df.setMultiplier(0);
\r
2119 errln("DecimalFormat.setMultiplier(0) did not throw an IllegalArgumentException");
\r
2120 } catch (IllegalArgumentException ex) {
\r
2124 // test negative multiplier
\r
2127 df.setMultiplier(-1);
\r
2129 if (df.getMultiplier() != -1) {
\r
2130 errln("DecimalFormat.setMultiplier(-1) did not change the multiplier to -1");
\r
2135 } catch (IllegalArgumentException ex) {
\r
2137 errln("DecimalFormat.setMultiplier(-1) threw an IllegalArgumentException");
\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
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
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
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
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
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
2171 for (int i = 0; i < numThreads; i++) {
\r
2173 threads[i].join();
\r
2174 } catch (InterruptedException ie) {
\r
2175 ie.printStackTrace();
\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
2184 errln("FAIL: " + errBuf);
\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
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
2201 public void run() {
\r
2202 for (int i = 0; i < 10000; i++) {
\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
2210 } catch (Throwable t) {
\r
2211 synchronized(errors) {
\r
2212 errors.add(new String(t.getClass().getName() + " - " + t.getMessage()));
\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
2232 * Testing the method public StringBuffer format(Object number, ...)
\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
2239 // Tests when "if (number instanceof Long)" is true
\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
2247 // Tests when "else if (number instanceof BigInteger)" is true
\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
2255 // Tests when "else if (number instanceof java.math.BigDecimal)" is true
\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
2263 // Tests when "else if (number instanceof com.ibm.icu.math.BigDecimal)" is true
\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
2271 // Tests when "else if (number instanceof CurrencyAmount)" is true
\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
2280 // Tests when "else if (number instanceof Number)" is true
\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
2288 // Tests when "else" is true
\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
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
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
2308 public void TestGetInstance() {
\r
2309 // Tests "public final static NumberFormat getInstance(int style)"
\r
2311 int[] invalid_cases = { NumberFormat.NUMBERSTYLE - 1, NumberFormat.NUMBERSTYLE - 2,
\r
2312 NumberFormat.PLURALCURRENCYSTYLE + 1, NumberFormat.PLURALCURRENCYSTYLE + 2 };
\r
2314 for (int i = NumberFormat.NUMBERSTYLE; i < NumberFormat.PLURALCURRENCYSTYLE; i++) {
\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
2323 for (int i = 0; i < invalid_cases.length; i++) {
\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
2332 // Tests "public static NumberFormat getInstance(Locale inLocale, int style)"
\r
2333 String[] localeCases = { "en_US", "fr_FR", "de_DE", "jp_JP" };
\r
2335 for (int i = NumberFormat.NUMBERSTYLE; i < NumberFormat.PLURALCURRENCYSTYLE; i++) {
\r
2336 for (int j = 0; j < localeCases.length; j++) {
\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
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
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
2359 * Tests the class public static abstract class NumberFormatFactory
\r
2361 public void TestNumberFormatFactory() {
\r
2363 * The following class allows the method public NumberFormat createFormat(Locale loc, int formatType) to be
\r
2366 class TestFactory extends NumberFormatFactory {
\r
2367 public Set<String> getSupportedLocaleNames() {
\r
2371 public NumberFormat createFormat(ULocale loc, int formatType) {
\r
2377 * The following class allows the method public NumberFormat createFormat(ULocale loc, int formatType) to be
\r
2380 class TestFactory1 extends NumberFormatFactory {
\r
2381 public Set<String> getSupportedLocaleNames() {
\r
2385 public NumberFormat createFormat(Locale loc, int formatType) {
\r
2390 TestFactory tf = new TestFactory();
\r
2391 TestFactory1 tf1 = new TestFactory1();
\r
2394 * Tests the method public boolean visible()
\r
2396 if (tf.visible() != true) {
\r
2397 errln("NumberFormatFactor.visible() was suppose to return true.");
\r
2401 * Tests the method public NumberFormat createFormat(Locale loc, int formatType)
\r
2403 if (tf.createFormat(new Locale(""), 0) != null) {
\r
2404 errln("NumberFormatFactor.createFormat(Locale loc, int formatType) " + "was suppose to return null");
\r
2408 * Tests the method public NumberFormat createFormat(ULocale loc, int formatType)
\r
2410 if (tf1.createFormat(new ULocale(""), 0) != null) {
\r
2411 errln("NumberFormatFactor.createFormat(ULocale loc, int formatType) " + "was suppose to return null");
\r
2416 * Tests the class public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory
\r
2418 public void TestSimpleNumberFormatFactory() {
\r
2419 class TestSimpleNumberFormatFactory extends SimpleNumberFormatFactory {
\r
2421 * Tests the method public SimpleNumberFormatFactory(Locale locale)
\r
2423 TestSimpleNumberFormatFactory() {
\r
2424 super(new Locale(""));
\r
2427 @SuppressWarnings("unused")
\r
2428 TestSimpleNumberFormatFactory tsnff = new TestSimpleNumberFormatFactory();
\r
2432 * Tests the method public static ULocale[] getAvailableLocales()
\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
2443 public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
\r
2447 public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {
\r
2451 public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
\r
2455 public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
\r
2459 public Number parse(String text, ParsePosition parsePosition) {
\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
2474 * Tests the method public void setMinimumIntegerDigits(int newValue)
\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
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
2499 * Tests the method protected Currency getEffectiveCurrency()
\r
2501 public void TestGetEffectiveCurrency() {
\r
2502 // TODO: Tests the method
\r
2506 * Tests the method public int getRoundingMode() public void setRoundingMode(int roundingMode)
\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
2515 public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
\r
2519 public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {
\r
2523 public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
\r
2527 public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
\r
2531 public Number parse(String text, ParsePosition parsePosition) {
\r
2535 TestRoundingMode tgrm = new TestRoundingMode();
\r
2537 // Tests the function 'public void setRoundingMode(int roundingMode)'
\r
2539 tgrm.setRoundingMode(0);
\r
2540 errln("NumberFormat.setRoundingMode(int) was suppose to return an exception");
\r
2541 } catch (Exception e) {
\r
2544 // Tests the function 'public int getRoundingMode()'
\r
2546 tgrm.getRoundingMode();
\r
2547 errln("NumberFormat.getRoundingMode() was suppose to return an exception");
\r
2548 } catch (Exception e) {
\r
2553 * Testing lenient decimal/grouping separator parsing
\r
2555 public void TestLenientSymbolParsing() {
\r
2556 DecimalFormat fmt = new DecimalFormat();
\r
2557 DecimalFormatSymbols sym = new DecimalFormatSymbols();
\r
2559 expect(fmt, "12\u300234", 12.34);
\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
2565 sym.setDecimalSeparator('\u3002');
\r
2568 fmt.setDecimalFormatSymbols(sym);
\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
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
2583 expect(fmt, "1,234.56", 1234.56);
\r
2585 sym.setGroupingSeparator('\uFF61');
\r
2586 fmt.setDecimalFormatSymbols(sym);
\r
2588 expect(fmt, "2\uFF61345.67", 2345.67);
\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
2599 expect(fmt, "12 345", 12345);
\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
2606 expect(fmt, "23 456", 23);
\r
2608 // Set the configuration back to the default
\r
2609 System.setProperty("com.ibm.icu.text.DecimalFormat.SkipExtendedSeparatorParsing", "false");
\r