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) 2001-2011, International Business Machines Corporation and    *
      6  * others. All Rights Reserved.                                                *
      7  *******************************************************************************
      8  */
      9 
     10 /**
     11  * Port From:   ICU4C v1.8.1 : format : IntlTestNumberFormat
     12  * Source File: $ICU4CRoot/source/test/intltest/tsnmfmt.cpp
     13  **/
     14 
     15 package com.ibm.icu.dev.test.format;
     16 import java.util.Locale;
     17 import java.util.Random;
     18 
     19 import org.junit.Test;
     20 import org.junit.runner.RunWith;
     21 import org.junit.runners.JUnit4;
     22 
     23 import com.ibm.icu.dev.test.TestFmwk;
     24 import com.ibm.icu.text.DecimalFormat;
     25 import com.ibm.icu.text.NumberFormat;
     26 
     27 /**
     28  * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
     29  * NumberFormat.
     30  */
     31 @RunWith(JUnit4.class)
     32 public class IntlTestNumberFormat extends TestFmwk {
     33 
     34     public NumberFormat fNumberFormat;
     35 
     36     /**
     37      * Internal use
     38      */
     39     private void _testLocale(Locale locale) {
     40         String localeName = locale + " (" + locale.getDisplayName() + ")";
     41 
     42         logln("Number test " + localeName);
     43         fNumberFormat = NumberFormat.getInstance(locale);
     44         _testFormat();
     45 
     46         logln("Currency test " + localeName);
     47         fNumberFormat = NumberFormat.getCurrencyInstance(locale);
     48         _testFormat();
     49 
     50         logln("Percent test " + localeName);
     51         fNumberFormat = NumberFormat.getPercentInstance(locale);
     52         _testFormat();
     53 
     54         if (locale.toString().compareTo("en_US_POSIX") != 0 ) {
     55            logln("Scientific test " + localeName);
     56            fNumberFormat = NumberFormat.getScientificInstance(locale);
     57            _testFormat();
     58         }
     59     }
     60 
     61     /**
     62      * call _testFormat for currency, percent and plain number instances
     63      */
     64     @Test
     65     public void TestLocale() {
     66         Locale locale = Locale.getDefault();
     67         String localeName = locale + " (" + locale.getDisplayName() + ")";
     68 
     69         logln("Number test " + localeName);
     70         fNumberFormat = NumberFormat.getInstance(locale);
     71         _testFormat();
     72 
     73         logln("Currency test " + localeName);
     74         fNumberFormat = NumberFormat.getCurrencyInstance(locale);
     75         _testFormat();
     76 
     77         logln("Percent test " + localeName);
     78         fNumberFormat = NumberFormat.getPercentInstance(locale);
     79         _testFormat();
     80     }
     81 
     82     /**
     83      * call tryIt with many variations, called by testLocale
     84      */
     85     private void _testFormat() {
     86 
     87         if (fNumberFormat == null){
     88             errln("**** FAIL: Null format returned by createXxxInstance.");
     89              return;
     90         }
     91         DecimalFormat s = (DecimalFormat)fNumberFormat;
     92         logln("pattern :" + s.toPattern());
     93 
     94         tryIt(-2.02147304840132e-68);
     95         tryIt(3.88057859588817e-68);
     96         tryIt(-2.64651110485945e+65);
     97         tryIt(9.29526819488338e+64);
     98 
     99         tryIt(-2.02147304840132e-100);
    100         tryIt(3.88057859588817e-096);
    101         tryIt(-2.64651110485945e+306);
    102         tryIt(9.29526819488338e+250);
    103 
    104         tryIt(-9.18228054496402e+64);
    105         tryIt(-9.69413034454191e+64);
    106 
    107         tryIt(-9.18228054496402e+255);
    108         tryIt(-9.69413034454191e+273);
    109 
    110 
    111         tryIt(1.234e-200);
    112         tryIt(-2.3e-168);
    113 
    114         tryIt(Double.NaN);
    115         tryIt(Double.POSITIVE_INFINITY);
    116         tryIt(Double.NEGATIVE_INFINITY);
    117 
    118         tryIt(251887531);
    119         tryIt(5e-20 / 9);
    120         tryIt(5e20 / 9);
    121         tryIt(1.234e-50);
    122         tryIt(9.99999999999996);
    123         tryIt(9.999999999999996);
    124 
    125         tryIt(5.06e-27);
    126 
    127         tryIt(Integer.MIN_VALUE);
    128         tryIt(Integer.MAX_VALUE);
    129         tryIt((double)Integer.MIN_VALUE);
    130         tryIt((double)Integer.MAX_VALUE);
    131         tryIt(Integer.MIN_VALUE - 1.0);
    132         tryIt(Integer.MAX_VALUE + 1.0);
    133 
    134         tryIt(5.0 / 9.0 * 1e-20);
    135         tryIt(4.0 / 9.0 * 1e-20);
    136         tryIt(5.0 / 9.0 * 1e+20);
    137         tryIt(4.0 / 9.0 * 1e+20);
    138 
    139         tryIt(2147483647.);
    140         tryIt(0);
    141         tryIt(0.0);
    142         tryIt(1);
    143         tryIt(10);
    144         tryIt(100);
    145         tryIt(-1);
    146         tryIt(-10);
    147         tryIt(-100);
    148         tryIt(-1913860352);
    149 
    150         Random random = createRandom(); // use test framework's random seed
    151         for (int j = 0; j < 10; j++) {
    152             double d = random.nextDouble()*2e10 - 1e10;
    153             tryIt(d);
    154 
    155         }
    156     }
    157 
    158     /**
    159      * Perform tests using aNumber and fNumberFormat, called in many variations
    160      */
    161     public void tryIt(double aNumber) {
    162         final int DEPTH = 10;
    163         double[] number = new double[DEPTH];
    164         String[] string = new String[DEPTH];
    165         int numberMatch = 0;
    166         int stringMatch = 0;
    167         boolean dump = false;
    168         int i;
    169 
    170         for (i = 0; i < DEPTH; i++) {
    171             if (i == 0) {
    172                 number[i] = aNumber;
    173             } else {
    174                 try {
    175                     number[i - 1] = fNumberFormat.parse(string[i - 1]).doubleValue();
    176                 } catch(java.text.ParseException pe) {
    177                     errln("**** FAIL: Parse of " + string[i-1] + " failed.");
    178                     dump = true;
    179                     break;
    180                 }
    181             }
    182 
    183             string[i] = fNumberFormat.format(number[i]);
    184             if (i > 0)
    185             {
    186                 if (numberMatch == 0 && number[i] == number[i-1])
    187                     numberMatch = i;
    188                 else if (numberMatch > 0 && number[i] != number[i-1])
    189                 {
    190                     errln("**** FAIL: Numeric mismatch after match.");
    191                     dump = true;
    192                     break;
    193                 }
    194                 if (stringMatch == 0 && string[i] == string[i-1])
    195                     stringMatch = i;
    196                 else if (stringMatch > 0 && string[i] != string[i-1])
    197                 {
    198                     errln("**** FAIL: String mismatch after match.");
    199                     dump = true;
    200                     break;
    201                 }
    202             }
    203             if (numberMatch > 0 && stringMatch > 0)
    204                 break;
    205 
    206             if (i == DEPTH)
    207             --i;
    208 
    209         if (stringMatch > 2 || numberMatch > 2)
    210         {
    211             errln("**** FAIL: No string and/or number match within 2 iterations.");
    212             dump = true;
    213         }
    214 
    215         if (dump)
    216         {
    217             for (int k=0; k<=i; ++k)
    218             {
    219                 logln(k + ": " + number[k] + " F> " +
    220                       string[k] + " P> ");
    221             }
    222         }
    223         }
    224     }
    225 
    226     /**
    227      *  perform tests using aNumber and fNumberFormat, called in many variations
    228      **/
    229     public void tryIt(int aNumber) {
    230         long number;
    231 
    232         String stringNum = fNumberFormat.format(aNumber);
    233         try {
    234             number = fNumberFormat.parse(stringNum).longValue();
    235         } catch (java.text.ParseException pe) {
    236             errln("**** FAIL: Parse of " + stringNum + " failed.");
    237             return;
    238         }
    239 
    240         if (number != aNumber) {
    241             errln("**** FAIL: Parse of " + stringNum + " failed. Got:" + number
    242                 + " Expected:" + aNumber);
    243         }
    244 
    245     }
    246 
    247     /**
    248      *  test NumberFormat::getAvailableLocales
    249      **/
    250     @Test
    251     public void TestAvailableLocales() {
    252         final Locale[] locales = NumberFormat.getAvailableLocales();
    253         int count = locales.length;
    254         logln(count + " available locales");
    255         if (count != 0)
    256         {
    257             String all = "";
    258             for (int i = 0; i< count; ++i)
    259             {
    260                 if (i!=0)
    261                     all += ", ";
    262                 all += locales[i].getDisplayName();
    263             }
    264             logln(all);
    265         }
    266         else
    267             errln("**** FAIL: Zero available locales or null array pointer");
    268     }
    269 
    270     /**
    271      *  call testLocale for all locales
    272      **/
    273     @Test
    274     public void TestMonster() {
    275         final String SEP = "============================================================\n";
    276         int count;
    277         final Locale[] allLocales = NumberFormat.getAvailableLocales();
    278         Locale[] locales = allLocales;
    279         count = locales.length;
    280         if (count != 0)
    281         {
    282             if (TestFmwk.getExhaustiveness() < 10 && count > 6) {
    283                 count = 6;
    284                 locales = new Locale[6];
    285                 locales[0] = allLocales[0];
    286                 locales[1] = allLocales[1];
    287                 locales[2] = allLocales[2];
    288                 // In a quick test, make sure we test locales that use
    289                 // currency prefix, currency suffix, and choice currency
    290                 // logic.  Otherwise bugs in these areas can slip through.
    291                 locales[3] = new Locale("ar", "AE", "");
    292                 locales[4] = new Locale("cs", "CZ", "");
    293                 locales[5] = new Locale("en", "IN", "");
    294             }
    295             for (int i=0; i<count; ++i)
    296             {
    297                 logln(SEP);
    298                 _testLocale(locales[i]);
    299             }
    300         }
    301 
    302         logln(SEP);
    303     }
    304 }
    305