/* * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * @test * @bug 4122840 4135202 4408066 4838107 8008577 * @summary test NumberFormat * @library /java/text/testlib * @modules java.base/sun.util.resources * @compile -XDignore.symbol.file NumberTest.java * @run main/othervm -Djava.locale.providers=COMPAT,SPI NumberTest */ import java.util.*; import java.text.*; import sun.util.resources.LocaleData; public class NumberTest extends IntlTest { public static void main(String[] args) throws Exception { new NumberTest().run(args); } // Test pattern handling public void TestPatterns() { DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US); String pat[] = { "#.#", "#.", ".#", "#" }; String newpat[] = { "#0.#", "#0.", "#.0", "#" }; String num[] = { "0", "0.", ".0", "0" }; for (int i=0; i \"" + fmt.toPattern() + '"'); for (int v=0; v " + escape(s)); if (!s.equals(valFormat[v+ival])) { errln("FAIL: Expected " + valFormat[v+ival] + ", got " + s + ", pattern=" + fmt.toPattern()); } ParsePosition pos = new ParsePosition(0); Number a = fmt.parse(s, pos); if (pos.getIndex() == s.length()) { logln(" Parse -> " + a); if (a.doubleValue() != valParse[v+ival]) { errln("FAIL: Expected " + valParse[v+ival] + ", got " + a.doubleValue() + ", pattern=" + fmt.toPattern()); } } else { errln(" FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a); } } for (int v=0; v " + escape(s)); if (!s.equals(lvalFormat[v+ilval])) { errln("ERROR: Expected " + lvalFormat[v+ilval] + ", got " + s + ", pattern=" + fmt.toPattern()); } ParsePosition pos = new ParsePosition(0); Number a = fmt.parse(s, pos); if (pos.getIndex() == s.length()) { logln(" Parse -> " + a); if (a.longValue() != lvalParse[v+ilval]) { errln("FAIL: Expected " + lvalParse[v+ilval] + ", got " + a + ", pattern=" + fmt.toPattern()); } } else { errln(" FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a); } } ival += val.length; ilval += lval.length; } } // Test the handling of quotes public void TestQuotes() { String pat; DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US); DecimalFormat fmt = new DecimalFormat(pat = "a'fo''o'b#", sym); String s = fmt.format(123); logln("Pattern \"" + pat + "\""); logln(" Format 123 -> " + escape(s)); if (!s.equals("afo'ob123")) errln("FAIL: Expected afo'ob123"); fmt = new DecimalFormat(pat = "a''b#", sym); s = fmt.format(123); logln("Pattern \"" + pat + "\""); logln(" Format 123 -> " + escape(s)); if (!s.equals("a'b123")) errln("FAIL: Expected a'b123"); } // Test the use of the currency sign public void TestCurrencySign() { DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US); DecimalFormat fmt = new DecimalFormat("\u00A4#,##0.00;-\u00A4#,##0.00", sym); // Can't test this properly until currency API goes public // DecimalFormatSymbols sym = fmt.getDecimalFormatSymbols(); String s = fmt.format(1234.56); logln("Pattern \"" + fmt.toPattern() + "\""); logln(" Format " + 1234.56 + " -> " + escape(s)); if (!s.equals("$1,234.56")) errln("FAIL: Expected $1,234.56"); s = fmt.format(-1234.56); logln(" Format " + -1234.56 + " -> " + escape(s)); if (!s.equals("-$1,234.56")) errln("FAIL: Expected -$1,234.56"); fmt = new DecimalFormat("\u00A4\u00A4 #,##0.00;\u00A4\u00A4 -#,##0.00", sym); s = fmt.format(1234.56); logln("Pattern \"" + fmt.toPattern() + "\""); logln(" Format " + 1234.56 + " -> " + escape(s)); if (!s.equals("USD 1,234.56")) errln("FAIL: Expected USD 1,234.56"); s = fmt.format(-1234.56); logln(" Format " + -1234.56 + " -> " + escape(s)); if (!s.equals("USD -1,234.56")) errln("FAIL: Expected USD -1,234.56"); } static String escape(String s) { StringBuffer buf = new StringBuffer(); char HEX[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; for (int i=0; i> 12]); buf.append(HEX[(c & 0x0F00) >> 8]); buf.append(HEX[(c & 0x00F0) >> 4]); buf.append(HEX[c & 0x000F]); } } return buf.toString(); } // Test simple currency format // Bug 4024941; this code used to throw a NumberFormat exception public void TestCurrency() { NumberFormat currencyFmt = NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH); String s = currencyFmt.format(1.50); logln("Un pauvre ici a..........." + s); if (!s.equals("1,50 $")) { errln("FAIL: Expected 1,50 $; got " + s + "; "+ dumpFmt(currencyFmt)); } currencyFmt = NumberFormat.getCurrencyInstance(Locale.GERMANY); s = currencyFmt.format(1.50); logln("Un pauvre en Allemagne a.." + s); if (!s.equals("1,50 \u20AC")) { errln("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt)); } currencyFmt = NumberFormat.getCurrencyInstance(Locale.FRANCE); s = currencyFmt.format(1.50); logln("Un pauvre en France a....." + s); if (!s.equals("1,50 \u20AC")) { errln("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt)); } } String dumpFmt(NumberFormat numfmt) { DecimalFormat fmt = (DecimalFormat)numfmt; StringBuffer buf = new StringBuffer(); buf.append("pattern \""); buf.append(fmt.toPattern()); buf.append("\", currency \""); buf.append(fmt.getDecimalFormatSymbols().getCurrencySymbol()); buf.append("\""); return buf.toString(); } // Test numeric parsing // Bug 4059870 public void TestParse() { String arg = "0"; java.text.DecimalFormat format = new java.text.DecimalFormat("00"); try { Number n = format.parse(arg); logln("parse(" + arg + ") = " + n); if (n.doubleValue() != 0.0) errln("FAIL: Expected 0"); } catch (Exception e) { errln("Exception caught: " + e); } } // Test rounding public void TestRounding487() { NumberFormat nf = NumberFormat.getInstance(Locale.US); roundingTest(nf, 0.00159999, 4, "0.0016"); roundingTest(nf, 0.00995, 4, "0.01"); roundingTest(nf, 12.7995, 3, "12.8"); roundingTest(nf, 12.4999, 0, "12"); roundingTest(nf, -19.5, 0, "-20"); } void roundingTest(NumberFormat nf, double x, int maxFractionDigits, String expected) { nf.setMaximumFractionDigits(maxFractionDigits); String out = nf.format(x); logln("" + x + " formats with " + maxFractionDigits + " fractional digits to " + out); if (!out.equals(expected)) { errln("FAIL: Expected " + expected + ", got " + out); } } /** * Bug 4135202 * DecimalFormat should recognize not only Latin digits 0-9 (\u0030-\u0039) * but also various other ranges of Unicode digits, such as Arabic * digits \u0660-\u0669 and Devanagari digits \u0966-\u096F, to name * a couple. * @see java.lang.Character#isDigit(char) */ public void TestUnicodeDigits() { char[] zeros = { 0x0030, // ISO-LATIN-1 digits ('0' through '9') 0x0660, // Arabic-Indic digits 0x06F0, // Extended Arabic-Indic digits 0x0966, // Devanagari digits 0x09E6, // Bengali digits 0x0A66, // Gurmukhi digits 0x0AE6, // Gujarati digits 0x0B66, // Oriya digits 0x0BE6, // Tamil digits 0x0C66, // Telugu digits 0x0CE6, // Kannada digits 0x0D66, // Malayalam digits 0x0E50, // Thai digits 0x0ED0, // Lao digits 0x0F20, // Tibetan digits 0xFF10, // Fullwidth digits }; NumberFormat format = NumberFormat.getInstance(); for (int i=0; i= 0) { if (customNeg.indexOf(INTL_SYM) >= 0) errln("Fail: Positive and negative patterns use different symbols"); else logln("Ok: " + locales[i] + " uses currency symbol: " + genericPos + ", " + customPos); } else if (customPos.indexOf(INTL_SYM) >= 0) { if (customNeg.indexOf(SYM) >= 0) errln("Fail: Positive and negative patterns use different symbols"); else logln("Ok: " + locales[i] + " uses intl. currency symbol: " + genericPos + ", " + customPos); } else { errln("FAIL: " + locales[i] + " contains no currency symbol (impossible!)"); } } } else logln("Skipping " + locales[i] + "; not a DecimalFormat"); } } public void TestIntegerFormat() throws ParseException { NumberFormat format = NumberFormat.getIntegerInstance(Locale.GERMANY); float[] formatInput = { 12345.67f, -12345.67f, -0, 0 }; String[] formatExpected = { "12.346", "-12.346", "0", "0" }; for (int i = 0; i < formatInput.length; i++) { String result = format.format(formatInput[i]); if (!result.equals(formatExpected[i])) { errln("FAIL: Expected " + formatExpected[i] + ", got " + result); } } String[] parseInput = { "0", "-0", "12.345,67", "-12.345,67" }; float[] parseExpected = { 0, 0, 12345, -12345 }; for (int i = 0; i < parseInput.length; i++) { float result = format.parse(parseInput[i]).floatValue(); if (result != parseExpected[i]) { errln("FAIL: Expected " + parseExpected[i] + ", got " + result); } } } }