| /***************************************************************************************** |
| * |
| * Copyright (C) 1996-2013, International Business Machines |
| * Corporation and others. All Rights Reserved. |
| **/ |
| |
| /** |
| * Port From: JDK 1.4b1 : java.text.Format.NumberRegression |
| * Source File: java/text/format/NumberRegression.java |
| **/ |
| |
| /** |
| * @test 1.49 01/05/21 |
| * @bug 4052223 4059870 4061302 4062486 4066646 4068693 4070798 4071005 4071014 |
| * 4071492 4071859 4074454 4074620 4075713 4083018 4086575 4087244 4087245 |
| * 4087251 4087535 4088161 4088503 4090489 4090504 4092480 4092561 4095713 |
| * 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840 |
| * 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198 |
| * 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742 |
| * 4217661 4243011 4243108 4330377 4233840 |
| * @summary Regression tests for NumberFormat and associated classes |
| */ |
| |
| package com.ibm.icu.dev.test.format; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InvalidObjectException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.math.BigInteger; |
| import java.text.FieldPosition; |
| import java.text.ParseException; |
| import java.text.ParsePosition; |
| import java.util.Date; |
| import java.util.Locale; |
| |
| import com.ibm.icu.impl.ICUResourceBundle; |
| import com.ibm.icu.text.DateFormat; |
| import com.ibm.icu.text.DecimalFormat; |
| import com.ibm.icu.text.DecimalFormatSymbols; |
| import com.ibm.icu.text.NumberFormat; |
| import com.ibm.icu.util.GregorianCalendar; |
| import com.ibm.icu.util.ULocale; |
| import com.ibm.icu.util.VersionInfo; |
| |
| public class NumberRegression extends com.ibm.icu.dev.test.TestFmwk { |
| |
| public static void main(String[] args) throws Exception { |
| new NumberRegression().run(args); |
| } |
| |
| private static final char EURO = '\u20ac'; |
| |
| /** |
| * NumberFormat.equals comparing with null should always return false. |
| */ |
| public void Test4075713(){ |
| |
| try { |
| MyNumberFormatTest tmp = new MyNumberFormatTest(); |
| if (!tmp.equals(null)) |
| logln("NumberFormat.equals passed"); |
| } catch (NullPointerException e) { |
| errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception"); |
| } |
| } |
| |
| /** |
| * NumberFormat.equals comparing two obj equal even the setGroupingUsed |
| * flag is different. |
| */ |
| public void Test4074620() { |
| |
| MyNumberFormatTest nf1 = new MyNumberFormatTest(); |
| MyNumberFormatTest nf2 = new MyNumberFormatTest(); |
| |
| nf1.setGroupingUsed(false); |
| nf2.setGroupingUsed(true); |
| |
| if (nf1.equals(nf2)) errln("Test for bug 4074620 failed"); |
| else logln("Test for bug 4074620 passed."); |
| return; |
| } |
| |
| |
| /** |
| * DecimalFormat.format() incorrectly uses maxFractionDigits setting. |
| */ |
| |
| public void Test4088161 (){ |
| DecimalFormat df = new DecimalFormat(); |
| double d = 100; |
| df.setMinimumFractionDigits(0); |
| df.setMaximumFractionDigits(16); |
| StringBuffer sBuf1 = new StringBuffer(""); |
| FieldPosition fp1 = new FieldPosition(0); |
| logln("d = " + d); |
| logln("maxFractionDigits = " + df.getMaximumFractionDigits()); |
| logln(" format(d) = '" + df.format(d, sBuf1, fp1) + "'"); |
| df.setMaximumFractionDigits(17); |
| StringBuffer sBuf2 = new StringBuffer(""); |
| FieldPosition fp2 = new FieldPosition(0); |
| logln("maxFractionDigits = " + df.getMaximumFractionDigits()); |
| df.format(d, sBuf2, fp2); |
| if (!sBuf2.toString().equals("100")) |
| errln(" format(d) = '" + sBuf2 + "'"); |
| } |
| /** |
| * DecimalFormatSymbols should be cloned in the ctor DecimalFormat. |
| * DecimalFormat(String, DecimalFormatSymbols). |
| */ |
| public void Test4087245 (){ |
| DecimalFormatSymbols symbols = new DecimalFormatSymbols(); |
| DecimalFormat df = new DecimalFormat("#,##0.0", symbols); |
| long n = 123; |
| StringBuffer buf1 = new StringBuffer(); |
| StringBuffer buf2 = new StringBuffer(); |
| logln("format(" + n + ") = " + |
| df.format(n, buf1, new FieldPosition(0))); |
| symbols.setDecimalSeparator('p'); // change value of field |
| logln("format(" + n + ") = " + |
| df.format(n, buf2, new FieldPosition(0))); |
| if (!buf1.toString().equals(buf2.toString())) |
| errln("Test for bug 4087245 failed"); |
| } |
| /** |
| * DecimalFormat.format() incorrectly formats 0.0 |
| */ |
| public void Test4087535 () |
| { |
| DecimalFormat df = new DecimalFormat(); |
| df.setMinimumIntegerDigits(0); |
| |
| double n = 0; |
| String buffer = new String(); |
| buffer = df.format(n); |
| if (buffer.length() == 0) |
| errln(n + ": '" + buffer + "'"); |
| n = 0.1; |
| buffer = df.format(n); |
| if (buffer.length() == 0) |
| errln(n + ": '" + buffer + "'"); |
| } |
| |
| /** |
| * DecimalFormat.format fails when groupingSize is set to 0. |
| */ |
| public void Test4088503 (){ |
| DecimalFormat df = new DecimalFormat(); |
| df.setGroupingSize(0); |
| StringBuffer sBuf = new StringBuffer(""); |
| FieldPosition fp = new FieldPosition(0); |
| try { |
| logln(df.format(123, sBuf, fp).toString()); |
| } catch (Exception foo) { |
| errln("Test for bug 4088503 failed."); |
| } |
| |
| } |
| /** |
| * NumberFormat.getCurrencyInstance is wrong. |
| */ |
| public void Test4066646 () { |
| //float returnfloat = 0.0f; //The variable is never used |
| assignFloatValue(2.04f); |
| assignFloatValue(2.03f); |
| assignFloatValue(2.02f); |
| assignFloatValue(0.0f); |
| } |
| |
| public float assignFloatValue(float returnfloat) |
| { |
| logln(" VALUE " + returnfloat); |
| NumberFormat nfcommon = NumberFormat.getCurrencyInstance(Locale.US); |
| nfcommon.setGroupingUsed(false); |
| |
| String stringValue = nfcommon.format(returnfloat).substring(1); |
| if (Float.valueOf(stringValue).floatValue() != returnfloat) |
| errln(" DISPLAYVALUE " + stringValue); |
| return returnfloat; |
| } // End Of assignFloatValue() |
| |
| /** |
| * DecimalFormat throws exception when parsing "0" |
| */ |
| public void Test4059870() { |
| DecimalFormat format = new DecimalFormat("00"); |
| try { |
| logln(format.parse("0").toString()); |
| } catch (Exception e) { errln("Test for bug 4059870 failed : " + e); } |
| } |
| /** |
| * DecimalFormatSymbol.equals should always return false when |
| * comparing with null. |
| */ |
| |
| public void Test4083018 (){ |
| DecimalFormatSymbols dfs = new DecimalFormatSymbols(); |
| try { |
| if (!dfs.equals(null)) |
| logln("Test Passed!"); |
| } catch (Exception foo) { |
| errln("Test for bug 4083018 failed => Message : " + foo.getMessage()); |
| } |
| } |
| /** |
| * DecimalFormat does not round up correctly. |
| */ |
| public void Test4071492 (){ |
| double x = 0.00159999; |
| NumberFormat nf = NumberFormat.getInstance(); |
| nf.setMaximumFractionDigits(4); |
| String out = nf.format(x); |
| logln("0.00159999 formats with 4 fractional digits to " + out); |
| String expected = "0.0016"; |
| if (!out.equals(expected)) |
| errln("FAIL: Expected " + expected); |
| } |
| |
| /** |
| * A space as a group separator for localized pattern causes |
| * wrong format. WorkAround : use non-breaking space. |
| */ |
| public void Test4086575() { |
| |
| NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE); |
| logln("nf toPattern1: " + ((DecimalFormat)nf).toPattern()); |
| logln("nf toLocPattern1: " + ((DecimalFormat)nf).toLocalizedPattern()); |
| |
| // No group separator |
| logln("...applyLocalizedPattern ###,00;(###,00) "); |
| ((DecimalFormat)nf).applyLocalizedPattern("###,00;(###,00)"); |
| logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); |
| logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); |
| |
| logln("nf: " + nf.format(1234)); // 1234,00 |
| logln("nf: " + nf.format(-1234)); // (1234,00) |
| |
| // Space as group separator |
| |
| logln("...applyLocalizedPattern # ###,00;(# ###,00) "); |
| ((DecimalFormat)nf).applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)"); |
| logln("nf toPattern2: " + ((DecimalFormat)nf).toPattern()); |
| logln("nf toLocPattern2: " + ((DecimalFormat)nf).toLocalizedPattern()); |
| String buffer = nf.format(1234); |
| if (!buffer.equals("1\u00a0234,00")) |
| errln("nf : " + buffer); // Expect 1 234,00 |
| buffer = nf.format(-1234); |
| if (!buffer.equals("(1\u00a0234,00)")) |
| errln("nf : " + buffer); // Expect (1 234,00) |
| |
| // Erroneously prints: |
| // 1234,00 , |
| // (1234,00 ,) |
| |
| } |
| /** |
| * DecimalFormat.parse returns wrong value |
| */ |
| public void Test4068693() |
| { |
| logln("----- Test Application -----"); |
| //ParsePosition pos; |
| DecimalFormat df = new DecimalFormat(); |
| Number d = df.parse("123.55456", new ParsePosition(0)); |
| if (!d.toString().equals("123.55456")) { |
| errln("Result -> " + d.doubleValue()); |
| } |
| } |
| |
| /* bugs 4069754, 4067878 |
| * null pointer thrown when accessing a deserialized DecimalFormat |
| * object. |
| */ |
| public void Test4069754() throws Exception |
| { |
| //try { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| ObjectOutputStream oos = new ObjectOutputStream(baos); |
| myformat it = new myformat(); |
| logln(it.Now()); |
| oos.writeObject(it); |
| oos.flush(); |
| baos.close(); |
| logln("Save OK!"); |
| byte [] bytes = baos.toByteArray(); |
| ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); |
| myformat o = (myformat)ois.readObject(); |
| ois.close(); |
| it.Now(); |
| logln("Load OK!"); |
| if (!o._dateFormat.equals(it._dateFormat)) { |
| throw new Exception("The saved and loaded object are not equals!"); |
| } |
| logln("Compare OK!"); |
| //} catch (Exception foo) { |
| //errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); |
| //} |
| } |
| |
| /** |
| * DecimalFormat.applyPattern(String) allows illegal patterns |
| */ |
| public void Test4087251 (){ |
| DecimalFormat df = new DecimalFormat(); |
| try { |
| df.applyPattern("#.#.#"); |
| logln("toPattern() returns \"" + df.toPattern() + "\""); |
| errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException"); |
| } catch (IllegalArgumentException e) { |
| logln("Caught Illegal Argument Error !"); |
| } |
| // Second test; added 5/11/98 when reported to fail on 1.2b3 |
| try { |
| df.applyPattern("#0.0#0#0"); |
| logln("toPattern() returns \"" + df.toPattern() + "\""); |
| errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException"); |
| } catch (IllegalArgumentException e) { |
| logln("Ok - IllegalArgumentException for #0.0#0#0"); |
| } |
| } |
| |
| /** |
| * DecimalFormat.format() loses precision |
| */ |
| public void Test4090489 (){ |
| DecimalFormat df = new DecimalFormat(); |
| df.setMinimumFractionDigits(10); |
| df.setGroupingUsed(false); |
| double d = 1.000000000000001E7; |
| java.math.BigDecimal bd = new java.math.BigDecimal(d); |
| StringBuffer sb = new StringBuffer(""); |
| FieldPosition fp = new FieldPosition(0); |
| logln("d = " + d); |
| logln("BigDecimal.toString(): " + bd.toString()); |
| df.format(d, sb, fp); |
| if (!sb.toString().equals("10000000.0000000100")) { |
| errln("DecimalFormat.format(): " + sb.toString()); |
| } |
| } |
| |
| /** |
| * DecimalFormat.format() loses precision |
| */ |
| public void Test4090504 () |
| { |
| double d = 1; |
| logln("d = " + d); |
| DecimalFormat df = new DecimalFormat(); |
| StringBuffer sb; |
| FieldPosition fp; |
| try { |
| for (int i = 17; i <= 20; i++) { |
| df.setMaximumFractionDigits(i); |
| sb = new StringBuffer(""); |
| fp = new FieldPosition(0); |
| logln(" getMaximumFractionDigits() = " + i); |
| logln(" formated: " + df.format(d, sb, fp)); |
| } |
| } catch (Exception foo) { |
| errln("Bug 4090504 regression test failed. Message : " + foo.getMessage()); |
| } |
| } |
| /** |
| * DecimalFormat.parse(String str, ParsePosition pp) loses precision |
| */ |
| public void Test4095713 () |
| { |
| DecimalFormat df = new DecimalFormat(); |
| String str = "0.1234"; |
| Double d1 = new Double(str); |
| Number d2 = df.parse(str, new ParsePosition(0)); |
| logln(d1.toString()); |
| if (d2.doubleValue() != d1.doubleValue()) |
| errln("Bug 4095713 test failed, new double value : " + d2.doubleValue()); |
| } |
| |
| /** |
| * DecimalFormat.parse() fails when multiplier is not set to 1 |
| */ |
| public void Test4092561 () |
| { |
| Locale savedLocale = Locale.getDefault(); |
| Locale.setDefault(Locale.US); |
| DecimalFormat df = new DecimalFormat(); |
| String str = Long.toString(Long.MIN_VALUE); |
| logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); |
| df.setMultiplier(100); |
| Number num = df.parse(str, new ParsePosition(0)); |
| if (num.doubleValue() != -9.223372036854776E16) { |
| errln("Bug 4092561 test failed when multiplier is set to not 1."); |
| } |
| Locale.setDefault(savedLocale); |
| } |
| |
| /** |
| * DecimalFormat: Negative format ignored. |
| */ |
| public void Test4092480 () |
| { |
| DecimalFormat dfFoo = new DecimalFormat("000"); |
| |
| try { |
| dfFoo.applyPattern("0000;-000"); |
| if (!dfFoo.toPattern().equals("#0000")) |
| errln("dfFoo.toPattern : " + dfFoo.toPattern()); |
| logln(dfFoo.format(42)); |
| logln(dfFoo.format(-42)); |
| dfFoo.applyPattern("000;-000"); |
| if (!dfFoo.toPattern().equals("#000")) |
| errln("dfFoo.toPattern : " + dfFoo.toPattern()); |
| logln(dfFoo.format(42)); |
| logln(dfFoo.format(-42)); |
| |
| dfFoo.applyPattern("000;-0000"); |
| if (!dfFoo.toPattern().equals("#000")) |
| errln("dfFoo.toPattern : " + dfFoo.toPattern()); |
| logln(dfFoo.format(42)); |
| logln(dfFoo.format(-42)); |
| |
| dfFoo.applyPattern("0000;-000"); |
| if (!dfFoo.toPattern().equals("#0000")) |
| errln("dfFoo.toPattern : " + dfFoo.toPattern()); |
| logln(dfFoo.format(42)); |
| logln(dfFoo.format(-42)); |
| } catch (Exception foo) { |
| errln("Message " + foo.getMessage()); |
| } |
| } |
| /** |
| * NumberFormat.getCurrencyInstance() produces format that uses |
| * decimal separator instead of monetary decimal separator. |
| * |
| * Rewrote this test not to depend on the actual pattern. Pattern should |
| * never contain the monetary separator! Decimal separator in pattern is |
| * interpreted as monetary separator if currency symbol is seen! |
| */ |
| public void Test4087244 () { |
| Locale de = new Locale("pt", "PT"); |
| DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(de); |
| DecimalFormatSymbols sym = df.getDecimalFormatSymbols(); |
| sym.setMonetaryDecimalSeparator('$'); |
| df.setDecimalFormatSymbols(sym); |
| char decSep = sym.getDecimalSeparator(); |
| char monSep = sym.getMonetaryDecimalSeparator(); |
| //char zero = sym.getZeroDigit(); //The variable is never used |
| if (decSep == monSep) { |
| errln("ERROR in test: want decimal sep != monetary sep"); |
| } else { |
| df.setMinimumIntegerDigits(1); |
| df.setMinimumFractionDigits(2); |
| String str = df.format(1.23); |
| String monStr = "1" + monSep + "23"; |
| String decStr = "1" + decSep + "23"; |
| if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) { |
| logln("OK: 1.23 -> \"" + str + "\" contains \"" + |
| monStr + "\" and not \"" + decStr + '"'); |
| } else { |
| errln("FAIL: 1.23 -> \"" + str + "\", should contain \"" + |
| monStr + |
| "\" and not \"" + decStr + '"'); |
| } |
| } |
| } |
| /** |
| * Number format data rounding errors for locale FR |
| */ |
| public void Test4070798 () { |
| NumberFormat formatter; |
| String tempString; |
| /* User error : |
| String expectedDefault = "-5\u00a0789,987"; |
| String expectedCurrency = "5\u00a0789,98\u00a0F"; |
| String expectedPercent = "-578\u00a0998%"; |
| */ |
| String expectedDefault = "-5\u00a0789,988"; |
| String expectedCurrency = "5\u00a0789,99\u00a0" + EURO; // euro |
| String expectedPercent = "-578\u00a0999\u00a0%"; |
| |
| formatter = NumberFormat.getNumberInstance(Locale.FRANCE); |
| tempString = formatter.format (-5789.9876); |
| |
| if (tempString.equals(expectedDefault)) { |
| logln ("Bug 4070798 default test passed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedDefault + |
| " Received " + tempString ); |
| } |
| |
| |
| formatter = NumberFormat.getCurrencyInstance(Locale.FRANCE); |
| tempString = formatter.format( 5789.9876 ); |
| |
| if (tempString.equals(expectedCurrency) ) { |
| logln ("Bug 4070798 currency test assed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedCurrency + |
| " Received " + tempString ); |
| } |
| |
| |
| formatter = NumberFormat.getPercentInstance(Locale.FRANCE); |
| tempString = formatter.format (-5789.9876); |
| |
| if (tempString.equals(expectedPercent) ) { |
| logln ("Bug 4070798 percentage test passed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedPercent + |
| " Received " + tempString ); |
| } |
| } |
| /** |
| * Data rounding errors for French (Canada) locale |
| */ |
| public void Test4071005 () { |
| |
| NumberFormat formatter; |
| String tempString; |
| /* user error : |
| String expectedDefault = "-5 789,987"; |
| String expectedCurrency = "5 789,98\u00a0$"; |
| String expectedPercent = "-578 998%"; |
| */ |
| String expectedDefault = "-5\u00a0789,988"; |
| String expectedCurrency = "5\u00a0789,99\u00a0$"; |
| String expectedPercent = "-578\u00a0999\u00A0%"; |
| |
| formatter = NumberFormat.getNumberInstance(Locale.CANADA_FRENCH); |
| tempString = formatter.format (-5789.9876); |
| if (tempString.equals(expectedDefault)) { |
| logln ("Bug 4071005 default test passed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedDefault + |
| " Received " + tempString ); |
| } |
| |
| formatter = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH); |
| tempString = formatter.format( 5789.9876 ) ; |
| |
| if (tempString.equals(expectedCurrency) ) { |
| logln ("Bug 4071005 currency test passed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedCurrency + |
| " Received " + tempString ); |
| } |
| formatter = NumberFormat.getPercentInstance(Locale.CANADA_FRENCH); |
| tempString = formatter.format (-5789.9876); |
| |
| if (tempString.equals(expectedPercent) ) { |
| logln ("Bug 4071005 percentage test passed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedPercent + |
| " Received " + tempString ); |
| } |
| } |
| |
| /** |
| * Data rounding errors for German (Germany) locale |
| */ |
| public void Test4071014 () { |
| NumberFormat formatter; |
| String tempString; |
| /* user error : |
| String expectedDefault = "-5.789,987"; |
| String expectedCurrency = "5.789,98\u00a0DM"; |
| String expectedPercent = "-578.998%"; |
| */ |
| String expectedDefault = "-5.789,988"; |
| String expectedCurrency = "5.789,99\u00a0" + EURO; |
| String expectedPercent = "-578.999\u00a0%"; |
| |
| formatter = NumberFormat.getNumberInstance(Locale.GERMANY); |
| tempString = formatter.format (-5789.9876); |
| |
| if (tempString.equals(expectedDefault)) { |
| logln ("Bug 4071014 default test passed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedDefault + |
| " Received " + tempString ); |
| } |
| |
| formatter = NumberFormat.getCurrencyInstance(Locale.GERMANY); |
| tempString = formatter.format( 5789.9876 ) ; |
| |
| if (tempString.equals(expectedCurrency) ) { |
| logln ("Bug 4071014 currency test passed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedCurrency + |
| " Received " + tempString ); |
| } |
| |
| formatter = NumberFormat.getPercentInstance(Locale.GERMANY); |
| tempString = formatter.format (-5789.9876); |
| |
| if (tempString.equals(expectedPercent) ) { |
| logln ("Bug 4071014 percentage test passed."); |
| } else { |
| errln("Failed:" + |
| " Expected " + expectedPercent + |
| " Received " + tempString ); |
| } |
| |
| } |
| /** |
| * Data rounding errors for Italian locale number formats |
| * Note- with the Euro, there is no need for currency rounding anymore |
| */ |
| public void Test4071859 () { |
| NumberFormat formatter; |
| String tempString; |
| /* user error : |
| String expectedDefault = "-5.789,987"; |
| String expectedCurrency = "-L.\u00a05.789,98"; |
| String expectedPercent = "-578.998%"; |
| */ |
| String expectedDefault = "-5.789,988"; |
| String expectedCurrency = "-5.789,99\u00A0" + EURO; |
| String expectedPercent = "-578.999%"; |
| |
| formatter = NumberFormat.getNumberInstance(Locale.ITALY); |
| tempString = formatter.format (-5789.9876); |
| |
| if (tempString.equals(expectedDefault)) { |
| logln ("Bug 4071859 default test passed."); |
| } else { |
| errln("a) Failed:" + |
| " Expected " + expectedDefault + |
| " Received " + tempString ); |
| } |
| |
| formatter = NumberFormat.getCurrencyInstance(Locale.ITALY); |
| tempString = formatter.format( -5789.9876 ) ; |
| |
| if (tempString.equals(expectedCurrency) ) { |
| logln ("Bug 4071859 currency test passed."); |
| } else { |
| errln("b) Failed:" + |
| " Expected " + expectedCurrency + |
| " Received " + tempString ); |
| } |
| |
| formatter = NumberFormat.getPercentInstance(Locale.ITALY); |
| tempString = formatter.format (-5789.9876); |
| |
| if (tempString.equals(expectedPercent) ) { |
| logln ("Bug 4071859 percentage test passed."); |
| } else { |
| errln("c) Failed:" + |
| " Expected " + expectedPercent + |
| " Received " + tempString ); |
| } |
| |
| } |
| /* bug 4071859 |
| * Test rounding for nearest even. |
| */ |
| public void Test4093610() |
| { |
| DecimalFormat df = new DecimalFormat("#0.#"); |
| roundingTest(df, 12.35, "12.4"); |
| roundingTest(df, 12.45, "12.4"); |
| roundingTest(df, 12.452,"12.5"); |
| roundingTest(df, 12.55, "12.6"); |
| roundingTest(df, 12.65, "12.6"); |
| roundingTest(df, 12.652,"12.7"); |
| roundingTest(df, 12.75, "12.8"); |
| roundingTest(df, 12.752,"12.8"); |
| roundingTest(df, 12.85, "12.8"); |
| roundingTest(df, 12.852,"12.9"); |
| roundingTest(df, 12.95, "13"); |
| roundingTest(df, 12.952,"13"); |
| |
| } |
| void roundingTest(DecimalFormat df, double x, String expected) |
| { |
| String out = df.format(x); |
| logln("" + x + " formats with 1 fractional digits to " + out); |
| if (!out.equals(expected)) errln("FAIL: Expected " + expected); |
| } |
| /** |
| * Tests the setMaximumFractionDigits limit. |
| */ |
| public void Test4098741() |
| { |
| try { |
| NumberFormat fmt = NumberFormat.getPercentInstance(); |
| fmt.setMaximumFractionDigits(20); |
| logln(fmt.format(.001)); |
| } catch (Exception foo) { |
| warnln("Bug 4098471 failed with exception thrown : " + foo.getMessage()); |
| } |
| } |
| /** |
| * Tests illegal pattern exception. |
| * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated. |
| * Part2 has been fixed. |
| */ |
| public void Test4074454() |
| { |
| try { |
| DecimalFormat fmt = new DecimalFormat("#,#00.00;-#.#"); |
| logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used" |
| logln("Inconsistent negative pattern is fine."); |
| DecimalFormat newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces"); |
| String tempString = newFmt.format(3456.78); |
| if (!tempString.equals("3,456.78 p'ieces")) |
| errln("Failed! 3456.78 p'ieces expected, but got : " + tempString); |
| } catch (Exception foo) { |
| warnln("An exception was thrown for any inconsistent negative pattern."); |
| } |
| } |
| /** |
| * Tests all different comments. |
| * Response to some comments : |
| * [1] DecimalFormat.parse API documentation is more than just one line. |
| * This is not a reproducable doc error in 116 source code. |
| * [2] See updated javadoc. |
| * [3] Fixed. |
| * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails, |
| * a null object will be returned. The unchanged parse position also |
| * reflects an error. |
| * NumberFormat.parse(String) : If parsing fails, an ParseException |
| * will be thrown. |
| * See updated javadoc for more details. |
| * [5] See updated javadoc. |
| * [6] See updated javadoc. |
| * [7] This is a correct behavior if the DateFormat object is linient. |
| * Otherwise, an IllegalArgumentException will be thrown when formatting |
| * "January 35". See GregorianCalendar class javadoc for more details. |
| */ |
| public void Test4099404() |
| { |
| try { |
| DecimalFormat fmt = new DecimalFormat("000.0#0"); |
| logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used" |
| errln("Bug 4099404 failed applying illegal pattern \"000.0#0\""); |
| } catch (Exception foo) { |
| logln("Bug 4099404 pattern \"000.0#0\" passed"); |
| } |
| try { |
| DecimalFormat fmt = new DecimalFormat("0#0.000"); |
| logln("format 3456.78: " + fmt.format(3456.78)); //fix "The variable 'fmt' is never used" |
| errln("Bug 4099404 failed applying illegal pattern \"0#0.000\""); |
| } catch (Exception foo) { |
| logln("Bug 4099404 pattern \"0#0.000\" passed"); |
| } |
| } |
| /** |
| * DecimalFormat.applyPattern doesn't set minimum integer digits |
| */ |
| public void Test4101481() |
| { |
| DecimalFormat sdf = new DecimalFormat("#,##0"); |
| if (sdf.getMinimumIntegerDigits() != 1) |
| errln("Minimum integer digits : " + sdf.getMinimumIntegerDigits()); |
| } |
| /** |
| * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition(). |
| */ |
| public void Test4052223() |
| { |
| try { |
| DecimalFormat fmt = new DecimalFormat("#,#00.00"); |
| Number num = fmt.parse("abc3"); |
| errln("Bug 4052223 failed : can't parse string \"a\". Got " + num); |
| } catch (ParseException foo) { |
| logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset()); |
| } |
| } |
| /** |
| * API tests for API addition request A9. |
| */ |
| public void Test4061302() |
| { |
| DecimalFormatSymbols fmt = new DecimalFormatSymbols(); |
| String currency = fmt.getCurrencySymbol(); |
| String intlCurrency = fmt.getInternationalCurrencySymbol(); |
| char monDecSeparator = fmt.getMonetaryDecimalSeparator(); |
| if (currency.equals("") || |
| intlCurrency.equals("") || |
| monDecSeparator == 0) { |
| errln("getCurrencySymbols failed, got empty string."); |
| } |
| logln("Before set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); |
| fmt.setCurrencySymbol("XYZ"); |
| fmt.setInternationalCurrencySymbol("ABC"); |
| fmt.setMonetaryDecimalSeparator('*'); |
| currency = fmt.getCurrencySymbol(); |
| intlCurrency = fmt.getInternationalCurrencySymbol(); |
| monDecSeparator = fmt.getMonetaryDecimalSeparator(); |
| if (!currency.equals("XYZ") || |
| !intlCurrency.equals("ABC") || |
| monDecSeparator != '*') { |
| errln("setCurrencySymbols failed."); |
| } |
| logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparator); |
| } |
| /** |
| * API tests for API addition request A23. FieldPosition.getBeginIndex and |
| * FieldPosition.getEndIndex. |
| */ |
| public void Test4062486() |
| { |
| DecimalFormat fmt = new DecimalFormat("#,##0.00"); |
| StringBuffer formatted = new StringBuffer(); |
| FieldPosition field = new FieldPosition(0); |
| Double num = new Double(1234.5); |
| fmt.format(num, formatted, field); |
| if (field.getBeginIndex() != 0 && field.getEndIndex() != 5) |
| errln("Format 1234.5 failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); |
| field.setBeginIndex(7); |
| field.setEndIndex(4); |
| if (field.getBeginIndex() != 7 && field.getEndIndex() != 4) |
| errln("Set begin/end field indexes failed. Begin index: " + field.getBeginIndex() + " End index: " + field.getEndIndex()); |
| } |
| |
| /** |
| * DecimalFormat.parse incorrectly works with a group separator. |
| */ |
| public void Test4108738() |
| { |
| |
| DecimalFormat df = new DecimalFormat("#,##0.###", new |
| DecimalFormatSymbols(java.util.Locale.US)); |
| String text = "1.222,111"; |
| Number num = df.parse(text,new ParsePosition(0)); |
| if (!num.toString().equals("1.222")) |
| errln("\"" + text + "\" is parsed as " + num); |
| text = "1.222x111"; |
| num = df.parse(text,new ParsePosition(0)); |
| if (!num.toString().equals("1.222")) |
| errln("\"" + text + "\" is parsed as " + num); |
| } |
| |
| /** |
| * DecimalFormat.format() incorrectly formats negative doubles. |
| */ |
| public void Test4106658() |
| { |
| Locale savedLocale = Locale.getDefault(); |
| Locale.setDefault(Locale.US); |
| DecimalFormat df = new DecimalFormat(); // Corrected; see 4147706 |
| double d1 = -0.0; |
| double d2 = -0.0001; |
| StringBuffer buffer = new StringBuffer(); |
| logln("pattern: \"" + df.toPattern() + "\""); |
| df.format(d1, buffer, new FieldPosition(0)); |
| if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 |
| errln(d1 + " is formatted as " + buffer); |
| } |
| buffer.setLength(0); |
| df.format(d2, buffer, new FieldPosition(0)); |
| if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 |
| errln(d2 + " is formatted as " + buffer); |
| } |
| Locale.setDefault(savedLocale); |
| } |
| |
| /** |
| * DecimalFormat.parse returns 0 if string parameter is incorrect. |
| */ |
| public void Test4106662() |
| { |
| DecimalFormat df = new DecimalFormat(); |
| String text = "x"; |
| ParsePosition pos1 = new ParsePosition(0), pos2 = new ParsePosition(0); |
| |
| logln("pattern: \"" + df.toPattern() + "\""); |
| Number num = df.parse(text, pos1); |
| if (num != null) { |
| errln("Test Failed: \"" + text + "\" is parsed as " + num); |
| } |
| df = null; |
| df = new DecimalFormat("$###.00"); |
| num = df.parse("$", pos2); |
| if (num != null){ |
| errln("Test Failed: \"$\" is parsed as " + num); |
| } |
| } |
| |
| /** |
| * NumberFormat.parse doesn't return null |
| */ |
| public void Test4114639() |
| { |
| NumberFormat format = NumberFormat.getInstance(); |
| String text = "time 10:x"; |
| ParsePosition pos = new ParsePosition(8); |
| Number result = format.parse(text, pos); |
| if (result != null) errln("Should return null but got : " + result); // Should be null; it isn't |
| } |
| |
| /** |
| * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG. |
| */ |
| public void Test4106664() |
| { |
| DecimalFormat df = new DecimalFormat(); |
| long n = 1234567890123456L; |
| int m = 12345678; |
| BigInteger bigN = BigInteger.valueOf(n); |
| bigN = bigN.multiply(BigInteger.valueOf(m)); |
| df.setMultiplier(m); |
| df.setGroupingUsed(false); |
| logln("formated: " + |
| df.format(n, new StringBuffer(), new FieldPosition(0))); |
| logln("expected: " + bigN.toString()); |
| } |
| /** |
| * DecimalFormat.format incorrectly formats -0.0. |
| */ |
| public void Test4106667() |
| { |
| Locale savedLocale = Locale.getDefault(); |
| Locale.setDefault(Locale.US); |
| DecimalFormat df = new DecimalFormat(); |
| df.setPositivePrefix("+"); |
| double d = -0.0; |
| logln("pattern: \"" + df.toPattern() + "\""); |
| StringBuffer buffer = new StringBuffer(); |
| df.format(d, buffer, new FieldPosition(0)); |
| if (!buffer.toString().equals("-0")) { // Corrected; see 4147706 |
| errln(d + " is formatted as " + buffer); |
| } |
| Locale.setDefault(savedLocale); |
| } |
| |
| /** |
| * DecimalFormat.setMaximumIntegerDigits() works incorrectly. |
| */ |
| public void Test4110936() |
| { |
| NumberFormat nf = NumberFormat.getInstance(); |
| nf.setMaximumIntegerDigits(128); |
| logln("setMaximumIntegerDigits(128)"); |
| if (nf.getMaximumIntegerDigits() != 128) |
| errln("getMaximumIntegerDigits() returns " + |
| nf.getMaximumIntegerDigits()); |
| } |
| |
| /** |
| * Locale data should use generic currency symbol |
| * |
| * 1) Make sure that all currency formats use the generic currency symbol. |
| * 2) Make sure we get the same results using the generic symbol or a |
| * hard-coded one. |
| */ |
| public void Test4122840() |
| { |
| Locale[] locales = NumberFormat.getAvailableLocales(); |
| |
| for (int i = 0; i < locales.length; i++) { |
| ICUResourceBundle rb = (ICUResourceBundle)ICUResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME,locales[i]); |
| |
| // |
| // Get the currency pattern for this locale. We have to fish it |
| // out of the ResourceBundle directly, since DecimalFormat.toPattern |
| // will return the localized symbol, not \00a4 |
| // |
| String pattern = rb.getStringWithFallback("NumberElements/latn/patterns/currencyFormat"); |
| if (pattern.indexOf('\u00A4') == -1 ) { // 'x' not "x" -- workaround bug in IBM JDK 1.4.1 |
| errln("Currency format for " + locales[i] + |
| " does not contain generic currency symbol:" + |
| pattern ); |
| } |
| |
| // Create a DecimalFormat using the pattern we got and format a number |
| DecimalFormatSymbols symbols = new DecimalFormatSymbols(locales[i]); |
| DecimalFormat fmt1 = new DecimalFormat(pattern, symbols); |
| |
| String result1 = fmt1.format(1.111); |
| |
| // |
| // Now substitute in the locale's currency symbol and create another |
| // pattern. Replace the decimal separator with the monetary separator. |
| // |
| //char decSep = symbols.getDecimalSeparator(); //The variable is never used |
| char monSep = symbols.getMonetaryDecimalSeparator(); |
| StringBuffer buf = new StringBuffer(pattern); |
| for (int j = 0; j < buf.length(); j++) { |
| if (buf.charAt(j) == '\u00a4') { |
| String cur = "'" + symbols.getCurrencySymbol() + "'"; |
| buf.replace(j, j+1, cur); |
| j += cur.length() - 1; |
| } |
| } |
| symbols.setDecimalSeparator(monSep); |
| DecimalFormat fmt2 = new DecimalFormat(buf.toString(), symbols); |
| |
| // Actual width of decimal fractions and rounding option are inherited |
| // from the currency, not the pattern itself. So we need to force |
| // maximum/minimumFractionDigits and rounding option for the second |
| // DecimalForamt instance. The fix for ticket#7282 requires this test |
| // code change to make it work properly. |
| fmt2.setMaximumFractionDigits(fmt1.getMaximumFractionDigits()); |
| fmt2.setMinimumFractionDigits(fmt1.getMinimumFractionDigits()); |
| fmt2.setRoundingIncrement(fmt1.getRoundingIncrement()); |
| |
| String result2 = fmt2.format(1.111); |
| |
| // NOTE: en_IN is a special case (ChoiceFormat currency display name) |
| if (!result1.equals(result2) && |
| !locales[i].toString().equals("en_IN")) { |
| errln("Results for " + locales[i] + " differ: " + |
| result1 + " vs " + result2); |
| } |
| } |
| } |
| |
| /** |
| * DecimalFormat.format() delivers wrong string. |
| */ |
| public void Test4125885() |
| { |
| double rate = 12.34; |
| DecimalFormat formatDec = new DecimalFormat ("000.00"); |
| logln("toPattern: " + formatDec.toPattern()); |
| String rateString= formatDec.format(rate); |
| if (!rateString.equals("012.34")) |
| errln("result : " + rateString + " expected : 012.34"); |
| rate = 0.1234; |
| formatDec = null; |
| formatDec = new DecimalFormat ("+000.00%;-000.00%"); |
| logln("toPattern: " + formatDec.toPattern()); |
| rateString= formatDec.format(rate); |
| if (!rateString.equals("+012.34%")) |
| errln("result : " + rateString + " expected : +012.34%"); |
| } |
| |
| /** |
| ** |
| * DecimalFormat produces extra zeros when formatting numbers. |
| */ |
| public void Test4134034() { |
| DecimalFormat nf = new DecimalFormat("##,###,###.00"); |
| |
| String f = nf.format(9.02); |
| if (f.equals("9.02")) logln(f + " ok"); else errln("9.02 -> " + f + "; want 9.02"); |
| |
| f = nf.format(0); |
| if (f.equals(".00")) logln(f + " ok"); else errln("0 -> " + f + "; want .00"); |
| } |
| |
| /** |
| * CANNOT REPRODUCE - This bug could not be reproduced. It may be |
| * a duplicate of 4134034. |
| * |
| * JDK 1.1.6 Bug, did NOT occur in 1.1.5 |
| * Possibly related to bug 4125885. |
| * |
| * This class demonstrates a regression in version 1.1.6 |
| * of DecimalFormat class. |
| * |
| * 1.1.6 Results |
| * Value 1.2 Format #.00 Result '01.20' !!!wrong |
| * Value 1.2 Format 0.00 Result '001.20' !!!wrong |
| * Value 1.2 Format 00.00 Result '0001.20' !!!wrong |
| * Value 1.2 Format #0.0# Result '1.2' |
| * Value 1.2 Format #0.00 Result '001.20' !!!wrong |
| * |
| * 1.1.5 Results |
| * Value 1.2 Format #.00 Result '1.20' |
| * Value 1.2 Format 0.00 Result '1.20' |
| * Value 1.2 Format 00.00 Result '01.20' |
| * Value 1.2 Format #0.0# Result '1.2' |
| * Value 1.2 Format #0.00 Result '1.20' |
| */ |
| public void Test4134300() { |
| String[] DATA = { |
| // Pattern Expected string |
| "#.00", "1.20", |
| "0.00", "1.20", |
| "00.00", "01.20", |
| "#0.0#", "1.2", |
| "#0.00", "1.20", |
| }; |
| for (int i=0; i<DATA.length; i+=2) { |
| String result = new DecimalFormat(DATA[i]).format(1.2); |
| if (!result.equals(DATA[i+1])) { |
| errln("Fail: 1.2 x " + DATA[i] + " = " + result + |
| "; want " + DATA[i+1]); |
| } |
| else { |
| logln("Ok: 1.2 x " + DATA[i] + " = " + result); |
| } |
| } |
| } |
| |
| /** |
| * Empty pattern produces double negative prefix. |
| */ |
| public void Test4140009() { |
| final double IN[] = { 123.456, -123.456 }; |
| final String OUT[] = { "123.456", "-123.456" }; |
| for (int i=0; i<2; ++i) { |
| DecimalFormat f = null; |
| switch (i) { |
| case 0: |
| f = new DecimalFormat("", |
| new DecimalFormatSymbols(Locale.ENGLISH)); |
| break; |
| case 1: |
| f = new DecimalFormat("#.#", |
| new DecimalFormatSymbols(Locale.ENGLISH)); |
| f.applyPattern(""); |
| break; |
| } |
| for (int j=0; j<2; ++j) { |
| assertEquals("<empty pat " + i + ">.format(" + IN[j] + ")", |
| OUT[j], f.format(IN[j])); |
| } |
| } |
| } |
| |
| /** |
| * BigDecimal numbers get their fractions truncated by NumberFormat. |
| */ |
| public void Test4141750() { |
| try { |
| String str = "12345.67"; |
| java.math.BigDecimal bd = new java.math.BigDecimal(str); |
| String sd = NumberFormat.getInstance(Locale.US).format(bd); |
| if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd); |
| } |
| catch (Exception e) { |
| warnln(e.toString()); |
| //e.printStackTrace(); |
| } |
| } |
| |
| /** |
| * DecimalFormat toPattern() doesn't quote special characters or handle |
| * single quotes. |
| */ |
| public void Test4145457() { |
| try { |
| DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(); |
| DecimalFormatSymbols sym = nf.getDecimalFormatSymbols(); |
| sym.setDecimalSeparator('\''); |
| nf.setDecimalFormatSymbols(sym); |
| double pi = 3.14159; |
| |
| String[] PATS = { "#.00 'num''ber'", "''#.00''" }; |
| |
| for (int i=0; i<PATS.length; ++i) { |
| nf.applyPattern(PATS[i]); |
| String out = nf.format(pi); |
| String pat = nf.toPattern(); |
| double val = nf.parse(out).doubleValue(); |
| |
| nf.applyPattern(pat); |
| String out2 = nf.format(pi); |
| String pat2 = nf.toPattern(); |
| double val2 = nf.parse(out2).doubleValue(); |
| |
| if (!pat.equals(pat2)) |
| errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" + |
| pat + "\" vs. \"" + pat2 + "\""); |
| else |
| logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"'); |
| |
| if (val == val2 && out.equals(out2)) { |
| logln("Ok " + pi + " x \"" + PATS[i] + "\" -> \"" + |
| out + "\" -> " + val + " -> \"" + |
| out2 + "\" -> " + val2); |
| } |
| else { |
| errln("Fail " + pi + " x \"" + PATS[i] + "\" -> \"" + |
| out + "\" -> " + val + " -> \"" + |
| out2 + "\" -> " + val2); |
| } |
| } |
| } |
| catch (ParseException e) { |
| errln("Fail: " + e); |
| e.printStackTrace(); |
| } |
| } |
| |
| /** |
| * DecimalFormat.applyPattern() sets minimum integer digits incorrectly. |
| * CANNOT REPRODUCE |
| * This bug is a duplicate of 4139344, which is a duplicate of 4134300 |
| */ |
| public void Test4147295() { |
| DecimalFormat sdf = new DecimalFormat(); |
| String pattern = "#,###"; |
| logln("Applying pattern \"" + pattern + "\""); |
| sdf.applyPattern(pattern); |
| int minIntDig = sdf.getMinimumIntegerDigits(); |
| if (minIntDig != 0) { |
| errln("Test failed"); |
| errln(" Minimum integer digits : " + minIntDig); |
| errln(" new pattern: " + sdf.toPattern()); |
| } else { |
| logln("Test passed"); |
| logln(" Minimum integer digits : " + minIntDig); |
| } |
| } |
| |
| /** |
| * DecimalFormat formats -0.0 as +0.0 |
| * See also older related bug 4106658, 4106667 |
| */ |
| public void Test4147706() { |
| DecimalFormat df = new DecimalFormat("#,##0.0##"); |
| df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.ENGLISH)); |
| double d1 = -0.0; |
| double d2 = -0.0001; |
| StringBuffer f1 = df.format(d1, new StringBuffer(), new FieldPosition(0)); |
| StringBuffer f2 = df.format(d2, new StringBuffer(), new FieldPosition(0)); |
| if (!f1.toString().equals("-0.0")) { |
| errln(d1 + " x \"" + df.toPattern() + "\" is formatted as \"" + f1 + '"'); |
| } |
| if (!f2.toString().equals("-0.0")) { |
| errln(d2 + " x \"" + df.toPattern() + "\" is formatted as \"" + f2 + '"'); |
| } |
| } |
| |
| /** |
| * NumberFormat cannot format Double.MAX_VALUE |
| */ |
| public void Test4162198() { |
| double dbl = Double.MAX_VALUE; |
| NumberFormat f = NumberFormat.getInstance(); |
| f.setMaximumFractionDigits(Integer.MAX_VALUE); |
| f.setMaximumIntegerDigits(Integer.MAX_VALUE); |
| String s = f.format(dbl); |
| logln("The number " + dbl + " formatted to " + s); |
| Number n = null; |
| try { |
| n = f.parse(s); |
| } catch (java.text.ParseException e) { |
| errln("Caught a ParseException:"); |
| e.printStackTrace(); |
| } |
| logln("The string " + s + " parsed as " + n); |
| if (n.doubleValue() != dbl) { |
| errln("Round trip failure"); |
| } |
| } |
| |
| /** |
| * NumberFormat does not parse negative zero. |
| */ |
| public void Test4162852() throws ParseException { |
| for (int i=0; i<2; ++i) { |
| NumberFormat f = (i == 0) ? NumberFormat.getInstance() |
| : NumberFormat.getPercentInstance(); |
| double d = -0.0; |
| String s = f.format(d); |
| double e = f.parse(s).doubleValue(); |
| logln("" + |
| d + " -> " + |
| '"' + s + '"' + " -> " + |
| e); |
| if (e != 0.0 || 1.0/e > 0.0) { |
| logln("Failed to parse negative zero"); |
| } |
| } |
| } |
| |
| /** |
| * NumberFormat truncates data |
| */ |
| public void Test4167494() throws Exception { |
| NumberFormat fmt = NumberFormat.getInstance(Locale.US); |
| |
| double a = Double.MAX_VALUE; |
| String s = fmt.format(a); |
| double b = fmt.parse(s).doubleValue(); |
| boolean match = a == b; |
| if (match) { |
| logln("" + a + " -> \"" + s + "\" -> " + b + " ok"); |
| } else { |
| errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); |
| } |
| |
| // We don't test Double.MIN_VALUE because the locale data for the US |
| // currently doesn't specify enough digits to display Double.MIN_VALUE. |
| // This is correct for now; however, we leave this here as a reminder |
| // in case we want to address this later. |
| if (false) { |
| a = Double.MIN_VALUE; |
| s = fmt.format(a); |
| b = fmt.parse(s).doubleValue(); |
| match = a == b; |
| if (match) { |
| logln("" + a + " -> \"" + s + "\" -> " + b + " ok"); |
| } else { |
| errln("" + a + " -> \"" + s + "\" -> " + b + " FAIL"); |
| } |
| } |
| } |
| |
| /** |
| * DecimalFormat.parse() fails when ParseIntegerOnly set to true |
| */ |
| public void Test4170798() { |
| Locale savedLocale = Locale.getDefault(); |
| Locale.setDefault(Locale.US); |
| DecimalFormat df = new DecimalFormat(); |
| df.setParseIntegerOnly(true); |
| Number n = df.parse("-0.0", new ParsePosition(0)); |
| if (!(n instanceof Double) |
| || n.intValue() != 0) { |
| errln("FAIL: parse(\"-0.0\") returns " + |
| n + " (" + n.getClass().getName() + ')'); |
| } |
| Locale.setDefault(savedLocale); |
| } |
| |
| /** |
| * toPattern only puts the first grouping separator in. |
| */ |
| public void Test4176114() { |
| String[] DATA = { |
| "00", "#00", |
| "000", "#000", // No grouping |
| "#000", "#000", // No grouping |
| "#,##0", "#,##0", |
| "#,000", "#,000", |
| "0,000", "#0,000", |
| "00,000", "#00,000", |
| "000,000", "#,000,000", |
| "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported |
| }; |
| for (int i=0; i<DATA.length; i+=2) { |
| DecimalFormat df = new DecimalFormat(DATA[i]); |
| String s = df.toPattern(); |
| if (!s.equals(DATA[i+1])) { |
| errln("FAIL: " + DATA[i] + " -> " + s + ", want " + DATA[i+1]); |
| } |
| } |
| } |
| |
| /** |
| * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2 |
| */ |
| public void Test4179818() { |
| String DATA[] = { |
| // Input Pattern Expected output |
| "1.2511", "#.#", "1.3", |
| "1.2501", "#.#", "1.3", |
| "0.9999", "#", "1", |
| }; |
| DecimalFormat fmt = new DecimalFormat("#", |
| new DecimalFormatSymbols(Locale.US)); |
| for (int i=0; i<DATA.length; i+=3) { |
| double in = Double.valueOf(DATA[i]).doubleValue(); |
| String pat = DATA[i+1]; |
| String exp = DATA[i+2]; |
| fmt.applyPattern(pat); |
| String out = fmt.format(in); |
| if (out.equals(exp)) { |
| logln("Ok: " + in + " x " + pat + " = " + out); |
| } else { |
| errln("FAIL: " + in + " x " + pat + " = " + out + |
| ", expected " + exp); |
| } |
| } |
| } |
| |
| public void Test4185761() throws IOException, ClassNotFoundException { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| ObjectOutputStream oos = new ObjectOutputStream(baos); |
| |
| NumberFormat nf = NumberFormat.getInstance(Locale.US); |
| |
| // Set special values we are going to search for in the output byte stream |
| // These are all legal values. |
| nf.setMinimumIntegerDigits(0x111); // Keep under 309 |
| nf.setMaximumIntegerDigits(0x112); // Keep under 309 |
| nf.setMinimumFractionDigits(0x113); // Keep under 340 |
| nf.setMaximumFractionDigits(0x114); // Keep under 340 |
| |
| oos.writeObject(nf); |
| oos.flush(); |
| baos.close(); |
| |
| byte[] bytes = baos.toByteArray(); |
| |
| // Scan for locations of min/max int/fract values in the byte array. |
| // At the moment (ICU4J 2.1), there is only one instance of each target pair |
| // in the byte stream, so assume first match is it. Note this is not entirely |
| // failsafe, and needs to be checked if we change the package or structure of |
| // this class. |
| // Current positions are 890, 880, 886, 876 |
| int[] offsets = new int[4]; |
| for (int i = 0; i < bytes.length - 1; ++i) { |
| if (bytes[i] == 0x01) { // high byte |
| for (int j = 0; j < offsets.length; ++j) { |
| if ((offsets[j] == 0) && (bytes[i+1] == (0x11 + j))) { // low byte |
| offsets[j] = i; |
| break; |
| } |
| } |
| } |
| } |
| |
| { |
| ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); |
| Object o = ois.readObject(); |
| ois.close(); |
| |
| if (!nf.equals(o)) { |
| errln("Fail: NumberFormat serialization/equality bug"); |
| } else { |
| logln("NumberFormat serialization/equality is OKAY."); |
| } |
| } |
| |
| // Change the values in the byte stream so that min > max. |
| // Numberformat should catch this and throw an exception. |
| for (int i = 0; i < offsets.length; ++i) { |
| bytes[offsets[i]] = (byte)(4 - i); |
| } |
| |
| { |
| ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); |
| try { |
| NumberFormat format = (NumberFormat) ois.readObject(); |
| logln("format: " + format.format(1234.56)); //fix "The variable is never used" |
| errln("FAIL: Deserialized bogus NumberFormat with minXDigits > maxXDigits"); |
| } catch (InvalidObjectException e) { |
| logln("Ok: " + e.getMessage()); |
| } |
| } |
| |
| // Set values so they are too high, but min <= max |
| // Format should pass the min <= max test, and DecimalFormat should reset to current maximum |
| // (for compatibility with versions streamed out before the maximums were imposed). |
| for (int i = 0; i < offsets.length; ++i) { |
| bytes[offsets[i]] = 4; |
| } |
| |
| { |
| ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); |
| NumberFormat format = (NumberFormat) ois.readObject(); |
| //For compatibility with previous version |
| if ((format.getMaximumIntegerDigits() != 309) |
| || format.getMaximumFractionDigits() != 340) { |
| errln("FAIL: Deserialized bogus NumberFormat with values out of range," + |
| " intMin: " + format.getMinimumIntegerDigits() + |
| " intMax: " + format.getMaximumIntegerDigits() + |
| " fracMin: " + format.getMinimumFractionDigits() + |
| " fracMax: " + format.getMaximumFractionDigits()); |
| } else { |
| logln("Ok: Digit count out of range"); |
| } |
| } |
| } |
| |
| |
| /** |
| * Some DecimalFormatSymbols changes are not picked up by DecimalFormat. |
| * This includes the minus sign, currency symbol, international currency |
| * symbol, percent, and permille. This is filed as bugs 4212072 and |
| * 4212073. |
| */ |
| public void Test4212072() throws IOException, ClassNotFoundException { |
| DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US); |
| DecimalFormat fmt = new DecimalFormat("#", sym); |
| |
| sym.setMinusSign('^'); |
| fmt.setDecimalFormatSymbols(sym); |
| if (!fmt.format(-1).equals("^1")) { |
| errln("FAIL: -1 x (minus=^) -> " + fmt.format(-1) + |
| ", exp ^1"); |
| } |
| if (!fmt.getNegativePrefix().equals("^")) { |
| errln("FAIL: (minus=^).getNegativePrefix -> " + |
| fmt.getNegativePrefix() + ", exp ^"); |
| } |
| sym.setMinusSign('-'); |
| |
| fmt.applyPattern("#%"); |
| sym.setPercent('^'); |
| fmt.setDecimalFormatSymbols(sym); |
| if (!fmt.format(0.25).equals("25^")) { |
| errln("FAIL: 0.25 x (percent=^) -> " + fmt.format(0.25) + |
| ", exp 25^"); |
| } |
| if (!fmt.getPositiveSuffix().equals("^")) { |
| errln("FAIL: (percent=^).getPositiveSuffix -> " + |
| fmt.getPositiveSuffix() + ", exp ^"); |
| } |
| sym.setPercent('%'); |
| |
| fmt.applyPattern("#\u2030"); |
| sym.setPerMill('^'); |
| fmt.setDecimalFormatSymbols(sym); |
| if (!fmt.format(0.25).equals("250^")) { |
| errln("FAIL: 0.25 x (permill=^) -> " + fmt.format(0.25) + |
| ", exp 250^"); |
| } |
| if (!fmt.getPositiveSuffix().equals("^")) { |
| errln("FAIL: (permill=^).getPositiveSuffix -> " + |
| fmt.getPositiveSuffix() + ", exp ^"); |
| } |
| sym.setPerMill('\u2030'); |
| |
| fmt.applyPattern("\u00A4#.00"); |
| sym.setCurrencySymbol("usd"); |
| fmt.setDecimalFormatSymbols(sym); |
| if (!fmt.format(12.5).equals("usd12.50")) { |
| errln("FAIL: 12.5 x (currency=usd) -> " + fmt.format(12.5) + |
| ", exp usd12.50"); |
| } |
| if (!fmt.getPositivePrefix().equals("usd")) { |
| errln("FAIL: (currency=usd).getPositivePrefix -> " + |
| fmt.getPositivePrefix() + ", exp usd"); |
| } |
| sym.setCurrencySymbol("$"); |
| |
| fmt.applyPattern("\u00A4\u00A4#.00"); |
| sym.setInternationalCurrencySymbol("DOL"); |
| fmt.setDecimalFormatSymbols(sym); |
| if (!fmt.format(12.5).equals("DOL12.50")) { |
| errln("FAIL: 12.5 x (intlcurrency=DOL) -> " + fmt.format(12.5) + |
| ", exp DOL12.50"); |
| } |
| if (!fmt.getPositivePrefix().equals("DOL")) { |
| errln("FAIL: (intlcurrency=DOL).getPositivePrefix -> " + |
| fmt.getPositivePrefix() + ", exp DOL"); |
| } |
| sym.setInternationalCurrencySymbol("USD"); |
| |
| if (VersionInfo.ICU_VERSION == VersionInfo.getInstance(2,2)) { |
| // bug in 2.2 that fails this test |
| // to be fixed in the later versions |
| System.out.println("\n Test skipped for release 2.2"); |
| return; |
| } |
| |
| // Since the pattern logic has changed, make sure that patterns round |
| // trip properly. Test stream in/out integrity too. |
| Locale[] avail = NumberFormat.getAvailableLocales(); |
| for (int i=0; i<avail.length; ++i) { |
| for (int j=0; j<3; ++j) { |
| NumberFormat nf; |
| switch (j) { |
| case 0: |
| nf = NumberFormat.getInstance(avail[i]); |
| break; |
| case 1: |
| nf = NumberFormat.getCurrencyInstance(avail[i]); |
| break; |
| default: |
| nf = NumberFormat.getPercentInstance(avail[i]); |
| break; |
| } |
| DecimalFormat df = (DecimalFormat) nf; |
| |
| // Test toPattern/applyPattern round trip |
| String pat = df.toPattern(); |
| DecimalFormatSymbols symb = new DecimalFormatSymbols(avail[i]); |
| DecimalFormat f2 = new DecimalFormat(pat, symb); |
| if (!df.equals(f2)) { |
| errln("FAIL: " + avail[i] + " #" + j + " -> \"" + pat + |
| "\" -> \"" + f2.toPattern() + '"'); |
| } |
| |
| // Test toLocalizedPattern/applyLocalizedPattern round trip |
| pat = df.toLocalizedPattern(); |
| try{ |
| f2.applyLocalizedPattern(pat); |
| |
| String s1 = f2.format(123456); |
| String s2 = df.format(123456); |
| if(!s1.equals(s2)){ |
| errln("FAIL: " + avail[i] + " #" + j + " -> localized \"" + s2 + |
| "\" -> \"" + s2 + '"'+ " in locale "+df.getLocale(ULocale.ACTUAL_LOCALE)); |
| |
| } |
| if (!df.equals(f2)) { |
| errln("FAIL: " + avail[i] + " #" + j + " -> localized \"" + pat + |
| "\" -> \"" + f2.toLocalizedPattern() + '"'+ " in locale "+df.getLocale(ULocale.ACTUAL_LOCALE)); |
| errln("s1: "+s1+" s2: "+s2); |
| } |
| |
| }catch(IllegalArgumentException ex){ |
| errln(ex.getMessage()+" for locale "+ df.getLocale(ULocale.ACTUAL_LOCALE)); |
| } |
| |
| |
| // Test writeObject/readObject round trip |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| ObjectOutputStream oos = new ObjectOutputStream(baos); |
| oos.writeObject(df); |
| oos.flush(); |
| baos.close(); |
| byte[] bytes = baos.toByteArray(); |
| ObjectInputStream ois = |
| new ObjectInputStream(new ByteArrayInputStream(bytes)); |
| f2 = (DecimalFormat) ois.readObject(); |
| if (!df.equals(f2)) { |
| errln("FAIL: Stream in/out " + avail[i] + " -> \"" + pat + |
| "\" -> " + |
| (f2 != null ? ("\""+f2.toPattern()+'"') : "null")); |
| } |
| |
| } |
| } |
| |
| // @since ICU 2.4 |
| // Make sure that all special characters, when quoted in a suffix or |
| // prefix, lose their special meaning. |
| char[] SPECIALS = { '0', ',', '.', '\u2030', '%', '#', |
| ';', 'E', '*', '+', '-' }; |
| sym = new DecimalFormatSymbols(Locale.US); |
| for (int j=0; j<SPECIALS.length; ++j) { |
| char special = SPECIALS[j]; |
| String pat = "'" + special + "'#0'" + special + "'"; |
| try { |
| fmt = new DecimalFormat(pat, sym); |
| String pat2 = fmt.toPattern(); |
| if (!pat.equals(pat2)) { |
| errln("FAIL: Pattern \"" + pat + "\" => toPattern() => \"" + |
| pat2 + "\""); |
| } |
| String s = fmt.format(123); |
| String exp = "" + special + "123" + special; |
| if (!s.equals(exp)) { |
| errln("FAIL: 123 x \"" + pat + "\" => \"" + s + "\", exp \"" + |
| exp + "\""); |
| } |
| } catch (IllegalArgumentException e) { |
| errln("FAIL: Pattern \"" + pat + "\" => " + e.getMessage()); |
| } |
| } |
| } |
| |
| /** |
| * DecimalFormat.parse() fails for mulipliers 2^n. |
| */ |
| public void Test4216742() throws ParseException { |
| DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance(Locale.US); |
| long[] DATA = { Long.MIN_VALUE, Long.MAX_VALUE, -100000000L, 100000000L}; |
| for (int i=0; i<DATA.length; ++i) { |
| String str = Long.toString(DATA[i]); |
| for (int m = 1; m <= 100; m++) { |
| fmt.setMultiplier(m); |
| long n = ((Number) fmt.parse(str)).longValue(); |
| if (n > 0 != DATA[i] > 0) { |
| errln("\"" + str + "\" parse(x " + fmt.getMultiplier() + |
| ") => " + n); |
| } |
| } |
| } |
| } |
| |
| /** |
| * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction |
| * digits. |
| */ |
| public void Test4217661() { |
| Object[] DATA = { |
| new Double(0.001), "0", |
| new Double(1.001), "1", |
| new Double(0.006), "0.01", |
| new Double(1.006), "1.01", |
| }; |
| NumberFormat fmt = NumberFormat.getInstance(Locale.US); |
| fmt.setMaximumFractionDigits(2); |
| for (int i=0; i<DATA.length; i+=2) { |
| String s = fmt.format(((Double) DATA[i]).doubleValue()); |
| if (!s.equals(DATA[i+1])) { |
| errln("FAIL: Got " + s + ", exp " + DATA[i+1]); |
| } |
| } |
| } |
| |
| /** |
| * 4243011: Formatting .5 rounds to "1" instead of "0" |
| */ |
| public void Test4243011() { |
| double DATA[] = {0.5, 1.5, 2.5, 3.5, 4.5}; |
| String EXPECTED[] = {"0.", "2.", "2.", "4.", "4."}; |
| |
| DecimalFormat format = new DecimalFormat("0."); |
| for (int i = 0; i < DATA.length; i++) { |
| String result = format.format(DATA[i]); |
| if (result.equals(EXPECTED[i])) { |
| logln("OK: got " + result); |
| } else { |
| errln("FAIL: got " + result); |
| } |
| } |
| } |
| |
| /** |
| * 4243108: format(0.0) gives "0.1" if preceded by parse("99.99") |
| */ |
| public void Test4243108() { |
| DecimalFormat f = new DecimalFormat("#.#"); |
| String result = f.format(0.0); |
| if (result.equals("0")) { |
| logln("OK: got " + result); |
| } else { |
| errln("FAIL: got " + result); |
| } |
| try { |
| double dResult = f.parse("99.99").doubleValue(); |
| if (dResult == 99.99) { |
| logln("OK: got " + dResult); |
| } else { |
| errln("FAIL: got " + dResult); |
| } |
| } catch (ParseException e) { |
| errln("Caught a ParseException:"); |
| e.printStackTrace(); |
| } |
| result = f.format(0.0); |
| if (result.equals("0")) { |
| logln("OK: got " + result); |
| } else { |
| errln("FAIL: got " + result); |
| } |
| } |
| |
| /** |
| * 4330377: DecimalFormat engineering notation gives incorrect results |
| */ |
| public void test4330377() { |
| /* |
| double[] input = {5000.0, 500.0, 50.0, 5.0, 0.5, 0.05, 0.005, 0.0005, |
| 5050.0, 505.0, 50.5, 5.05, 0.505, 0.0505, 0.00505, 0.000505}; |
| String[] pattern = {"000.#E0", "##0.#E0", "#00.#E0"}; |
| String[][] expected = { |
| // it's questionable whether "#00.#E0" should result in post-decimal |
| // zeroes, i.e., whether "5.0E3", "5.0E0", "5.0E-3" are really good |
| {"500E1", "5E3", "5.0E3"}, |
| {"500E0", "500E0", "500E0"}, |
| {"500E-1", "50E0", "50E0"}, |
| {"500E-2", "5E0", "5.0E0"}, |
| {"500E-3", "500E-3", "500E-3"}, |
| {"500E-4", "50E-3", "50E-3"}, |
| {"500E-5", "5E-3", "5.0E-3"}, |
| {"500E-6", "500E-6", "500E-6"}, |
| {"505E1", "5.05E3", "5.05E3"}, |
| {"505E0", "505E0", "505E0"}, |
| {"505E-1", "50.5E0", "50.5E0"}, |
| {"505E-2", "5.05E0", "5.05E0"}, |
| {"505E-3", "505E-3", "505E-3"}, |
| {"505E-4", "50.5E-3", "50.5E-3"}, |
| {"505E-5", "5.05E-3", "5.05E-3"}, |
| {"505E-6", "505E-6", "505E-6"} |
| }; |
| for (int i = 0; i < input.length; i++) { |
| for (int j = 0; j < pattern.length; j++) { |
| DecimalFormat format = new DecimalFormat(pattern[j]); |
| String result = format.format(input[i]); |
| if (!result.equals(expected[i][j])) { |
| errln("FAIL: input: " + input[i] + |
| ", pattern: " + pattern[j] + |
| ", expected: " + expected[i][j] + |
| ", got: " + result); |
| } |
| } |
| } |
| */ |
| } |
| |
| /** |
| * 4233840: NumberFormat does not round correctly |
| */ |
| public void test4233840() { |
| float f = 0.0099f; |
| |
| NumberFormat nf = new DecimalFormat("0.##", new DecimalFormatSymbols(Locale.US)); |
| nf.setMinimumFractionDigits(2); |
| |
| String result = nf.format(f); |
| |
| if (!result.equals("0.01")) { |
| errln("FAIL: input: " + f + ", expected: 0.01, got: " + result); |
| } |
| } |
| |
| /** |
| * 4241880: Decimal format doesnt round a double properly when the number is less than 1 |
| */ |
| public void test4241880() { |
| Locale savedLocale = Locale.getDefault(); |
| Locale.setDefault(Locale.US); |
| double[] input = { |
| .019, .009, .015, .016, .014, |
| .004, .005, .006, .007, .008, |
| .5, 1.5, .05, .15, .005, |
| .015, .0005, .0015, |
| }; |
| String[] pattern = { |
| "##0%", "##0%", "##0%", "##0%", "##0%", |
| "##0%", "##0%", "##0%", "##0%", "##0%", |
| "#,##0", "#,##0", "#,##0.0", "#,##0.0", "#,##0.00", |
| "#,##0.00", "#,##0.000", "#,##0.000", |
| }; |
| String[] expected = { |
| "2%", "1%", "2%", "2%", "1%", |
| "0%", "0%", "1%", "1%", "1%", |
| "0", "2", "0.0", "0.2", "0.00", |
| "0.02", "0.000", "0.002", |
| }; |
| for (int i = 0; i < input.length; i++) { |
| DecimalFormat format = new DecimalFormat(pattern[i]); |
| String result = format.format(input[i]); |
| if (!result.equals(expected[i])) { |
| errln("FAIL: input: " + input[i] + |
| ", pattern: " + pattern[i] + |
| ", expected: " + expected[i] + |
| ", got: " + result); |
| } |
| } |
| Locale.setDefault(savedLocale); |
| } |
| } |
| |
| class myformat implements Serializable |
| { |
| /** |
| * For serialization |
| */ |
| private static final long serialVersionUID = 4120813612616076506L; |
| DateFormat _dateFormat = DateFormat.getDateInstance(); |
| |
| public String Now() |
| { |
| GregorianCalendar calendar = new GregorianCalendar(); |
| Date t = calendar.getTime(); |
| String nowStr = _dateFormat.format(t); |
| return nowStr; |
| } |
| } |
| |
| class MyNumberFormatTest extends NumberFormat { |
| /** |
| * For serialization |
| */ |
| private static final long serialVersionUID = 1251303884737169952L; |
| public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { |
| return new StringBuffer(""); |
| } |
| public StringBuffer format(long number,StringBuffer toAppendTo, FieldPosition pos) { |
| return new StringBuffer(""); |
| } |
| public Number parse(String text, ParsePosition parsePosition) { |
| return new Integer(0); |
| } |
| public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) { |
| return new StringBuffer(""); |
| } |
| public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) { |
| return new StringBuffer(""); |
| } |
| public StringBuffer format(com.ibm.icu.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) { |
| return new StringBuffer(""); |
| } |
| } |
| |