Home | History | Annotate | Download | only in format
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html#License
      3 /*****************************************************************************************
      4  *
      5  *   Copyright (C) 1996-2012, International Business Machines
      6  *   Corporation and others.  All Rights Reserved.
      7  **/
      8 
      9 /**
     10  * Port From:   JDK 1.4b1 : java.text.Format.IntlTestDecimalFormatAPI
     11  * Source File: java/text/format/IntlTestDecimalFormatAPI.java
     12  **/
     13 
     14 /*
     15     @test 1.4 98/03/06
     16     @summary test International Decimal Format API
     17 */
     18 
     19 package com.ibm.icu.dev.test.format;
     20 
     21 import java.text.FieldPosition;
     22 import java.text.Format;
     23 import java.text.ParseException;
     24 import java.text.ParsePosition;
     25 import java.util.Locale;
     26 
     27 import org.junit.Test;
     28 import org.junit.runner.RunWith;
     29 import org.junit.runners.JUnit4;
     30 
     31 import com.ibm.icu.dev.test.TestFmwk;
     32 import com.ibm.icu.math.BigDecimal;
     33 import com.ibm.icu.math.MathContext;
     34 import com.ibm.icu.text.DecimalFormat;
     35 import com.ibm.icu.text.DecimalFormatSymbols;
     36 import com.ibm.icu.text.NumberFormat;
     37 
     38 @RunWith(JUnit4.class)
     39 public class IntlTestDecimalFormatAPI extends TestFmwk
     40 {
     41     /**
     42      * Problem 1: simply running
     43      * decF4.setRoundingMode(java.math.BigDecimal.ROUND_HALF_UP) does not work
     44      * as decF4.setRoundingIncrement(.0001) must also be run.
     45      * Problem 2: decF4.format(8.88885) does not return 8.8889 as expected.
     46      * You must run decF4.format(new BigDecimal(Double.valueOf(8.88885))) in
     47      * order for this to work as expected.
     48      * Problem 3: There seems to be no way to set half up to be the default
     49      * rounding mode.
     50      * We solved the problem with the code at the bottom of this page however
     51      * this is not quite general purpose enough to include in icu4j. A static
     52      * setDefaultRoundingMode function would solve the problem nicely. Also
     53      * decimal places past 20 are not handled properly. A small ammount of work
     54      * would make bring this up to snuff.
     55      */
     56     @Test
     57     public void testJB1871()
     58     {
     59         // problem 2
     60         double number = 8.88885;
     61         String expected = "8.8889";
     62 
     63         String pat = ",##0.0000";
     64         DecimalFormat dec = new DecimalFormat(pat);
     65         dec.setRoundingMode(BigDecimal.ROUND_HALF_UP);
     66         dec.setRoundingIncrement(new java.math.BigDecimal("0.0001"));
     67         String str = dec.format(number);
     68         if (!str.equals(expected)) {
     69             errln("Fail: " + number + " x \"" + pat + "\" = \"" +
     70                   str + "\", expected \"" + expected + "\"");
     71         }
     72 
     73         pat = ",##0.0001";
     74         dec = new DecimalFormat(pat);
     75         dec.setRoundingMode(BigDecimal.ROUND_HALF_UP);
     76         str = dec.format(number);
     77         if (!str.equals(expected)) {
     78             errln("Fail: " + number + " x \"" + pat + "\" = \"" +
     79                   str + "\", expected \"" + expected + "\"");
     80         }
     81 
     82         // testing 20 decimal places
     83         pat = ",##0.00000000000000000001";
     84         dec = new DecimalFormat(pat);
     85         BigDecimal bignumber = new BigDecimal("8.888888888888888888885");
     86         expected = "8.88888888888888888889";
     87 
     88         dec.setRoundingMode(BigDecimal.ROUND_HALF_UP);
     89         str = dec.format(bignumber);
     90         if (!str.equals(expected)) {
     91             errln("Fail: " + bignumber + " x \"" + pat + "\" = \"" +
     92                   str + "\", expected \"" + expected + "\"");
     93         }
     94 
     95     }
     96 
     97     /**
     98      * This test checks various generic API methods in DecimalFormat to achieve
     99      * 100% API coverage.
    100      */
    101     @Test
    102     public void TestAPI()
    103     {
    104         logln("DecimalFormat API test---"); logln("");
    105         Locale.setDefault(Locale.ENGLISH);
    106 
    107         // ======= Test constructors
    108 
    109         logln("Testing DecimalFormat constructors");
    110 
    111         DecimalFormat def = new DecimalFormat();
    112 
    113         final String pattern = new String("#,##0.# FF");
    114         DecimalFormat pat = null;
    115         try {
    116             pat = new DecimalFormat(pattern);
    117         }
    118         catch (IllegalArgumentException e) {
    119             errln("ERROR: Could not create DecimalFormat (pattern)");
    120         }
    121 
    122         DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.FRENCH);
    123 
    124         DecimalFormat cust1 = new DecimalFormat(pattern, symbols);
    125 
    126         // ======= Test clone(), assignment, and equality
    127 
    128         logln("Testing clone() and equality operators");
    129 
    130         Format clone = (Format) def.clone();
    131         if( ! def.equals(clone)) {
    132             errln("ERROR: Clone() failed");
    133         }
    134 
    135         // ======= Test various format() methods
    136 
    137         logln("Testing various format() methods");
    138 
    139 //        final double d = -10456.0037; // this appears as -10456.003700000001 on NT
    140 //        final double d = -1.04560037e-4; // this appears as -1.0456003700000002E-4 on NT
    141         final double d = -10456.00370000000000; // this works!
    142         final long l = 100000000;
    143         logln("" + d + " is the double value");
    144 
    145         StringBuffer res1 = new StringBuffer();
    146         StringBuffer res2 = new StringBuffer();
    147         StringBuffer res3 = new StringBuffer();
    148         StringBuffer res4 = new StringBuffer();
    149         FieldPosition pos1 = new FieldPosition(0);
    150         FieldPosition pos2 = new FieldPosition(0);
    151         FieldPosition pos3 = new FieldPosition(0);
    152         FieldPosition pos4 = new FieldPosition(0);
    153 
    154         res1 = def.format(d, res1, pos1);
    155         logln("" + d + " formatted to " + res1);
    156 
    157         res2 = pat.format(l, res2, pos2);
    158         logln("" + l + " formatted to " + res2);
    159 
    160         res3 = cust1.format(d, res3, pos3);
    161         logln("" + d + " formatted to " + res3);
    162 
    163         res4 = cust1.format(l, res4, pos4);
    164         logln("" + l + " formatted to " + res4);
    165 
    166         // ======= Test parse()
    167 
    168         logln("Testing parse()");
    169 
    170         String text = new String("-10,456.0037");
    171         ParsePosition pos = new ParsePosition(0);
    172         String patt = new String("#,##0.#");
    173         pat.applyPattern(patt);
    174         double d2 = pat.parse(text, pos).doubleValue();
    175         if(d2 != d) {
    176             errln("ERROR: Roundtrip failed (via parse(" + d2 + " != " + d + ")) for " + text);
    177         }
    178         logln(text + " parsed into " + (long) d2);
    179 
    180         // ======= Test getters and setters
    181 
    182         logln("Testing getters and setters");
    183 
    184         final DecimalFormatSymbols syms = pat.getDecimalFormatSymbols();
    185         def.setDecimalFormatSymbols(syms);
    186         if( ! pat.getDecimalFormatSymbols().equals(def.getDecimalFormatSymbols())) {
    187             errln("ERROR: set DecimalFormatSymbols() failed");
    188         }
    189 
    190         String posPrefix;
    191         pat.setPositivePrefix("+");
    192         posPrefix = pat.getPositivePrefix();
    193         logln("Positive prefix (should be +): " + posPrefix);
    194         assertEquals("ERROR: setPositivePrefix() failed", "+", posPrefix);
    195 
    196         String negPrefix;
    197         pat.setNegativePrefix("-");
    198         negPrefix = pat.getNegativePrefix();
    199         logln("Negative prefix (should be -): " + negPrefix);
    200         assertEquals("ERROR: setNegativePrefix() failed", "-", negPrefix);
    201 
    202         String posSuffix;
    203         pat.setPositiveSuffix("_");
    204         posSuffix = pat.getPositiveSuffix();
    205         logln("Positive suffix (should be _): " + posSuffix);
    206         assertEquals("ERROR: setPositiveSuffix() failed", "_", posSuffix);
    207 
    208         String negSuffix;
    209         pat.setNegativeSuffix("~");
    210         negSuffix = pat.getNegativeSuffix();
    211         logln("Negative suffix (should be ~): " + negSuffix);
    212         assertEquals("ERROR: setNegativeSuffix() failed", "~", negSuffix);
    213 
    214         long multiplier = 0;
    215         pat.setMultiplier(8);
    216         multiplier = pat.getMultiplier();
    217         logln("Multiplier (should be 8): " + multiplier);
    218         if(multiplier != 8) {
    219             errln("ERROR: setMultiplier() failed");
    220         }
    221 
    222         int groupingSize = 0;
    223         pat.setGroupingSize(2);
    224         groupingSize = pat.getGroupingSize();
    225         logln("Grouping size (should be 2): " + (long) groupingSize);
    226         if(groupingSize != 2) {
    227             errln("ERROR: setGroupingSize() failed");
    228         }
    229 
    230         pat.setDecimalSeparatorAlwaysShown(true);
    231         boolean tf = pat.isDecimalSeparatorAlwaysShown();
    232         logln("DecimalSeparatorIsAlwaysShown (should be true) is " +  (tf ? "true" : "false"));
    233         if(tf != true) {
    234             errln("ERROR: setDecimalSeparatorAlwaysShown() failed");
    235         }
    236 
    237         String funkyPat;
    238         funkyPat = pat.toPattern();
    239         logln("Pattern is " + funkyPat);
    240 
    241         String locPat;
    242         locPat = pat.toLocalizedPattern();
    243         logln("Localized pattern is " + locPat);
    244 
    245         // ======= Test applyPattern()
    246 
    247         logln("Testing applyPattern()");
    248 
    249         String p1 = new String("#,##0.0#;(#,##0.0#)");
    250         logln("Applying pattern " + p1);
    251         pat.applyPattern(p1);
    252         String s2;
    253         s2 = pat.toPattern();
    254         logln("Extracted pattern is " + s2);
    255         if( ! s2.equals(p1) ) {
    256             errln("ERROR: toPattern() result did not match pattern applied");
    257         }
    258 
    259         String p2 = new String("#,##0.0# FF;(#,##0.0# FF)");
    260         logln("Applying pattern " + p2);
    261         pat.applyLocalizedPattern(p2);
    262         String s3;
    263         s3 = pat.toLocalizedPattern();
    264         logln("Extracted pattern is " + s3);
    265         if( ! s3.equals(p2) ) {
    266             errln("ERROR: toLocalizedPattern() result did not match pattern applied");
    267         }
    268     }
    269 
    270     @Test
    271     public void testJB6134()
    272     {
    273         DecimalFormat decfmt = new DecimalFormat();
    274         StringBuffer buf = new StringBuffer();
    275 
    276         FieldPosition fposByInt = new FieldPosition(NumberFormat.INTEGER_FIELD);
    277         decfmt.format(123, buf, fposByInt);
    278 
    279         buf.setLength(0);
    280         FieldPosition fposByField = new FieldPosition(NumberFormat.Field.INTEGER);
    281         decfmt.format(123, buf, fposByField);
    282 
    283         if (fposByInt.getEndIndex() != fposByField.getEndIndex())
    284         {
    285             errln("ERROR: End index for integer field - fposByInt:" + fposByInt.getEndIndex() +
    286                 " / fposByField: " + fposByField.getEndIndex());
    287         }
    288     }
    289 
    290     @Test
    291     public void testJB4971()
    292     {
    293         DecimalFormat decfmt = new DecimalFormat();
    294         MathContext resultICU;
    295 
    296         MathContext comp1 = new MathContext(0, MathContext.PLAIN, false, MathContext.ROUND_HALF_EVEN);
    297         resultICU = decfmt.getMathContextICU();
    298         if ((comp1.getDigits() != resultICU.getDigits()) ||
    299             (comp1.getForm() != resultICU.getForm()) ||
    300             (comp1.getLostDigits() != resultICU.getLostDigits()) ||
    301             (comp1.getRoundingMode() != resultICU.getRoundingMode()))
    302         {
    303             errln("ERROR: Math context 1 not equal - result: " + resultICU.toString() +
    304                 " / expected: " + comp1.toString());
    305         }
    306 
    307         MathContext comp2 = new MathContext(5, MathContext.ENGINEERING, false, MathContext.ROUND_HALF_EVEN);
    308         decfmt.setMathContextICU(comp2);
    309         resultICU = decfmt.getMathContextICU();
    310         if ((comp2.getDigits() != resultICU.getDigits()) ||
    311             (comp2.getForm() != resultICU.getForm()) ||
    312             (comp2.getLostDigits() != resultICU.getLostDigits()) ||
    313             (comp2.getRoundingMode() != resultICU.getRoundingMode()))
    314         {
    315             errln("ERROR: Math context 2 not equal - result: " + resultICU.toString() +
    316                 " / expected: " + comp2.toString());
    317         }
    318 
    319         java.math.MathContext result;
    320 
    321         java.math.MathContext comp3 = new java.math.MathContext(3, java.math.RoundingMode.DOWN);
    322         decfmt.setMathContext(comp3);
    323         result = decfmt.getMathContext();
    324         if ((comp3.getPrecision() != result.getPrecision()) ||
    325             (comp3.getRoundingMode() != result.getRoundingMode()))
    326         {
    327             errln("ERROR: Math context 3 not equal - result: " + result.toString() +
    328                 " / expected: " + comp3.toString());
    329         }
    330 
    331     }
    332 
    333     @Test
    334     public void testJB6354()
    335     {
    336         DecimalFormat pat = new DecimalFormat("#,##0.00");
    337         java.math.BigDecimal r1, r2;
    338 
    339         // get default rounding increment
    340         r1 = pat.getRoundingIncrement();
    341 
    342         // set rounding mode with zero increment.  Rounding
    343         // increment should be set by this operation
    344         pat.setRoundingMode(BigDecimal.ROUND_UP);
    345         r2 = pat.getRoundingIncrement();
    346 
    347         // check for different values
    348         if ((r1 != null) && (r2 != null))
    349         {
    350             if (r1.compareTo(r2) == 0)
    351             {
    352                 errln("ERROR: Rounding increment did not change");
    353             }
    354         }
    355     }
    356 
    357     @Test
    358     public void testJB6648()
    359     {
    360         DecimalFormat df = new DecimalFormat();
    361         df.setParseStrict(true);
    362 
    363         String numstr = new String();
    364 
    365         String[] patterns = {
    366             "0",
    367             "00",
    368             "000",
    369             "0,000",
    370             "0.0",
    371             "#000.0"
    372         };
    373 
    374         for(int i=0; i < patterns.length; i++) {
    375             df.applyPattern(patterns[i]);
    376             numstr = df.format(5);
    377             try {
    378                 Number n = df.parse(numstr);
    379                 logln("INFO: Parsed " + numstr + " -> " + n);
    380             } catch (ParseException pe) {
    381                 errln("ERROR: Failed round trip with strict parsing.");
    382             }
    383         }
    384 
    385         df.applyPattern(patterns[1]);
    386         numstr = "005";
    387         try {
    388             Number n = df.parse(numstr);
    389             logln("INFO: Successful parse for " + numstr + " with strict parse enabled. Number is " + n);
    390         } catch (ParseException pe) {
    391             errln("ERROR: Parse Exception encountered in strict mode: numstr -> " + numstr);
    392         }
    393 
    394     }
    395 }
    396