Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/text/Format/NumberFormat/NumberTest.java
47178 views
/*1* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 4122840 4135202 4408066 4838107 800857726* @summary test NumberFormat27* @library /java/text/testlib28* @modules java.base/sun.util.resources29* @compile -XDignore.symbol.file NumberTest.java30* @run main/othervm -Djava.locale.providers=JRE,SPI NumberTest31*/3233import java.util.*;34import java.text.*;35import sun.util.resources.LocaleData;3637public class NumberTest extends IntlTest38{39public static void main(String[] args) throws Exception {40new NumberTest().run(args);41}4243// Test pattern handling44public void TestPatterns()45{46DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US);47String pat[] = { "#.#", "#.", ".#", "#" };48String newpat[] = { "#0.#", "#0.", "#.0", "#" };49String num[] = { "0", "0.", ".0", "0" };50for (int i=0; i<pat.length; ++i)51{52DecimalFormat fmt = new DecimalFormat(pat[i], sym);53String newp = fmt.toPattern();54if (!newp.equals(newpat[i]))55errln("FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] +56"; " + newp + " seen instead");5758String s = fmt.format(0);59if (!s.equals(num[i]))60{61errln("FAIL: Pattern " + pat[i] + " should format zero as " + num[i] +62"; " + s + " seen instead");63logln("Min integer digits = " + fmt.getMinimumIntegerDigits());64}65}66}6768// Test exponential pattern69public void TestExponential() {70DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US);71String pat[] = { "0.####E0", "00.000E00", "##0.####E000", "0.###E0;[0.###E0]" };72double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };73long lval[] = { 0, -1, 1, 123456789 };74String valFormat[] = {75"1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",76"12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",77"12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",78"1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"79};80String lvalFormat[] = {81"0E0", "-1E0", "1E0", "1.2346E8",82"00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",83"0E000", "-1E000", "1E000", "123.4568E006",84"0E0", "[1E0]", "1E0", "1.235E8"85};86double valParse[] = {870.01234, 123460000, 1.23E300, -3.1416E-271,880.01234, 123460000, 1.23E300, -3.1416E-271,890.01234, 123456800, 1.23E300, -3.141593E-271,900.01234, 123500000, 1.23E300, -3.142E-271,91};92long lvalParse[] = {930, -1, 1, 123460000,940, -1, 1, 123460000,950, -1, 1, 123456800,960, -1, 1, 123500000,97};98int ival = 0, ilval = 0;99for (int p=0; p<pat.length; ++p) {100DecimalFormat fmt = new DecimalFormat(pat[p], sym);101logln("Pattern \"" + pat[p] + "\" -toPattern-> \"" +102fmt.toPattern() + '"');103104for (int v=0; v<val.length; ++v) {105String s = fmt.format(val[v]);106logln(" Format " + val[v] + " -> " + escape(s));107if (!s.equals(valFormat[v+ival])) {108errln("FAIL: Expected " + valFormat[v+ival] +109", got " + s +110", pattern=" + fmt.toPattern());111}112113ParsePosition pos = new ParsePosition(0);114Number a = fmt.parse(s, pos);115if (pos.getIndex() == s.length()) {116logln(" Parse -> " + a);117if (a.doubleValue() != valParse[v+ival]) {118errln("FAIL: Expected " + valParse[v+ival] +119", got " + a.doubleValue() +120", pattern=" + fmt.toPattern());121}122} else {123errln(" FAIL: Partial parse (" + pos.getIndex() +124" chars) -> " + a);125}126}127for (int v=0; v<lval.length; ++v) {128String s = fmt.format(lval[v]);129logln(" Format " + lval[v] + "L -> " + escape(s));130if (!s.equals(lvalFormat[v+ilval])) {131errln("ERROR: Expected " + lvalFormat[v+ilval] +132", got " + s +133", pattern=" + fmt.toPattern());134}135136ParsePosition pos = new ParsePosition(0);137Number a = fmt.parse(s, pos);138if (pos.getIndex() == s.length()) {139logln(" Parse -> " + a);140if (a.longValue() != lvalParse[v+ilval]) {141errln("FAIL: Expected " + lvalParse[v+ilval] +142", got " + a +143", pattern=" + fmt.toPattern());144}145} else {146errln(" FAIL: Partial parse (" + pos.getIndex() +147" chars) -> " + a);148}149}150ival += val.length;151ilval += lval.length;152}153}154155// Test the handling of quotes156public void TestQuotes()157{158String pat;159DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US);160DecimalFormat fmt = new DecimalFormat(pat = "a'fo''o'b#", sym);161String s = fmt.format(123);162logln("Pattern \"" + pat + "\"");163logln(" Format 123 -> " + escape(s));164if (!s.equals("afo'ob123")) errln("FAIL: Expected afo'ob123");165166fmt = new DecimalFormat(pat = "a''b#", sym);167s = fmt.format(123);168logln("Pattern \"" + pat + "\"");169logln(" Format 123 -> " + escape(s));170if (!s.equals("a'b123")) errln("FAIL: Expected a'b123");171}172173// Test the use of the currency sign174public void TestCurrencySign()175{176DecimalFormatSymbols sym = DecimalFormatSymbols.getInstance(Locale.US);177DecimalFormat fmt = new DecimalFormat("\u00A4#,##0.00;-\u00A4#,##0.00", sym);178// Can't test this properly until currency API goes public179// DecimalFormatSymbols sym = fmt.getDecimalFormatSymbols();180181String s = fmt.format(1234.56);182logln("Pattern \"" + fmt.toPattern() + "\"");183logln(" Format " + 1234.56 + " -> " + escape(s));184if (!s.equals("$1,234.56")) errln("FAIL: Expected $1,234.56");185s = fmt.format(-1234.56);186logln(" Format " + -1234.56 + " -> " + escape(s));187if (!s.equals("-$1,234.56")) errln("FAIL: Expected -$1,234.56");188189fmt = new DecimalFormat("\u00A4\u00A4 #,##0.00;\u00A4\u00A4 -#,##0.00", sym);190s = fmt.format(1234.56);191logln("Pattern \"" + fmt.toPattern() + "\"");192logln(" Format " + 1234.56 + " -> " + escape(s));193if (!s.equals("USD 1,234.56")) errln("FAIL: Expected USD 1,234.56");194s = fmt.format(-1234.56);195logln(" Format " + -1234.56 + " -> " + escape(s));196if (!s.equals("USD -1,234.56")) errln("FAIL: Expected USD -1,234.56");197}198static String escape(String s)199{200StringBuffer buf = new StringBuffer();201char HEX[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };202for (int i=0; i<s.length(); ++i)203{204char c = s.charAt(i);205if (c <= (char)0x7F) buf.append(c);206else207{208buf.append("\\U");209buf.append(HEX[(c & 0xF000) >> 12]);210buf.append(HEX[(c & 0x0F00) >> 8]);211buf.append(HEX[(c & 0x00F0) >> 4]);212buf.append(HEX[c & 0x000F]);213}214}215return buf.toString();216}217218// Test simple currency format219// Bug 4024941; this code used to throw a NumberFormat exception220public void TestCurrency() {221NumberFormat currencyFmt =222NumberFormat.getCurrencyInstance(Locale.CANADA_FRENCH);223String s = currencyFmt.format(1.50);224logln("Un pauvre ici a..........." + s);225if (!s.equals("1,50 $")) {226errln("FAIL: Expected 1,50 $; got " + s + "; "+ dumpFmt(currencyFmt));227}228currencyFmt = NumberFormat.getCurrencyInstance(Locale.GERMANY);229s = currencyFmt.format(1.50);230logln("Un pauvre en Allemagne a.." + s);231if (!s.equals("1,50 \u20AC")) {232errln("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt));233}234currencyFmt = NumberFormat.getCurrencyInstance(Locale.FRANCE);235s = currencyFmt.format(1.50);236logln("Un pauvre en France a....." + s);237if (!s.equals("1,50 \u20AC")) {238errln("FAIL: Expected 1,50 \u20AC; got " + s + "; " + dumpFmt(currencyFmt));239}240}241242String dumpFmt(NumberFormat numfmt) {243DecimalFormat fmt = (DecimalFormat)numfmt;244StringBuffer buf = new StringBuffer();245buf.append("pattern \"");246buf.append(fmt.toPattern());247buf.append("\", currency \"");248buf.append(fmt.getDecimalFormatSymbols().getCurrencySymbol());249buf.append("\"");250return buf.toString();251}252253// Test numeric parsing254// Bug 4059870255public void TestParse()256{257String arg = "0";258java.text.DecimalFormat format = new java.text.DecimalFormat("00");259try {260Number n = format.parse(arg);261logln("parse(" + arg + ") = " + n);262if (n.doubleValue() != 0.0) errln("FAIL: Expected 0");263} catch (Exception e) { errln("Exception caught: " + e); }264}265266// Test rounding267public void TestRounding487() {268NumberFormat nf = NumberFormat.getInstance(Locale.US);269roundingTest(nf, 0.00159999, 4, "0.0016");270roundingTest(nf, 0.00995, 4, "0.01");271roundingTest(nf, 12.7995, 3, "12.8");272roundingTest(nf, 12.4999, 0, "12");273roundingTest(nf, -19.5, 0, "-20");274}275276void roundingTest(NumberFormat nf, double x, int maxFractionDigits, String expected) {277nf.setMaximumFractionDigits(maxFractionDigits);278String out = nf.format(x);279logln("" + x + " formats with " + maxFractionDigits + " fractional digits to " + out);280if (!out.equals(expected)) {281errln("FAIL: Expected " + expected + ", got " + out);282}283}284285/**286* Bug 4135202287* DecimalFormat should recognize not only Latin digits 0-9 (\u0030-\u0039)288* but also various other ranges of Unicode digits, such as Arabic289* digits \u0660-\u0669 and Devanagari digits \u0966-\u096F, to name290* a couple.291* @see java.lang.Character#isDigit(char)292*/293public void TestUnicodeDigits() {294char[] zeros = {2950x0030, // ISO-LATIN-1 digits ('0' through '9')2960x0660, // Arabic-Indic digits2970x06F0, // Extended Arabic-Indic digits2980x0966, // Devanagari digits2990x09E6, // Bengali digits3000x0A66, // Gurmukhi digits3010x0AE6, // Gujarati digits3020x0B66, // Oriya digits3030x0BE6, // Tamil digits3040x0C66, // Telugu digits3050x0CE6, // Kannada digits3060x0D66, // Malayalam digits3070x0E50, // Thai digits3080x0ED0, // Lao digits3090x0F20, // Tibetan digits3100xFF10, // Fullwidth digits311};312NumberFormat format = NumberFormat.getInstance();313for (int i=0; i<zeros.length; ++i) {314char zero = zeros[i];315StringBuffer buf = new StringBuffer();316buf.append((char)(zero+3));317buf.append((char)(zero+1));318buf.append((char)(zero+4));319int n = -1;320try {321n = format.parse(buf.toString()).intValue();322}323catch (ParseException e) { n = -2; }324if (n != 314)325errln("Can't parse Unicode " + Integer.toHexString(zero) + " as digit (" + n + ")");326else327logln("Parse digit " + Integer.toHexString(zero) + " ok");328}329}330331/**332* Bug 4122840333* Make sure that the currency symbol is not hard-coded in any locale.334*/335public void TestCurrencySubstitution() {336final String SYM = "<currency>";337final String INTL_SYM = "<intl.currency>";338Locale[] locales = NumberFormat.getAvailableLocales();339for (int i=0; i<locales.length; ++i) {340NumberFormat nf = NumberFormat.getCurrencyInstance(locales[i]);341if (nf instanceof DecimalFormat) {342DecimalFormat df = (DecimalFormat)nf;343String genericPos = df.format(1234.5678);344String genericNeg = df.format(-1234.5678);345DecimalFormatSymbols sym = df.getDecimalFormatSymbols();346sym.setCurrencySymbol(SYM);347sym.setInternationalCurrencySymbol(INTL_SYM);348// We have to make a new DecimalFormat from scratch in order349// to make the new symbols 'take'. This may be a bug or350// design flaw in DecimalFormat.351String[] patterns = LocaleData.getBundle("sun.text.resources.FormatData", locales[i])352.getStringArray("NumberPatterns");353df = new DecimalFormat(patterns[1 /*CURRENCYSTYLE*/], sym);354String customPos = df.format(1234.5678);355String customNeg = df.format(-1234.5678);356if (genericPos.equals(customPos) || genericNeg.equals(customNeg)) {357errln("FAIL: " + locales[i] +358" not using currency symbol substitution: " + genericPos);359}360else {361if (customPos.indexOf(SYM) >= 0) {362if (customNeg.indexOf(INTL_SYM) >= 0)363errln("Fail: Positive and negative patterns use different symbols");364else365logln("Ok: " + locales[i] +366" uses currency symbol: " + genericPos +367", " + customPos);368}369else if (customPos.indexOf(INTL_SYM) >= 0) {370if (customNeg.indexOf(SYM) >= 0)371errln("Fail: Positive and negative patterns use different symbols");372else373logln("Ok: " + locales[i] +374" uses intl. currency symbol: " + genericPos +375", " + customPos);376}377else {378errln("FAIL: " + locales[i] +379" contains no currency symbol (impossible!)");380}381}382}383else logln("Skipping " + locales[i] + "; not a DecimalFormat");384}385}386387public void TestIntegerFormat() throws ParseException {388NumberFormat format = NumberFormat.getIntegerInstance(Locale.GERMANY);389390float[] formatInput = { 12345.67f, -12345.67f, -0, 0 };391String[] formatExpected = { "12.346", "-12.346", "0", "0" };392393for (int i = 0; i < formatInput.length; i++) {394String result = format.format(formatInput[i]);395if (!result.equals(formatExpected[i])) {396errln("FAIL: Expected " + formatExpected[i] + ", got " + result);397}398}399400String[] parseInput = { "0", "-0", "12.345,67", "-12.345,67" };401float[] parseExpected = { 0, 0, 12345, -12345 };402403for (int i = 0; i < parseInput.length; i++) {404float result = ((Number) format.parse(parseInput[i])).floatValue();405if (result != parseExpected[i]) {406errln("FAIL: Expected " + parseExpected[i] + ", got " + result);407}408}409}410}411412413