0001: //##header
0002: /*
0003: *******************************************************************************
0004: * Copyright (C) 2001-2006, International Business Machines Corporation and *
0005: * others. All Rights Reserved. *
0006: *******************************************************************************
0007: */
0008:
0009: /**
0010: * Port From: ICU4C v1.8.1 : format : NumberFormatTest
0011: * Source File: $ICU4CRoot/source/test/intltest/numfmtst.cpp
0012: **/package com.ibm.icu.dev.test.format;
0013:
0014: import com.ibm.icu.dev.test.TestUtil;
0015: import com.ibm.icu.text.*;
0016: import com.ibm.icu.text.NumberFormat.*;
0017: import com.ibm.icu.util.*;
0018: import com.ibm.icu.impl.LocaleUtility;
0019: import com.ibm.icu.impl.data.ResourceReader;
0020: import com.ibm.icu.impl.data.TokenIterator;
0021: import com.ibm.icu.math.BigDecimal;
0022:
0023: import java.math.BigInteger;
0024: import java.text.FieldPosition;
0025: import java.text.ParsePosition;
0026: import java.text.ParseException;
0027: import java.util.Locale;
0028: import java.util.ArrayList;
0029:
0030: public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
0031: private static final char EURO = '\u20ac';
0032:
0033: public static void main(String[] args) throws Exception {
0034: new NumberFormatTest().run(args);
0035: }
0036:
0037: // Test various patterns
0038: public void TestPatterns() {
0039:
0040: DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
0041: final String pat[] = { "#.#", "#.", ".#", "#" };
0042: int pat_length = pat.length;
0043: final String newpat[] = { "#0.#", "#0.", "#.0", "#" };
0044: final String num[] = { "0", "0.", ".0", "0" };
0045: for (int i = 0; i < pat_length; ++i) {
0046: DecimalFormat fmt = new DecimalFormat(pat[i], sym);
0047: String newp = fmt.toPattern();
0048: if (!newp.equals(newpat[i]))
0049: errln("FAIL: Pattern " + pat[i]
0050: + " should transmute to " + newpat[i] + "; "
0051: + newp + " seen instead");
0052:
0053: String s = ((NumberFormat) fmt).format(0);
0054: if (!s.equals(num[i])) {
0055: errln("FAIL: Pattern " + pat[i]
0056: + " should format zero as " + num[i] + "; " + s
0057: + " seen instead");
0058: logln("Min integer digits = "
0059: + fmt.getMinimumIntegerDigits());
0060: }
0061: }
0062: }
0063:
0064: // Test exponential pattern
0065: public void TestExponential() {
0066:
0067: DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
0068: final String pat[] = { "0.####E0", "00.000E00",
0069: "##0.######E000", "0.###E0;[0.###E0]" };
0070: int pat_length = pat.length;
0071:
0072: double val[] = { 0.01234, 123456789, 1.23e300,
0073: -3.141592653e-271 };
0074: int val_length = val.length;
0075: final String valFormat[] = {
0076: // 0.####E0
0077: "1.234E-2", "1.2346E8", "1.23E300",
0078: "-3.1416E-271",
0079: // 00.000E00
0080: "12.340E-03", "12.346E07", "12.300E299",
0081: "-31.416E-272",
0082: // ##0.######E000
0083: "12.34E-003", "123.4568E006", "1.23E300",
0084: "-314.1593E-273",
0085: // 0.###E0;[0.###E0]
0086: "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]" };
0087: /*double valParse[] =
0088: {
0089: 0.01234, 123460000, 1.23E300, -3.1416E-271,
0090: 0.01234, 123460000, 1.23E300, -3.1416E-271,
0091: 0.01234, 123456800, 1.23E300, -3.141593E-271,
0092: 0.01234, 123500000, 1.23E300, -3.142E-271,
0093: };*///The variable is never used
0094: int lval[] = { 0, -1, 1, 123456789 };
0095: int lval_length = lval.length;
0096: final String lvalFormat[] = {
0097: // 0.####E0
0098: "0E0", "-1E0", "1E0", "1.2346E8",
0099: // 00.000E00
0100: "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
0101: // ##0.######E000
0102: "0E000", "-1E000", "1E000", "123.4568E006",
0103: // 0.###E0;[0.###E0]
0104: "0E0", "[1E0]", "1E0", "1.235E8" };
0105: int lvalParse[] = { 0, -1, 1, 123460000, 0, -1, 1, 123460000,
0106: 0, -1, 1, 123456800, 0, -1, 1, 123500000, };
0107: int ival = 0, ilval = 0;
0108: for (int p = 0; p < pat_length; ++p) {
0109: DecimalFormat fmt = new DecimalFormat(pat[p], sym);
0110: logln("Pattern \"" + pat[p] + "\" -toPattern-> \""
0111: + fmt.toPattern() + "\"");
0112: int v;
0113: for (v = 0; v < val_length; ++v) {
0114: String s;
0115: s = ((NumberFormat) fmt).format(val[v]);
0116: logln(" " + val[v] + " -format-> " + s);
0117: if (!s.equals(valFormat[v + ival]))
0118: errln("FAIL: Expected " + valFormat[v + ival]);
0119:
0120: ParsePosition pos = new ParsePosition(0);
0121: double a = fmt.parse(s, pos).doubleValue();
0122: if (pos.getIndex() == s.length()) {
0123: logln(" -parse-> " + Double.toString(a));
0124: // Use epsilon comparison as necessary
0125: } else
0126: errln("FAIL: Partial parse (" + pos.getIndex()
0127: + " chars) -> " + a);
0128: }
0129: for (v = 0; v < lval_length; ++v) {
0130: String s;
0131: s = ((NumberFormat) fmt).format(lval[v]);
0132: logln(" " + lval[v] + "L -format-> " + s);
0133: if (!s.equals(lvalFormat[v + ilval]))
0134: errln("ERROR: Expected " + lvalFormat[v + ilval]
0135: + " Got: " + s);
0136:
0137: ParsePosition pos = new ParsePosition(0);
0138: long a = 0;
0139: Number A = fmt.parse(s, pos);
0140: if (A != null) {
0141: a = A.longValue();
0142: if (pos.getIndex() == s.length()) {
0143: logln(" -parse-> " + a);
0144: if (a != lvalParse[v + ilval])
0145: errln("FAIL: Expected "
0146: + lvalParse[v + ilval]);
0147: } else
0148: errln("FAIL: Partial parse (" + pos.getIndex()
0149: + " chars) -> " + Long.toString(a));
0150: } else {
0151: errln("Fail to parse the string: " + s);
0152: }
0153: }
0154: ival += val_length;
0155: ilval += lval_length;
0156: }
0157: }
0158:
0159: // Test the handling of quotes
0160: public void TestQuotes() {
0161:
0162: StringBuffer pat;
0163: DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
0164: pat = new StringBuffer("a'fo''o'b#");
0165: DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);
0166: String s = ((NumberFormat) fmt).format(123);
0167: logln("Pattern \"" + pat + "\"");
0168: logln(" Format 123 . " + s);
0169: if (!s.equals("afo'ob123"))
0170: errln("FAIL: Expected afo'ob123");
0171:
0172: s = "";
0173: pat = new StringBuffer("a''b#");
0174: fmt = new DecimalFormat(pat.toString(), sym);
0175: s = ((NumberFormat) fmt).format(123);
0176: logln("Pattern \"" + pat + "\"");
0177: logln(" Format 123 . " + s);
0178: if (!s.equals("a'b123"))
0179: errln("FAIL: Expected a'b123");
0180: }
0181:
0182: public void TestParseCurrencyTrailingSymbol() {
0183: // see sun bug 4709840
0184: NumberFormat fmt = NumberFormat
0185: .getCurrencyInstance(Locale.GERMANY);
0186: float val = 12345.67f;
0187: String str = fmt.format(val);
0188: logln("val: " + val + " str: " + str);
0189: try {
0190: Number num = fmt.parse(str);
0191: logln("num: " + num);
0192: } catch (ParseException e) {
0193: errln("parse of '" + str + "' threw exception: " + e);
0194: }
0195: }
0196:
0197: /**
0198: * Test the handling of the currency symbol in patterns.
0199: **/
0200: public void TestCurrencySign() {
0201: DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
0202: StringBuffer pat = new StringBuffer("");
0203: char currency = 0x00A4;
0204: // "\xA4#,##0.00;-\xA4#,##0.00"
0205: pat.append(currency).append("#,##0.00;-").append(currency)
0206: .append("#,##0.00");
0207: DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);
0208: String s = ((NumberFormat) fmt).format(1234.56);
0209: pat = new StringBuffer("");
0210: logln("Pattern \"" + fmt.toPattern() + "\"");
0211: logln(" Format " + 1234.56 + " . " + s);
0212: if (!s.equals("$1,234.56"))
0213: errln("FAIL: Expected $1,234.56");
0214: s = "";
0215: s = ((NumberFormat) fmt).format(-1234.56);
0216: logln(" Format " + Double.toString(-1234.56) + " . " + s);
0217: if (!s.equals("-$1,234.56"))
0218: errln("FAIL: Expected -$1,234.56");
0219:
0220: pat = new StringBuffer("");
0221: // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
0222: pat.append(currency).append(currency).append(" #,##0.00;")
0223: .append(currency).append(currency).append(" -#,##0.00");
0224: fmt = new DecimalFormat(pat.toString(), sym);
0225: s = "";
0226: s = ((NumberFormat) fmt).format(1234.56);
0227: logln("Pattern \"" + fmt.toPattern() + "\"");
0228: logln(" Format " + Double.toString(1234.56) + " . " + s);
0229:
0230: if (!s.equals("USD 1,234.56"))
0231: errln("FAIL: Expected USD 1,234.56");
0232: s = "";
0233: s = ((NumberFormat) fmt).format(-1234.56);
0234: logln(" Format " + Double.toString(-1234.56) + " . " + s);
0235: if (!s.equals("USD -1,234.56"))
0236: errln("FAIL: Expected USD -1,234.56");
0237:
0238: }
0239:
0240: /**
0241: * Test localized currency patterns.
0242: */
0243: public void TestCurrency() {
0244: String[] DATA = { "fr", "CA", "", "1,50 $", "de", "DE", "",
0245: "1,50 \u20AC", "de", "DE", "PREEURO", "1,50 DM", "fr",
0246: "FR", "", "1,50 \u20AC", "fr", "FR", "PREEURO",
0247: "1,50 F", };
0248:
0249: for (int i = 0; i < DATA.length; i += 4) {
0250: Locale locale = new Locale(DATA[i], DATA[i + 1],
0251: DATA[i + 2]);
0252: NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
0253: String s = fmt.format(1.50);
0254: if (s.equals(DATA[i + 3])) {
0255: logln("Ok: 1.50 x " + locale + " => " + s);
0256: } else {
0257: logln("FAIL: 1.50 x " + locale + " => " + s
0258: + ", expected " + DATA[i + 3]);
0259: }
0260: }
0261:
0262: // format currency with CurrencyAmount
0263: for (int i = 0; i < DATA.length; i += 4) {
0264: Locale locale = new Locale(DATA[i], DATA[i + 1],
0265: DATA[i + 2]);
0266:
0267: Currency curr = Currency.getInstance(locale);
0268: logln("\nName of the currency is: "
0269: + curr.getName(locale, Currency.LONG_NAME,
0270: new boolean[] { false }));
0271: CurrencyAmount cAmt = new CurrencyAmount(1.5, curr);
0272: logln("CurrencyAmount object's hashCode is: "
0273: + cAmt.hashCode()); //cover hashCode
0274:
0275: NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
0276: String sCurr = fmt.format(cAmt);
0277: if (sCurr.equals(DATA[i + 3])) {
0278: logln("Ok: 1.50 x " + locale + " => " + sCurr);
0279: } else {
0280: errln("FAIL: 1.50 x " + locale + " => " + sCurr
0281: + ", expected " + DATA[i + 3]);
0282: }
0283: }
0284:
0285: //Cover MeasureFormat.getCurrencyFormat()
0286: ULocale save = ULocale.getDefault();
0287: ULocale.setDefault(ULocale.US);
0288: MeasureFormat curFmt = MeasureFormat.getCurrencyFormat();
0289: //Not knowing how to test this factory method,
0290: // because the concreat class of MeasureFormat -
0291: // CurrencyFormat is just for internal use.
0292: ULocale.setDefault(save);
0293: }
0294:
0295: /**
0296: * Test the Currency object handling, new as of ICU 2.2.
0297: */
0298: public void TestCurrencyObject() {
0299: NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.US);
0300:
0301: expectCurrency(fmt, null, 1234.56, "$1,234.56");
0302:
0303: expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),
0304: 1234.56, "\u20AC1,234.56"); // Euro
0305:
0306: expectCurrency(fmt, Currency.getInstance(Locale.JAPAN),
0307: 1234.56, "\u00A51,235"); // Yen
0308:
0309: expectCurrency(fmt, Currency.getInstance(new Locale("fr", "CH",
0310: "")), 1234.56, "SwF1,234.55"); // 0.05 rounding
0311:
0312: expectCurrency(fmt, Currency.getInstance(Locale.US), 1234.56,
0313: "$1,234.56");
0314:
0315: fmt = NumberFormat.getCurrencyInstance(Locale.FRANCE);
0316:
0317: expectCurrency(fmt, null, 1234.56, "1 234,56 \u20AC");
0318:
0319: expectCurrency(fmt, Currency.getInstance(Locale.JAPAN),
0320: 1234.56, "1 235 \u00A5"); // Yen
0321:
0322: expectCurrency(fmt, Currency.getInstance(new Locale("fr", "CH",
0323: "")), 1234.56, "1 234,55 sFr."); // 0.25 rounding
0324:
0325: expectCurrency(fmt, Currency.getInstance(Locale.US), 1234.56,
0326: "1 234,56 $");
0327:
0328: expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),
0329: 1234.56, "1 234,56 \u20AC"); // Euro
0330: }
0331:
0332: public void TestCurrencyPatterns() {
0333: int i;
0334: Locale[] locs = NumberFormat.getAvailableLocales();
0335: for (i = 0; i < locs.length; ++i) {
0336: NumberFormat nf = NumberFormat.getCurrencyInstance(locs[i]);
0337: // Make sure currency formats do not have a variable number
0338: // of fraction digits
0339: int min = nf.getMinimumFractionDigits();
0340: int max = nf.getMaximumFractionDigits();
0341: if (min != max) {
0342: String a = nf.format(1.0);
0343: String b = nf.format(1.125);
0344: errln("FAIL: "
0345: + locs[i]
0346: + " min fraction digits != max fraction digits; "
0347: + "x 1.0 => " + a + "; x 1.125 => " + b);
0348: }
0349:
0350: // Make sure EURO currency formats have exactly 2 fraction digits
0351: if (nf instanceof DecimalFormat) {
0352: Currency curr = ((DecimalFormat) nf).getCurrency();
0353: if (curr != null
0354: && "EUR".equals(curr.getCurrencyCode())) {
0355: if (min != 2 || max != 2) {
0356: String a = nf.format(1.0);
0357: errln("FAIL: "
0358: + locs[i]
0359: + " is a EURO format but it does not have 2 fraction digits; "
0360: + "x 1.0 => " + a);
0361: }
0362: }
0363: }
0364: }
0365: }
0366:
0367: /**
0368: * Do rudimentary testing of parsing.
0369: */
0370: public void TestParse() {
0371: String arg = "0.0";
0372: DecimalFormat format = new DecimalFormat("00");
0373: double aNumber = 0l;
0374: try {
0375: aNumber = format.parse(arg).doubleValue();
0376: } catch (ParseException e) {
0377: System.out.println(e);
0378: }
0379: logln("parse(" + arg + ") = " + aNumber);
0380: }
0381:
0382: /**
0383: * Test proper rounding by the format method.
0384: */
0385: public void TestRounding487() {
0386:
0387: NumberFormat nf = NumberFormat.getInstance();
0388: roundingTest(nf, 0.00159999, 4, "0.0016");
0389: roundingTest(nf, 0.00995, 4, "0.01");
0390:
0391: roundingTest(nf, 12.3995, 3, "12.4");
0392:
0393: roundingTest(nf, 12.4999, 0, "12");
0394: roundingTest(nf, -19.5, 0, "-20");
0395:
0396: }
0397:
0398: /**
0399: * Test the functioning of the secondary grouping value.
0400: */
0401: public void TestSecondaryGrouping() {
0402:
0403: DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
0404: DecimalFormat f = new DecimalFormat("#,##,###", US);
0405:
0406: expect(f, 123456789L, "12,34,56,789");
0407: expectPat(f, "#,##,###");
0408: f.applyPattern("#,###");
0409:
0410: f.setSecondaryGroupingSize(4);
0411: expect(f, 123456789L, "12,3456,789");
0412: expectPat(f, "#,####,###");
0413: NumberFormat g = NumberFormat
0414: .getInstance(new Locale("hi", "IN"));
0415:
0416: String out = "";
0417: long l = 1876543210L;
0418: out = g.format(l);
0419:
0420: // expect "1,87,65,43,210", but with Hindi digits
0421: // 01234567890123
0422: boolean ok = true;
0423: if (out.length() != 14) {
0424: ok = false;
0425: } else {
0426: for (int i = 0; i < out.length(); ++i) {
0427: boolean expectGroup = false;
0428: switch (i) {
0429: case 1:
0430: case 4:
0431: case 7:
0432: case 10:
0433: expectGroup = true;
0434: break;
0435: }
0436: // Later -- fix this to get the actual grouping
0437: // character from the resource bundle.
0438: boolean isGroup = (out.charAt(i) == 0x002C);
0439: if (isGroup != expectGroup) {
0440: ok = false;
0441: break;
0442: }
0443: }
0444: }
0445: if (!ok) {
0446: errln("FAIL Expected "
0447: + l
0448: + " x hi_IN . \"1,87,65,43,210\" (with Hindi digits), got \""
0449: + out + "\"");
0450: } else {
0451: logln("Ok " + l + " x hi_IN . \"" + out + "\"");
0452: }
0453: }
0454:
0455: public void roundingTest(NumberFormat nf, double x,
0456: int maxFractionDigits, final String expected) {
0457: nf.setMaximumFractionDigits(maxFractionDigits);
0458: String out = nf.format(x);
0459: logln(x + " formats with " + maxFractionDigits
0460: + " fractional digits to " + out);
0461: if (!out.equals(expected))
0462: errln("FAIL: Expected " + expected);
0463: }
0464:
0465: /**
0466: * Upgrade to alphaWorks
0467: */
0468: public void TestExponent() {
0469: DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
0470: DecimalFormat fmt1 = new DecimalFormat("0.###E0", US);
0471: DecimalFormat fmt2 = new DecimalFormat("0.###E+0", US);
0472: int n = 1234;
0473: expect2(fmt1, n, "1.234E3");
0474: expect2(fmt2, n, "1.234E+3");
0475: expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"
0476:
0477: }
0478:
0479: /**
0480: * Upgrade to alphaWorks
0481: */
0482: public void TestScientific() {
0483:
0484: DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
0485:
0486: // Test pattern round-trip
0487: final String PAT[] = { "#E0", "0.####E0", "00.000E00",
0488: "##0.####E000", "0.###E0;[0.###E0]" };
0489: int PAT_length = PAT.length;
0490: int DIGITS[] = {
0491: // min int, max int, min frac, max frac
0492: 0, 1, 0, 0, // "#E0"
0493: 1, 1, 0, 4, // "0.####E0"
0494: 2, 2, 3, 3, // "00.000E00"
0495: 1, 3, 0, 4, // "##0.####E000"
0496: 1, 1, 0, 3, // "0.###E0;[0.###E0]"
0497: };
0498: for (int i = 0; i < PAT_length; ++i) {
0499: String pat = PAT[i];
0500: DecimalFormat df = new DecimalFormat(pat, US);
0501: String pat2 = df.toPattern();
0502: if (pat.equals(pat2)) {
0503: logln("Ok Pattern rt \"" + pat + "\" . \"" + pat2
0504: + "\"");
0505: } else {
0506: errln("FAIL Pattern rt \"" + pat + "\" . \"" + pat2
0507: + "\"");
0508: }
0509: // Make sure digit counts match what we expect
0510: if (df.getMinimumIntegerDigits() != DIGITS[4 * i]
0511: || df.getMaximumIntegerDigits() != DIGITS[4 * i + 1]
0512: || df.getMinimumFractionDigits() != DIGITS[4 * i + 2]
0513: || df.getMaximumFractionDigits() != DIGITS[4 * i + 3]) {
0514: errln("FAIL \"" + pat
0515: + "\" min/max int; min/max frac = "
0516: + df.getMinimumIntegerDigits() + "/"
0517: + df.getMaximumIntegerDigits() + ";"
0518: + df.getMinimumFractionDigits() + "/"
0519: + df.getMaximumFractionDigits() + ", expect "
0520: + DIGITS[4 * i] + "/" + DIGITS[4 * i + 1] + ";"
0521: + DIGITS[4 * i + 2] + "/" + DIGITS[4 * i + 3]);
0522: }
0523: }
0524:
0525: expect2(new DecimalFormat("#E0", US), 12345.0, "1.2345E4");
0526: expect(new DecimalFormat("0E0", US), 12345.0, "1E4");
0527:
0528: // pattern of NumberFormat.getScientificInstance(Locale.US) = "0.######E0" not "#E0"
0529: // so result = 1.234568E4 not 1.2345678901E4
0530: //when the pattern problem is finalized, delete comment mark'//'
0531: //of the following code
0532: expect2(NumberFormat.getScientificInstance(Locale.US),
0533: 12345.678901, "1.2345678901E4");
0534: logln("Testing NumberFormat.getScientificInstance(ULocale) ...");
0535: expect2(NumberFormat.getScientificInstance(ULocale.US),
0536: 12345.678901, "1.2345678901E4");
0537:
0538: expect(new DecimalFormat("##0.###E0", US), 12345.0, "12.34E3");
0539: expect(new DecimalFormat("##0.###E0", US), 12345.00001,
0540: "12.35E3");
0541: expect2(new DecimalFormat("##0.####E0", US), 12345, "12.345E3");
0542:
0543: // pattern of NumberFormat.getScientificInstance(Locale.US) = "0.######E0" not "#E0"
0544: // so result = 1.234568E4 not 1.2345678901E4
0545: expect2(NumberFormat.getScientificInstance(Locale.FRANCE),
0546: 12345.678901, "1,2345678901E4");
0547: logln("Testing NumberFormat.getScientificInstance(ULocale) ...");
0548: expect2(NumberFormat.getScientificInstance(ULocale.FRANCE),
0549: 12345.678901, "1,2345678901E4");
0550:
0551: expect(new DecimalFormat("##0.####E0", US), 789.12345e-9,
0552: "789.12E-9");
0553: expect2(new DecimalFormat("##0.####E0", US), 780.e-9, "780E-9");
0554: expect(new DecimalFormat(".###E0", US), 45678.0, ".457E5");
0555: expect2(new DecimalFormat(".###E0", US), 0, ".0E0");
0556: /*
0557: expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
0558: new DecimalFormat("##E0", US),
0559: new DecimalFormat("####E0", US),
0560: new DecimalFormat("0E0", US),
0561: new DecimalFormat("00E0", US),
0562: new DecimalFormat("000E0", US),
0563: },
0564: new Long(45678000),
0565: new String[] { "4.5678E7",
0566: "45.678E6",
0567: "4567.8E4",
0568: "5E7",
0569: "46E6",
0570: "457E5",
0571: }
0572: );
0573: !
0574: ! Unroll this test into individual tests below...
0575: !
0576: */
0577: expect2(new DecimalFormat("#E0", US), 45678000, "4.5678E7");
0578: expect2(new DecimalFormat("##E0", US), 45678000, "45.678E6");
0579: expect2(new DecimalFormat("####E0", US), 45678000, "4567.8E4");
0580: expect(new DecimalFormat("0E0", US), 45678000, "5E7");
0581: expect(new DecimalFormat("00E0", US), 45678000, "46E6");
0582: expect(new DecimalFormat("000E0", US), 45678000, "457E5");
0583: /*
0584: expect(new DecimalFormat("###E0", US, status),
0585: new Object[] { new Double(0.0000123), "12.3E-6",
0586: new Double(0.000123), "123E-6",
0587: new Double(0.00123), "1.23E-3",
0588: new Double(0.0123), "12.3E-3",
0589: new Double(0.123), "123E-3",
0590: new Double(1.23), "1.23E0",
0591: new Double(12.3), "12.3E0",
0592: new Double(123), "123E0",
0593: new Double(1230), "1.23E3",
0594: });
0595: !
0596: ! Unroll this test into individual tests below...
0597: !
0598: */
0599: expect2(new DecimalFormat("###E0", US), 0.0000123, "12.3E-6");
0600: expect2(new DecimalFormat("###E0", US), 0.000123, "123E-6");
0601: expect2(new DecimalFormat("###E0", US), 0.00123, "1.23E-3");
0602: expect2(new DecimalFormat("###E0", US), 0.0123, "12.3E-3");
0603: expect2(new DecimalFormat("###E0", US), 0.123, "123E-3");
0604: expect2(new DecimalFormat("###E0", US), 1.23, "1.23E0");
0605: expect2(new DecimalFormat("###E0", US), 12.3, "12.3E0");
0606: expect2(new DecimalFormat("###E0", US), 123.0, "123E0");
0607: expect2(new DecimalFormat("###E0", US), 1230.0, "1.23E3");
0608: /*
0609: expect(new DecimalFormat("0.#E+00", US, status),
0610: new Object[] { new Double(0.00012), "1.2E-04",
0611: new Long(12000), "1.2E+04",
0612: });
0613: !
0614: ! Unroll this test into individual tests below...
0615: !
0616: */
0617: expect2(new DecimalFormat("0.#E+00", US), 0.00012, "1.2E-04");
0618: expect2(new DecimalFormat("0.#E+00", US), 12000, "1.2E+04");
0619: }
0620:
0621: /**
0622: * Upgrade to alphaWorks
0623: */
0624: public void TestPad() {
0625:
0626: DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
0627: expect2(new DecimalFormat("*^##.##", US), 0, "^^^^0");
0628: expect2(new DecimalFormat("*^##.##", US), -1.3, "^-1.3");
0629: expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US), 0,
0630: "0.0E0______ g-m/s^2");
0631: expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US),
0632: 1.0 / 3, "333.333E-3_ g-m/s^2");
0633: expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US), 0,
0634: "0.0______ g-m/s^2");
0635: expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US), 1.0 / 3,
0636: "0.33333__ g-m/s^2");
0637:
0638: // Test padding before a sign
0639: final String formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
0640: expect2(new DecimalFormat(formatStr, US), -10,
0641: "xxxxxxxxxx(10.0)");
0642: expect2(new DecimalFormat(formatStr, US), -1000,
0643: "xxxxxxx(1,000.0)");
0644: expect2(new DecimalFormat(formatStr, US), -1000000,
0645: "xxx(1,000,000.0)");
0646: expect2(new DecimalFormat(formatStr, US), -100.37,
0647: "xxxxxxxx(100.37)");
0648: expect2(new DecimalFormat(formatStr, US), -10456.37,
0649: "xxxxx(10,456.37)");
0650: expect2(new DecimalFormat(formatStr, US), -1120456.37,
0651: "xx(1,120,456.37)");
0652: expect2(new DecimalFormat(formatStr, US), -112045600.37,
0653: "(112,045,600.37)");
0654: expect2(new DecimalFormat(formatStr, US), -1252045600.37,
0655: "(1,252,045,600.37)");
0656:
0657: expect2(new DecimalFormat(formatStr, US), 10,
0658: "xxxxxxxxxxxx10.0");
0659: expect2(new DecimalFormat(formatStr, US), 1000,
0660: "xxxxxxxxx1,000.0");
0661: expect2(new DecimalFormat(formatStr, US), 1000000,
0662: "xxxxx1,000,000.0");
0663: expect2(new DecimalFormat(formatStr, US), 100.37,
0664: "xxxxxxxxxx100.37");
0665: expect2(new DecimalFormat(formatStr, US), 10456.37,
0666: "xxxxxxx10,456.37");
0667: expect2(new DecimalFormat(formatStr, US), 1120456.37,
0668: "xxxx1,120,456.37");
0669: expect2(new DecimalFormat(formatStr, US), 112045600.37,
0670: "xx112,045,600.37");
0671: expect2(new DecimalFormat(formatStr, US), 10252045600.37,
0672: "10,252,045,600.37");
0673:
0674: // Test padding between a sign and a number
0675: final String formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
0676: expect2(new DecimalFormat(formatStr2, US), -10,
0677: "(10.0xxxxxxxxxx)");
0678: expect2(new DecimalFormat(formatStr2, US), -1000,
0679: "(1,000.0xxxxxxx)");
0680: expect2(new DecimalFormat(formatStr2, US), -1000000,
0681: "(1,000,000.0xxx)");
0682: expect2(new DecimalFormat(formatStr2, US), -100.37,
0683: "(100.37xxxxxxxx)");
0684: expect2(new DecimalFormat(formatStr2, US), -10456.37,
0685: "(10,456.37xxxxx)");
0686: expect2(new DecimalFormat(formatStr2, US), -1120456.37,
0687: "(1,120,456.37xx)");
0688: expect2(new DecimalFormat(formatStr2, US), -112045600.37,
0689: "(112,045,600.37)");
0690: expect2(new DecimalFormat(formatStr2, US), -1252045600.37,
0691: "(1,252,045,600.37)");
0692:
0693: expect2(new DecimalFormat(formatStr2, US), 10,
0694: "10.0xxxxxxxxxxxx");
0695: expect2(new DecimalFormat(formatStr2, US), 1000,
0696: "1,000.0xxxxxxxxx");
0697: expect2(new DecimalFormat(formatStr2, US), 1000000,
0698: "1,000,000.0xxxxx");
0699: expect2(new DecimalFormat(formatStr2, US), 100.37,
0700: "100.37xxxxxxxxxx");
0701: expect2(new DecimalFormat(formatStr2, US), 10456.37,
0702: "10,456.37xxxxxxx");
0703: expect2(new DecimalFormat(formatStr2, US), 1120456.37,
0704: "1,120,456.37xxxx");
0705: expect2(new DecimalFormat(formatStr2, US), 112045600.37,
0706: "112,045,600.37xx");
0707: expect2(new DecimalFormat(formatStr2, US), 10252045600.37,
0708: "10,252,045,600.37");
0709:
0710: //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
0711: DecimalFormat fmt = new DecimalFormat("#", US);
0712: char padString = 'P';
0713: fmt.setPadCharacter(padString);
0714: expectPad(fmt, "*P##.##", DecimalFormat.PAD_BEFORE_PREFIX, 5,
0715: padString);
0716: fmt.setPadCharacter('^');
0717: expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, '^');
0718: //commented untill implementation is complete
0719: /* fmt.setPadCharacter((UnicodeString)"^^^");
0720: expectPad(fmt, "*^^^#", DecimalFormat.kPadBeforePrefix, 3, (UnicodeString)"^^^");
0721: padString.remove();
0722: padString.append((UChar)0x0061);
0723: padString.append((UChar)0x0302);
0724: fmt.setPadCharacter(padString);
0725: UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
0726: UnicodeString pattern(patternChars);
0727: expectPad(fmt, pattern , DecimalFormat.kPadBeforePrefix, 4, padString);
0728: */
0729: }
0730:
0731: /**
0732: * Upgrade to alphaWorks
0733: */
0734: public void TestPatterns2() {
0735: DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
0736: DecimalFormat fmt = new DecimalFormat("#", US);
0737:
0738: char hat = 0x005E; /*^*/
0739:
0740: expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, hat);
0741: expectPad(fmt, "$*^#", DecimalFormat.PAD_AFTER_PREFIX, 2, hat);
0742: expectPad(fmt, "#*^", DecimalFormat.PAD_BEFORE_SUFFIX, 1, hat);
0743: expectPad(fmt, "#$*^", DecimalFormat.PAD_AFTER_SUFFIX, 2, hat);
0744: expectPad(fmt, "$*^$#", -1);
0745: expectPad(fmt, "#$*^$", -1);
0746: expectPad(fmt, "'pre'#,##0*x'post'",
0747: DecimalFormat.PAD_BEFORE_SUFFIX, 12, (char) 0x0078 /*x*/);
0748: expectPad(fmt, "''#0*x", DecimalFormat.PAD_BEFORE_SUFFIX, 3,
0749: (char) 0x0078 /*x*/);
0750: expectPad(fmt, "'I''ll'*a###.##",
0751: DecimalFormat.PAD_AFTER_PREFIX, 10, (char) 0x0061 /*a*/);
0752:
0753: fmt.applyPattern("AA#,##0.00ZZ");
0754: fmt.setPadCharacter(hat);
0755:
0756: fmt.setFormatWidth(10);
0757:
0758: fmt.setPadPosition(DecimalFormat.PAD_BEFORE_PREFIX);
0759: expectPat(fmt, "*^AA#,##0.00ZZ");
0760:
0761: fmt.setPadPosition(DecimalFormat.PAD_BEFORE_SUFFIX);
0762: expectPat(fmt, "AA#,##0.00*^ZZ");
0763:
0764: fmt.setPadPosition(DecimalFormat.PAD_AFTER_SUFFIX);
0765: expectPat(fmt, "AA#,##0.00ZZ*^");
0766:
0767: // 12 3456789012
0768: String exp = "AA*^#,##0.00ZZ";
0769: fmt.setFormatWidth(12);
0770: fmt.setPadPosition(DecimalFormat.PAD_AFTER_PREFIX);
0771: expectPat(fmt, exp);
0772:
0773: fmt.setFormatWidth(13);
0774: // 12 34567890123
0775: expectPat(fmt, "AA*^##,##0.00ZZ");
0776:
0777: fmt.setFormatWidth(14);
0778: // 12 345678901234
0779: expectPat(fmt, "AA*^###,##0.00ZZ");
0780:
0781: fmt.setFormatWidth(15);
0782: // 12 3456789012345
0783: expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
0784:
0785: fmt.setFormatWidth(16);
0786: // 12 34567890123456
0787: expectPat(fmt, "AA*^#,###,##0.00ZZ");
0788: }
0789:
0790: public void TestRegistration() {
0791: final ULocale SRC_LOC = ULocale.FRANCE;
0792: final ULocale SWAP_LOC = ULocale.US;
0793:
0794: class TestFactory extends SimpleNumberFormatFactory {
0795: NumberFormat currencyStyle;
0796:
0797: TestFactory() {
0798: super (SRC_LOC, true);
0799: currencyStyle = NumberFormat
0800: .getIntegerInstance(SWAP_LOC);
0801: }
0802:
0803: public NumberFormat createFormat(ULocale loc, int formatType) {
0804: if (formatType == FORMAT_CURRENCY) {
0805: return currencyStyle;
0806: }
0807: return null;
0808: }
0809: }
0810:
0811: NumberFormat f0 = NumberFormat.getIntegerInstance(SWAP_LOC);
0812: NumberFormat f1 = NumberFormat.getIntegerInstance(SRC_LOC);
0813: NumberFormat f2 = NumberFormat.getCurrencyInstance(SRC_LOC);
0814: Object key = NumberFormat.registerFactory(new TestFactory());
0815: NumberFormat f3 = NumberFormat.getCurrencyInstance(SRC_LOC);
0816: NumberFormat f4 = NumberFormat.getIntegerInstance(SRC_LOC);
0817: NumberFormat.unregister(key); // restore for other tests
0818: NumberFormat f5 = NumberFormat.getCurrencyInstance(SRC_LOC);
0819:
0820: float n = 1234.567f;
0821: logln("f0 swap int: " + f0.format(n));
0822: logln("f1 src int: " + f1.format(n));
0823: logln("f2 src cur: " + f2.format(n));
0824: logln("f3 reg cur: " + f3.format(n));
0825: logln("f4 reg int: " + f4.format(n));
0826: logln("f5 unreg cur: " + f5.format(n));
0827:
0828: if (!f3.format(n).equals(f0.format(n))) {
0829: errln("registered service did not match");
0830: }
0831: if (!f4.format(n).equals(f1.format(n))) {
0832: errln("registered service did not inherit");
0833: }
0834: if (!f5.format(n).equals(f2.format(n))) {
0835: errln("unregistered service did not match original");
0836: }
0837: }
0838:
0839: public void TestScientific2() {
0840: // jb 2552
0841: DecimalFormat fmt = (DecimalFormat) NumberFormat
0842: .getCurrencyInstance();
0843: Number num = new Double(12.34);
0844: expect(fmt, num, "$12.34");
0845: fmt.setScientificNotation(true);
0846: expect(fmt, num, "$1.23E1");
0847: fmt.setScientificNotation(false);
0848: expect(fmt, num, "$12.34");
0849: }
0850:
0851: public void TestScientificGrouping() {
0852: // jb 2552
0853: DecimalFormat fmt = new DecimalFormat("###.##E0");
0854: expect(fmt, .01234, "12.3E-3");
0855: expect(fmt, .1234, "123E-3");
0856: expect(fmt, 1.234, "1.23E0");
0857: expect(fmt, 12.34, "12.3E0");
0858: expect(fmt, 123.4, "123E0");
0859: expect(fmt, 1234, "1.23E3");
0860: }
0861:
0862: // additional coverage tests
0863:
0864: // sigh, can't have static inner classes, why not?
0865:
0866: static final class PI extends Number {
0867: private PI() {
0868: }
0869:
0870: public int intValue() {
0871: return (int) Math.PI;
0872: }
0873:
0874: public long longValue() {
0875: return (long) Math.PI;
0876: }
0877:
0878: public float floatValue() {
0879: return (float) Math.PI;
0880: }
0881:
0882: public double doubleValue() {
0883: return (double) Math.PI;
0884: }
0885:
0886: public byte byteValue() {
0887: return (byte) Math.PI;
0888: }
0889:
0890: public short shortValue() {
0891: return (short) Math.PI;
0892: }
0893:
0894: public static final Number INSTANCE = new PI();
0895: }
0896:
0897: public void TestCoverage() {
0898: NumberFormat fmt = NumberFormat.getNumberInstance(); // default locale
0899: logln(fmt.format(new BigInteger(
0900: "1234567890987654321234567890987654321", 10)));
0901:
0902: fmt = NumberFormat.getScientificInstance(); // default locale
0903:
0904: logln(fmt.format(PI.INSTANCE));
0905:
0906: try {
0907: logln(fmt.format("12345"));
0908: errln("numberformat of string did not throw exception");
0909: } catch (Exception e) {
0910: logln("PASS: numberformat of string failed as expected");
0911: }
0912:
0913: int hash = fmt.hashCode();
0914:
0915: logln("compare to string returns: " + fmt.equals(""));
0916:
0917: // For ICU 2.6 - alan
0918: DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
0919: DecimalFormat df = new DecimalFormat(
0920: "'*&'' '\u00A4' ''&*' #,##0.00", US);
0921: df.setCurrency(Currency.getInstance("INR"));
0922: expect2(df, 1.0, "*&' Re. '&* 1.00");
0923: expect2(df, -2.0, "-*&' Rs. '&* 2.00");
0924: df.applyPattern("#,##0.00 '*&'' '\u00A4' ''&*'");
0925: expect2(df, 2.0, "2.00 *&' Rs. '&*");
0926: expect2(df, -1.0, "-1.00 *&' Re. '&*");
0927:
0928: //#ifndef FOUNDATION
0929: java.math.BigDecimal r = df.getRoundingIncrement();
0930: //#else
0931: //## com.ibm.icu.math.BigDecimal r = df.getRoundingIncrement();
0932: //#endif
0933: if (r != null) {
0934: errln("FAIL: rounding = " + r + ", expect null");
0935: }
0936:
0937: if (df.isScientificNotation()) {
0938: errln("FAIL: isScientificNotation = true, expect false");
0939: }
0940:
0941: df.applyPattern("0.00000");
0942: df.setScientificNotation(true);
0943: if (!df.isScientificNotation()) {
0944: errln("FAIL: isScientificNotation = false, expect true");
0945: }
0946: df.setMinimumExponentDigits((byte) 2);
0947: if (df.getMinimumExponentDigits() != 2) {
0948: errln("FAIL: getMinimumExponentDigits = "
0949: + df.getMinimumExponentDigits() + ", expect 2");
0950: }
0951: df.setExponentSignAlwaysShown(true);
0952: if (!df.isExponentSignAlwaysShown()) {
0953: errln("FAIL: isExponentSignAlwaysShown = false, expect true");
0954: }
0955: df.setSecondaryGroupingSize(0);
0956: if (df.getSecondaryGroupingSize() != 0) {
0957: errln("FAIL: getSecondaryGroupingSize = "
0958: + df.getSecondaryGroupingSize() + ", expect 0");
0959: }
0960: expect2(df, 3.14159, "3.14159E+00");
0961: }
0962:
0963: public void TestWhiteSpaceParsing() {
0964: DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
0965: DecimalFormat fmt = new DecimalFormat("a b#0c ", US);
0966: int n = 1234;
0967: expect(fmt, "a b1234c ", n);
0968: expect(fmt, "a b1234c ", n);
0969: }
0970:
0971: /**
0972: * Test currencies whose display name is a ChoiceFormat.
0973: */
0974: public void TestComplexCurrency() {
0975: Locale loc = new Locale("en", "IN", "");
0976: NumberFormat fmt = NumberFormat.getCurrencyInstance(loc);
0977:
0978: expect2(fmt, 1.0, "Re. 1.00");
0979: expect(fmt, 1.001, "Re. 1.00"); // tricky
0980: expect2(fmt, 12345678.0, "Rs. 1,23,45,678.00");
0981: expect2(fmt, 0.5, "Rs. 0.50");
0982: expect2(fmt, -1.0, "-Re. 1.00");
0983: expect2(fmt, -10.0, "-Rs. 10.00");
0984: }
0985:
0986: public void TestCurrencyKeyword() {
0987: ULocale locale = new ULocale("th_TH@currency=QQQ");
0988: NumberFormat format = NumberFormat.getCurrencyInstance(locale);
0989: String result = format.format(12.34f);
0990: if (!"QQQ12.34".equals(result)) {
0991: errln("got unexpected currency: " + result);
0992: }
0993: }
0994:
0995: public void TestThreadedFormat() {
0996:
0997: class FormatTask implements Runnable {
0998: DecimalFormat fmt;
0999: StringBuffer buf;
1000: boolean inc;
1001: float num;
1002:
1003: FormatTask(DecimalFormat fmt, int index) {
1004: this .fmt = fmt;
1005: this .buf = new StringBuffer();
1006: this .inc = (index & 0x1) == 0;
1007: this .num = inc ? 0 : 10000;
1008: }
1009:
1010: public void run() {
1011: if (inc) {
1012: while (num < 10000) {
1013: buf.append(fmt.format(num) + "\n");
1014: num += 3.14159;
1015: }
1016: } else {
1017: while (num > 0) {
1018: buf.append(fmt.format(num) + "\n");
1019: num -= 3.14159;
1020: }
1021: }
1022: }
1023:
1024: String result() {
1025: return buf.toString();
1026: }
1027: }
1028:
1029: DecimalFormat fmt = new DecimalFormat("0.####");
1030: FormatTask[] tasks = new FormatTask[8];
1031: for (int i = 0; i < tasks.length; ++i) {
1032: tasks[i] = new FormatTask(fmt, i);
1033: }
1034:
1035: TestUtil.runUntilDone(tasks);
1036:
1037: for (int i = 2; i < tasks.length; i++) {
1038: String str1 = tasks[i].result();
1039: String str2 = tasks[i - 2].result();
1040: if (!str1.equals(str2)) {
1041: System.out.println("mismatch at " + i);
1042: System.out.println(str1);
1043: System.out.println(str2);
1044: errln("decimal format thread mismatch");
1045:
1046: break;
1047: }
1048: str1 = str2;
1049: }
1050: }
1051:
1052: public void TestPerMill() {
1053: DecimalFormat fmt = new DecimalFormat("###.###\u2030");
1054: assertEquals("0.4857 x ###.###\u2030", "485.7\u2030", fmt
1055: .format(0.4857));
1056:
1057: DecimalFormatSymbols sym = new DecimalFormatSymbols(
1058: Locale.ENGLISH);
1059: sym.setPerMill('m');
1060: DecimalFormat fmt2 = new DecimalFormat("", sym);
1061: fmt2.applyLocalizedPattern("###.###m");
1062: assertEquals("0.4857 x ###.###m", "485.7m", fmt2.format(0.4857));
1063: }
1064:
1065: public void TestIllegalPatterns() {
1066: // Test cases:
1067: // Prefix with "-:" for illegal patterns
1068: // Prefix with "+:" for legal patterns
1069: String DATA[] = {
1070: // Unquoted special characters in the suffix are illegal
1071: "-:000.000|###", "+:000.000'|###'", };
1072: for (int i = 0; i < DATA.length; ++i) {
1073: String pat = DATA[i];
1074: boolean valid = pat.charAt(0) == '+';
1075: pat = pat.substring(2);
1076: Exception e = null;
1077: try {
1078: // locale doesn't matter here
1079: new DecimalFormat(pat);
1080: } catch (IllegalArgumentException e1) {
1081: e = e1;
1082: } catch (IndexOutOfBoundsException e1) {
1083: e = e1;
1084: }
1085: String msg = (e == null) ? "success" : e.getMessage();
1086: if ((e == null) == valid) {
1087: logln("Ok: pattern \"" + pat + "\": " + msg);
1088: } else {
1089: errln("FAIL: pattern \"" + pat + "\" should have "
1090: + (valid ? "succeeded" : "failed") + "; got "
1091: + msg);
1092: }
1093: }
1094: }
1095:
1096: /**
1097: * Parse a CurrencyAmount using the given NumberFormat, with
1098: * the 'delim' character separating the number and the currency.
1099: */
1100: private static CurrencyAmount parseCurrencyAmount(String str,
1101: NumberFormat fmt, char delim) throws ParseException {
1102: int i = str.indexOf(delim);
1103: return new CurrencyAmount(fmt.parse(str.substring(0, i)),
1104: Currency.getInstance(str.substring(i + 1)));
1105: }
1106:
1107: /**
1108: * Return an integer representing the next token from this
1109: * iterator. The integer will be an index into the given list, or
1110: * -1 if there are no more tokens, or -2 if the token is not on
1111: * the list.
1112: */
1113: private static int keywordIndex(String tok) {
1114: for (int i = 0; i < KEYWORDS.length; ++i) {
1115: if (tok.equals(KEYWORDS[i])) {
1116: return i;
1117: }
1118: }
1119: return -1;
1120: }
1121:
1122: private static final String KEYWORDS[] = {
1123: /*0*/"ref=", // <reference pattern to parse numbers>
1124: /*1*/"loc=", // <locale for formats>
1125: /*2*/"f:", // <pattern or '-'> <number> <exp. string>
1126: /*3*/"fp:", // <pattern or '-'> <number> <exp. string> <exp. number>
1127: /*4*/"rt:", // <pattern or '-'> <(exp.) number> <(exp.) string>
1128: /*5*/"p:", // <pattern or '-'> <string> <exp. number>
1129: /*6*/"perr:", // <pattern or '-'> <invalid string>
1130: /*7*/"pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
1131: /*8*/"fpc:", // <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
1132: };
1133:
1134: public void TestCases() {
1135: String caseFileName = "NumberFormatTestCases.txt";
1136: java.io.InputStream is = NumberFormatTest.class
1137: .getResourceAsStream(caseFileName);
1138:
1139: ResourceReader reader = new ResourceReader(is, caseFileName);
1140: TokenIterator tokens = new TokenIterator(reader);
1141:
1142: Locale loc = new Locale("en", "US", "");
1143: DecimalFormat ref = null, fmt = null;
1144: MeasureFormat mfmt = null;
1145: String pat = null, str = null, mloc = null;
1146:
1147: try {
1148: for (;;) {
1149: String tok = tokens.next();
1150: if (tok == null) {
1151: break;
1152: }
1153: String where = "(" + tokens.getLineNumber() + ") ";
1154: int cmd = keywordIndex(tok);
1155: switch (cmd) {
1156: case 0:
1157: // ref= <reference pattern>
1158: ref = new DecimalFormat(tokens.next(),
1159: new DecimalFormatSymbols(Locale.US));
1160: break;
1161: case 1:
1162: // loc= <locale>
1163: loc = LocaleUtility
1164: .getLocaleFromName(tokens.next());
1165: break;
1166: case 2: // f:
1167: case 3: // fp:
1168: case 4: // rt:
1169: case 5: // p:
1170: tok = tokens.next();
1171: if (!tok.equals("-")) {
1172: pat = tok;
1173: try {
1174: fmt = new DecimalFormat(pat,
1175: new DecimalFormatSymbols(loc));
1176: } catch (IllegalArgumentException iae) {
1177: errln(where + "Pattern \"" + pat + '"');
1178: iae.printStackTrace();
1179: tokens.next(); // consume remaining tokens
1180: tokens.next();
1181: if (cmd == 3)
1182: tokens.next();
1183: continue;
1184: }
1185: }
1186: str = null;
1187: try {
1188: if (cmd == 2 || cmd == 3 || cmd == 4) {
1189: // f: <pattern or '-'> <number> <exp. string>
1190: // fp: <pattern or '-'> <number> <exp. string> <exp. number>
1191: // rt: <pattern or '-'> <number> <string>
1192: String num = tokens.next();
1193: str = tokens.next();
1194: Number n = (Number) ref.parse(num);
1195: assertEquals(where + '"' + pat
1196: + "\".format(" + num + ")", str,
1197: fmt.format(n));
1198: if (cmd == 3) { // fp:
1199: n = (Number) ref.parse(tokens.next());
1200: }
1201: if (cmd != 2) { // != f:
1202: assertEquals(where + '"' + pat
1203: + "\".parse(\"" + str + "\")",
1204: n, fmt.parse(str));
1205: }
1206: }
1207: // p: <pattern or '-'> <string to parse> <exp. number>
1208: else {
1209: str = tokens.next();
1210: String expstr = tokens.next();
1211: Number exp = (Number) ref.parse(expstr);
1212: assertEquals(where + '"' + pat
1213: + "\".parse(\"" + str + "\")", exp,
1214: fmt.parse(str));
1215: }
1216: } catch (ParseException e) {
1217: errln(where + '"' + pat + "\".parse(\"" + str
1218: + "\") threw an exception");
1219: e.printStackTrace();
1220: }
1221: break;
1222: case 6:
1223: // perr: <pattern or '-'> <invalid string>
1224: errln("Under construction");
1225: return;
1226: case 7:
1227: // pat: <pattern> <exp. toPattern, or '-' or 'err'>
1228: String testpat = tokens.next();
1229: String exppat = tokens.next();
1230: boolean err = exppat.equals("err");
1231: if (testpat.equals("-")) {
1232: if (err) {
1233: errln("Invalid command \"pat: - err\" at "
1234: + tokens.describePosition());
1235: continue;
1236: }
1237: testpat = pat;
1238: }
1239: if (exppat.equals("-"))
1240: exppat = testpat;
1241: try {
1242: DecimalFormat f = null;
1243: if (testpat == pat) { // [sic]
1244: f = fmt;
1245: } else {
1246: f = new DecimalFormat(testpat);
1247: }
1248: if (err) {
1249: errln(where + "Invalid pattern \""
1250: + testpat + "\" was accepted");
1251: } else {
1252: assertEquals(where + '"' + testpat
1253: + "\".toPattern()", exppat, f
1254: .toPattern());
1255: }
1256: } catch (IllegalArgumentException iae2) {
1257: if (err) {
1258: logln("Ok: " + where + "Invalid pattern \""
1259: + testpat + "\" threw an exception");
1260: } else {
1261: errln(where + "Valid pattern \"" + testpat
1262: + "\" threw an exception");
1263: iae2.printStackTrace();
1264: }
1265: }
1266: break;
1267: case 8: // fpc:
1268: tok = tokens.next();
1269: if (!tok.equals("-")) {
1270: mloc = tok;
1271: ULocale l = new ULocale(mloc);
1272: try {
1273: mfmt = MeasureFormat.getCurrencyFormat(l);
1274: } catch (IllegalArgumentException iae) {
1275: errln(where + "Loc \"" + tok + '"');
1276: iae.printStackTrace();
1277: tokens.next(); // consume remaining tokens
1278: tokens.next();
1279: tokens.next();
1280: continue;
1281: }
1282: }
1283: str = null;
1284: try {
1285: // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
1286: String currAmt = tokens.next();
1287: str = tokens.next();
1288: CurrencyAmount n = parseCurrencyAmount(currAmt,
1289: ref, '/');
1290: assertEquals(where + "getCurrencyFormat("
1291: + mloc + ").format(" + currAmt + ")",
1292: str, mfmt.format(n));
1293: n = parseCurrencyAmount(tokens.next(), ref, '/');
1294: assertEquals(where + "getCurrencyFormat("
1295: + mloc + ").parse(\"" + str + "\")", n,
1296: (CurrencyAmount) mfmt.parseObject(str));
1297: } catch (ParseException e) {
1298: errln(where + '"' + pat + "\".parse(\"" + str
1299: + "\") threw an exception");
1300: e.printStackTrace();
1301: }
1302: break;
1303: case -1:
1304: errln("Unknown command \"" + tok + "\" at "
1305: + tokens.describePosition());
1306: return;
1307: }
1308: }
1309: } catch (java.io.IOException e) {
1310: //#ifndef FOUNDATION
1311: throw new RuntimeException(e);
1312: //#else
1313: //## throw new RuntimeException(e.getMessage());
1314: //#endif
1315: }
1316: }
1317:
1318: public void TestRounding() {
1319: DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat
1320: .getInstance(ULocale.ENGLISH);
1321: if (false) { // for debugging specific value
1322: nf.setRoundingMode(BigDecimal.ROUND_HALF_UP);
1323: checkRounding(nf, new BigDecimal("300.0300000000"), 0,
1324: new BigDecimal("0.020000000"));
1325: }
1326: // full tests
1327: int[] roundingIncrements = { 1, 2, 5, 20, 50, 100 };
1328: int[] testValues = { 0, 300 };
1329: for (int j = 0; j < testValues.length; ++j) {
1330: for (int mode = BigDecimal.ROUND_UP; mode < BigDecimal.ROUND_HALF_EVEN; ++mode) {
1331: nf.setRoundingMode(mode);
1332: for (int increment = 0; increment < roundingIncrements.length; ++increment) {
1333: BigDecimal base = new BigDecimal(testValues[j]);
1334: BigDecimal rInc = new BigDecimal(
1335: roundingIncrements[increment]);
1336: checkRounding(nf, base, 20, rInc);
1337: rInc = new BigDecimal("1.000000000").divide(rInc);
1338: checkRounding(nf, base, 20, rInc);
1339: }
1340: }
1341: }
1342: }
1343:
1344: void checkRounding(DecimalFormat nf, BigDecimal base,
1345: int iterations, BigDecimal increment) {
1346: //#ifdef FOUNDATION
1347: //## nf.setRoundingIncrement(increment);
1348: //#else
1349: nf.setRoundingIncrement(increment.toBigDecimal());
1350: //#endif
1351: BigDecimal lastParsed = new BigDecimal(Integer.MIN_VALUE); // used to make sure that rounding is monotonic
1352: for (int i = -iterations; i <= iterations; ++i) {
1353: BigDecimal iValue = base.add(increment.multiply(
1354: new BigDecimal(i)).movePointLeft(1));
1355: BigDecimal smallIncrement = new BigDecimal("0.00000001");
1356: if (iValue.signum() != 0) {
1357: smallIncrement.multiply(iValue); // scale unless zero
1358: }
1359: // we not only test the value, but some values in a small range around it.
1360: lastParsed = checkRound(nf,
1361: iValue.subtract(smallIncrement), lastParsed);
1362: lastParsed = checkRound(nf, iValue, lastParsed);
1363: lastParsed = checkRound(nf, iValue.add(smallIncrement),
1364: lastParsed);
1365: }
1366: }
1367:
1368: private BigDecimal checkRound(DecimalFormat nf, BigDecimal iValue,
1369: BigDecimal lastParsed) {
1370: String formatedBigDecimal = nf.format(iValue);
1371: String formattedDouble = nf.format(iValue.doubleValue());
1372: if (!equalButForTrailingZeros(formatedBigDecimal,
1373: formattedDouble)) {
1374: errln("Failure at: " + iValue + " (" + iValue.doubleValue()
1375: + ")" + ",\tRounding-mode: "
1376: + roundingModeNames[nf.getRoundingMode()]
1377: + ",\tRounding-increment: "
1378: + nf.getRoundingIncrement() + ",\tdouble: "
1379: + formattedDouble + ",\tBigDecimal: "
1380: + formatedBigDecimal);
1381: } else {
1382: logln("Value: " + iValue + ",\tRounding-mode: "
1383: + roundingModeNames[nf.getRoundingMode()]
1384: + ",\tRounding-increment: "
1385: + nf.getRoundingIncrement() + ",\tdouble: "
1386: + formattedDouble + ",\tBigDecimal: "
1387: + formatedBigDecimal);
1388: }
1389: try {
1390: // Number should have compareTo(...)
1391: BigDecimal parsed = toBigDecimal(nf
1392: .parse(formatedBigDecimal));
1393: if (lastParsed.compareTo(parsed) > 0) {
1394: errln("Rounding wrong direction!: " + lastParsed
1395: + " > " + parsed);
1396: }
1397: lastParsed = parsed;
1398: } catch (ParseException e) {
1399: errln("Parse Failure with: " + formatedBigDecimal);
1400: }
1401: return lastParsed;
1402: }
1403:
1404: static BigDecimal toBigDecimal(Number number) {
1405: return number instanceof BigDecimal ? (BigDecimal) number
1406: : number instanceof BigInteger ? new BigDecimal(
1407: (BigInteger) number)
1408: //#ifndef FOUNDATION
1409: : number instanceof java.math.BigDecimal ? new BigDecimal(
1410: (java.math.BigDecimal) number)
1411: //#endif
1412: : number instanceof Double ? new BigDecimal(
1413: number.doubleValue())
1414: : number instanceof Float ? new BigDecimal(
1415: number.floatValue())
1416: : new BigDecimal(number
1417: .longValue());
1418: }
1419:
1420: static String[] roundingModeNames = { "ROUND_UP", "ROUND_DOWN",
1421: "ROUND_CEILING", "ROUND_FLOOR", "ROUND_HALF_UP",
1422: "ROUND_HALF_DOWN", "ROUND_HALF_EVEN", "ROUND_UNNECESSARY" };
1423:
1424: private static boolean equalButForTrailingZeros(String formatted1,
1425: String formatted2) {
1426: if (formatted1.length() == formatted2.length())
1427: return formatted1.equals(formatted2);
1428: return stripFinalZeros(formatted1).equals(
1429: stripFinalZeros(formatted2));
1430: }
1431:
1432: private static String stripFinalZeros(String formatted) {
1433: int len1 = formatted.length();
1434: char ch;
1435: while (len1 > 0
1436: && ((ch = formatted.charAt(len1 - 1)) == '0' || ch == '.'))
1437: --len1;
1438: return formatted.substring(0, len1);
1439: }
1440:
1441: //------------------------------------------------------------------
1442: // Support methods
1443: //------------------------------------------------------------------
1444:
1445: // Format-Parse test
1446: public void expect2(NumberFormat fmt, Number n, String exp) {
1447: // Don't round-trip format test, since we explicitly do it
1448: expect(fmt, n, exp, false);
1449: expect(fmt, exp, n);
1450: }
1451:
1452: // Format-Parse test (convenience)
1453: public void expect2(NumberFormat fmt, double n, String exp) {
1454: expect2(fmt, new Double(n), exp);
1455: }
1456:
1457: // Format-Parse test (convenience)
1458: public void expect2(NumberFormat fmt, long n, String exp) {
1459: expect2(fmt, new Long(n), exp);
1460: }
1461:
1462: // Format test
1463: public void expect(NumberFormat fmt, Number n, String exp,
1464: boolean rt) {
1465: StringBuffer saw = new StringBuffer();
1466: FieldPosition pos = new FieldPosition(0);
1467: fmt.format(n, saw, pos);
1468: String pat = ((DecimalFormat) fmt).toPattern();
1469: if (saw.toString().equals(exp)) {
1470: logln("Ok " + n + " x " + pat + " = \"" + saw + "\"");
1471: // We should be able to round-trip the formatted string =>
1472: // number => string (but not the other way around: number
1473: // => string => number2, might have number2 != number):
1474: if (rt) {
1475: try {
1476: Number n2 = fmt.parse(exp);
1477: StringBuffer saw2 = new StringBuffer();
1478: fmt.format(n2, saw2, pos);
1479: if (!saw2.toString().equals(exp)) {
1480: errln("FAIL \"" + exp + "\" => " + n2
1481: + " => \"" + saw2 + '"');
1482: }
1483: } catch (ParseException e) {
1484: errln(e.getMessage());
1485: return;
1486: }
1487: }
1488: } else {
1489: errln("FAIL " + n + " x " + pat + " = \"" + saw
1490: + "\", expected \"" + exp + "\"");
1491: }
1492: }
1493:
1494: // Format test (convenience)
1495: public void expect(NumberFormat fmt, Number n, String exp) {
1496: expect(fmt, n, exp, true);
1497: }
1498:
1499: // Format test (convenience)
1500: public void expect(NumberFormat fmt, double n, String exp) {
1501: expect(fmt, new Double(n), exp);
1502: }
1503:
1504: // Format test (convenience)
1505: public void expect(NumberFormat fmt, long n, String exp) {
1506: expect(fmt, new Long(n), exp);
1507: }
1508:
1509: // Parse test
1510: public void expect(NumberFormat fmt, String str, Number n) {
1511: Number num = null;
1512: try {
1513: num = (Number) fmt.parse(str);
1514: } catch (ParseException e) {
1515: errln(e.getMessage());
1516: return;
1517: }
1518: String pat = ((DecimalFormat) fmt).toPattern();
1519: // A little tricky here -- make sure Double(12345.0) and
1520: // Long(12345) match.
1521: if (num.equals(n) || num.doubleValue() == n.doubleValue()) {
1522: logln("Ok \"" + str + "\" x " + pat + " = " + num);
1523: } else {
1524: errln("FAIL \"" + str + "\" x " + pat + " = " + num
1525: + ", expected " + n);
1526: }
1527: }
1528:
1529: // Parse test (convenience)
1530: public void expect(NumberFormat fmt, String str, double n) {
1531: expect(fmt, str, new Double(n));
1532: }
1533:
1534: // Parse test (convenience)
1535: public void expect(NumberFormat fmt, String str, long n) {
1536: expect(fmt, str, new Long(n));
1537: }
1538:
1539: private void expectCurrency(NumberFormat nf, Currency curr,
1540: double value, String string) {
1541: DecimalFormat fmt = (DecimalFormat) nf;
1542: if (curr != null) {
1543: fmt.setCurrency(curr);
1544: }
1545: String s = fmt.format(value).replace('\u00A0', ' ');
1546:
1547: if (s.equals(string)) {
1548: logln("Ok: " + value + " x " + curr + " => " + s);
1549: } else {
1550: errln("FAIL: " + value + " x " + curr + " => " + s
1551: + ", expected " + string);
1552: }
1553: }
1554:
1555: public void expectPad(DecimalFormat fmt, String pat, int pos) {
1556: expectPad(fmt, pat, pos, 0, (char) 0);
1557: }
1558:
1559: public void expectPad(DecimalFormat fmt, final String pat, int pos,
1560: int width, final char pad) {
1561: int apos = 0, awidth = 0;
1562: char apadStr;
1563: try {
1564: fmt.applyPattern(pat);
1565: apos = fmt.getPadPosition();
1566: awidth = fmt.getFormatWidth();
1567: apadStr = fmt.getPadCharacter();
1568: } catch (Exception e) {
1569: apos = -1;
1570: awidth = width;
1571: apadStr = pad;
1572: }
1573:
1574: if (apos == pos && awidth == width && apadStr == pad) {
1575: logln("Ok \""
1576: + pat
1577: + "\" pos="
1578: + apos
1579: + ((pos == -1) ? "" : " width=" + awidth + " pad="
1580: + apadStr));
1581: } else {
1582: errln("FAIL \"" + pat + "\" pos=" + apos + " width="
1583: + awidth + " pad=" + apadStr + ", expected " + pos
1584: + " " + width + " " + pad);
1585: }
1586: }
1587:
1588: public void expectPat(DecimalFormat fmt, final String exp) {
1589: String pat = fmt.toPattern();
1590: if (pat.equals(exp)) {
1591: logln("Ok \"" + pat + "\"");
1592: } else {
1593: errln("FAIL \"" + pat + "\", expected \"" + exp + "\"");
1594: }
1595: }
1596:
1597: public void TestJB3832() {
1598: ULocale locale = new ULocale("pt_PT@currency=PTE");
1599: NumberFormat format = NumberFormat.getCurrencyInstance(locale);
1600: Currency curr = Currency.getInstance(locale);
1601: logln("\nName of the currency is: "
1602: + curr.getName(locale, Currency.LONG_NAME,
1603: new boolean[] { false }));
1604: CurrencyAmount cAmt = new CurrencyAmount(1150.50, curr);
1605: logln("CurrencyAmount object's hashCode is: " + cAmt.hashCode()); //cover hashCode
1606: String str = format.format(cAmt);
1607: String expected = "1,150$50 Esc.";
1608: if (!expected.equals(str)) {
1609: errln("Did not get the expected output Expected: "
1610: + expected + " Got: " + str);
1611: }
1612: }
1613:
1614: public void TestStrictParse() {
1615: String[] pass = { "0", // single zero before end of text is not leading
1616: "0 ", // single zero at end of number is not leading
1617: "0.", // single zero before period (or decimal, it's ambiguous) is not leading
1618: "0,", // single zero before comma (not group separator) is not leading
1619: "0.0", // single zero before decimal followed by digit is not leading
1620: "0. ", // same as above before period (or decimal) is not leading
1621: "0.100,5", // comma stops parse of decimal (no grouping)
1622: ".00", // leading decimal is ok, even with zeros
1623: "1234567", // group separators are not required
1624: "12345, ", // comma not followed by digit is not a group separator, but end of number
1625: "1,234, ", // if group separator is present, group sizes must be appropriate
1626: "1,234,567", // ...secondary too
1627: "0E", // an exponnent not followed by zero or digits is not an exponent
1628: };
1629: String[] fail = { "00", // leading zero before zero
1630: "012", // leading zero before digit
1631: "0,456", // leading zero before group separator
1632: "1,2", // wrong number of digits after group separator
1633: ",0", // leading group separator before zero
1634: ",1", // leading group separator before digit
1635: ",.02", // leading group separator before decimal
1636: "1,.02", // group separator before decimal
1637: "1,,200", // multiple group separators
1638: "1,45", // wrong number of digits in primary group
1639: "1,45 that", // wrong number of digits in primary group
1640: "1,45.34", // wrong number of digits in primary group
1641: "1234,567", // wrong number of digits in secondary group
1642: "12,34,567", // wrong number of digits in secondary group
1643: "1,23,456,7890", // wrong number of digits in primary and secondary groups
1644: };
1645:
1646: DecimalFormat nf = (DecimalFormat) NumberFormat
1647: .getInstance(Locale.ENGLISH);
1648: runStrictParseBatch(nf, pass, fail);
1649:
1650: String[] scientificPass = { "0E2", // single zero before exponent is ok
1651: "1234E2", // any number of digits before exponent is ok
1652: "1,234E", // an exponent string not followed by zero or digits is not an exponent
1653: };
1654: String[] scientificFail = { "00E2", // double zeros fail
1655: "1,234E2", // group separators with exponent fail
1656: };
1657:
1658: nf = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
1659: runStrictParseBatch(nf, scientificPass, scientificFail);
1660:
1661: String[] mixedPass = { "12,34,567", "12,34,567,",
1662: "12,34,567, that", "12,34,567 that", };
1663: String[] mixedFail = { "12,34,56", "12,34,56,",
1664: "12,34,56, that ", "12,34,56 that", };
1665:
1666: nf = new DecimalFormat("#,##,##0.#");
1667: runStrictParseBatch(nf, mixedPass, mixedFail);
1668: }
1669:
1670: void runStrictParseBatch(DecimalFormat nf, String[] pass,
1671: String[] fail) {
1672: nf.setParseStrict(false);
1673: runStrictParseTests("should pass", nf, pass, true);
1674: runStrictParseTests("should also pass", nf, fail, true);
1675: nf.setParseStrict(true);
1676: runStrictParseTests("should still pass", nf, pass, true);
1677: runStrictParseTests("should fail", nf, fail, false);
1678: }
1679:
1680: void runStrictParseTests(String msg, DecimalFormat nf,
1681: String[] tests, boolean pass) {
1682: logln("");
1683: logln("pattern: '" + nf.toPattern() + "'");
1684: logln(msg);
1685: for (int i = 0; i < tests.length; ++i) {
1686: String str = tests[i];
1687: ParsePosition pp = new ParsePosition(0);
1688: Number n = nf.parse(str, pp);
1689: String formatted = n != null ? nf.format(n) : "null";
1690: String err = pp.getErrorIndex() == -1 ? "" : "(error at "
1691: + pp.getErrorIndex() + ")";
1692: if ((err.length() == 0) != pass) {
1693: errln("'" + str + "' parsed '"
1694: + str.substring(0, pp.getIndex())
1695: + "' returned " + n + " formats to '"
1696: + formatted + "' " + err);
1697: } else {
1698: if (err.length() > 0) {
1699: err = "got expected " + err;
1700: }
1701: logln("'" + str + "' parsed '"
1702: + str.substring(0, pp.getIndex())
1703: + "' returned " + n + " formats to '"
1704: + formatted + "' " + err);
1705: }
1706: }
1707: }
1708:
1709: public void TestJB5251() {
1710: //save default locale
1711: ULocale defaultLocale = ULocale.getDefault();
1712: ULocale.setDefault(new ULocale("qr_QR"));
1713: NumberFormat nf1 = NumberFormat.getInstance();
1714: //reset default locale
1715: ULocale.setDefault(defaultLocale);
1716: }
1717:
1718: public void TestParseReturnType() {
1719: String[] defaultNonBigDecimals = { "123", // Long
1720: "123.0", // Long
1721: "0.0", // Long
1722: "12345678901234567890" // BigInteger
1723: };
1724:
1725: String[] doubles = { "-0.0", "NaN", "\u221E" // Infinity
1726: };
1727:
1728: DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
1729: DecimalFormat nf = new DecimalFormat("#.#", sym);
1730:
1731: if (nf.isParseBigDecimal()) {
1732: errln("FAIL: isParseDecimal() must return false by default");
1733: }
1734:
1735: // isParseBigDecimal() is false
1736: for (int i = 0; i < defaultNonBigDecimals.length; i++) {
1737: try {
1738: Number n = nf.parse(defaultNonBigDecimals[i]);
1739: if (n instanceof BigDecimal) {
1740: errln("FAIL: parse returns BigDecimal instance");
1741: }
1742: } catch (ParseException e) {
1743: errln("parse of '" + defaultNonBigDecimals[i]
1744: + "' threw exception: " + e);
1745: }
1746: }
1747: // parse results for doubls must be always Double
1748: for (int i = 0; i < doubles.length; i++) {
1749: try {
1750: Number n = nf.parse(doubles[i]);
1751: if (!(n instanceof Double)) {
1752: errln("FAIL: parse does not return Double instance");
1753: }
1754: } catch (ParseException e) {
1755: errln("parse of '" + doubles[i] + "' threw exception: "
1756: + e);
1757: }
1758: }
1759:
1760: // force this DecimalFormat to return BigDecimal
1761: nf.setParseBigDecimal(true);
1762: if (!nf.isParseBigDecimal()) {
1763: errln("FAIL: isParseBigDecimal() must return true");
1764: }
1765:
1766: // isParseBigDecimal() is true
1767: for (int i = 0; i < defaultNonBigDecimals.length; i++) {
1768: try {
1769: Number n = nf.parse(defaultNonBigDecimals[i]);
1770: if (!(n instanceof BigDecimal)) {
1771: errln("FAIL: parse does not return BigDecimal instance");
1772: }
1773: } catch (ParseException e) {
1774: errln("parse of '" + defaultNonBigDecimals[i]
1775: + "' threw exception: " + e);
1776: }
1777: }
1778: // parse results for doubls must be always Double
1779: for (int i = 0; i < doubles.length; i++) {
1780: try {
1781: Number n = nf.parse(doubles[i]);
1782: if (!(n instanceof Double)) {
1783: errln("FAIL: parse does not return Double instance");
1784: }
1785: } catch (ParseException e) {
1786: errln("parse of '" + doubles[i] + "' threw exception: "
1787: + e);
1788: }
1789: }
1790: }
1791:
1792: public void TestJB5358() {
1793: int numThreads = 10;
1794: String numstr = "12345";
1795: double expected = 12345;
1796: DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
1797: DecimalFormat fmt = new DecimalFormat("#.#", sym);
1798: ArrayList errors = new ArrayList();
1799:
1800: ParseThreadJB5358[] threads = new ParseThreadJB5358[numThreads];
1801: for (int i = 0; i < numThreads; i++) {
1802: threads[i] = new ParseThreadJB5358((DecimalFormat) fmt
1803: .clone(), numstr, expected, errors);
1804: threads[i].start();
1805: }
1806: for (int i = 0; i < numThreads; i++) {
1807: try {
1808: threads[i].join();
1809: } catch (InterruptedException ie) {
1810: ie.printStackTrace();
1811: }
1812: }
1813: if (errors.size() != 0) {
1814: StringBuffer errBuf = new StringBuffer();
1815: for (int i = 0; i < errors.size(); i++) {
1816: errBuf.append((String) errors.get(i));
1817: errBuf.append("\n");
1818: }
1819: errln("FAIL: " + errBuf);
1820: }
1821: }
1822:
1823: static private class ParseThreadJB5358 extends Thread {
1824: private DecimalFormat decfmt;
1825: private String numstr;
1826: private double expect;
1827: private ArrayList errors;
1828:
1829: public ParseThreadJB5358(DecimalFormat decfmt, String numstr,
1830: double expect, ArrayList errors) {
1831: this .decfmt = decfmt;
1832: this .numstr = numstr;
1833: this .expect = expect;
1834: this .errors = errors;
1835: }
1836:
1837: public void run() {
1838: for (int i = 0; i < 10000; i++) {
1839: try {
1840: Number n = decfmt.parse(numstr);
1841: if (n.doubleValue() != expect) {
1842: synchronized (errors) {
1843: errors.add(new String(
1844: "Bad parse result - expected:"
1845: + expect + " actual:"
1846: + n.doubleValue()));
1847: }
1848: }
1849: } catch (Throwable t) {
1850: synchronized (errors) {
1851: errors.add(new String(t.getClass().getName()
1852: + " - " + t.getMessage()));
1853: }
1854: }
1855: }
1856: }
1857: }
1858: }
|