Home | History | Annotate | Download | only in intltest
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1997-2015, International Business Machines Corporation and
      4  * others. All Rights Reserved.
      5  ********************************************************************/
      6 
      7 #include "unicode/utypes.h"
      8 
      9 #if !UCONFIG_NO_FORMATTING
     10 
     11 #include "dcfmapts.h"
     12 
     13 #include "unicode/currpinf.h"
     14 #include "unicode/dcfmtsym.h"
     15 #include "unicode/decimfmt.h"
     16 #include "unicode/fmtable.h"
     17 #include "unicode/localpointer.h"
     18 #include "unicode/parseerr.h"
     19 #include "unicode/stringpiece.h"
     20 
     21 #include "putilimp.h"
     22 #include "plurrule_impl.h"
     23 #include <stdio.h>
     24 
     25 // This is an API test, not a unit test.  It doesn't test very many cases, and doesn't
     26 // try to test the full functionality.  It just calls each function in the class and
     27 // verifies that it works on a basic level.
     28 
     29 void IntlTestDecimalFormatAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
     30 {
     31     if (exec) logln((UnicodeString)"TestSuite DecimalFormatAPI");
     32     switch (index) {
     33         case 0: name = "DecimalFormat API test";
     34                 if (exec) {
     35                     logln((UnicodeString)"DecimalFormat API test---"); logln((UnicodeString)"");
     36                     UErrorCode status = U_ZERO_ERROR;
     37                     Locale saveLocale;
     38                     Locale::setDefault(Locale::getEnglish(), status);
     39                     if(U_FAILURE(status)) {
     40                         errln((UnicodeString)"ERROR: Could not set default locale, test may not give correct results");
     41                     }
     42                     testAPI(/*par*/);
     43                     Locale::setDefault(saveLocale, status);
     44                 }
     45                 break;
     46         case 1: name = "Rounding test";
     47             if(exec) {
     48                logln((UnicodeString)"DecimalFormat Rounding test---");
     49                testRounding(/*par*/);
     50             }
     51             break;
     52         case 2: name = "Test6354";
     53             if(exec) {
     54                logln((UnicodeString)"DecimalFormat Rounding Increment test---");
     55                testRoundingInc(/*par*/);
     56             }
     57             break;
     58         case 3: name = "TestCurrencyPluralInfo";
     59             if(exec) {
     60                logln((UnicodeString)"CurrencyPluralInfo API test---");
     61                TestCurrencyPluralInfo();
     62             }
     63             break;
     64         case 4: name = "TestScale";
     65             if(exec) {
     66                logln((UnicodeString)"Scale test---");
     67                TestScale();
     68             }
     69             break;
     70          case 5: name = "TestFixedDecimal";
     71             if(exec) {
     72                logln((UnicodeString)"TestFixedDecimal ---");
     73                TestFixedDecimal();
     74             }
     75             break;
     76          case 6: name = "TestBadFastpath";
     77             if(exec) {
     78                logln((UnicodeString)"TestBadFastpath ---");
     79                TestBadFastpath();
     80             }
     81             break;
     82          case 7: name = "TestRequiredDecimalPoint";
     83             if(exec) {
     84                logln((UnicodeString)"TestRequiredDecimalPoint ---");
     85                TestRequiredDecimalPoint();
     86             }
     87             break;
     88        default: name = ""; break;
     89     }
     90 }
     91 
     92 /**
     93  * This test checks various generic API methods in DecimalFormat to achieve 100%
     94  * API coverage.
     95  */
     96 void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
     97 {
     98     UErrorCode status = U_ZERO_ERROR;
     99 
    100 // ======= Test constructors
    101 
    102     logln((UnicodeString)"Testing DecimalFormat constructors");
    103 
    104     DecimalFormat def(status);
    105     if(U_FAILURE(status)) {
    106         errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
    107         return;
    108     }
    109 
    110     // bug 10864
    111     status = U_ZERO_ERROR;
    112     DecimalFormat noGrouping("###0.##", status);
    113     if (noGrouping.getGroupingSize() != 0) {
    114       errln("Grouping size should be 0 for no grouping.");
    115     }
    116     noGrouping.setGroupingUsed(TRUE);
    117     if (noGrouping.getGroupingSize() != 0) {
    118       errln("Grouping size should still be 0.");
    119     }
    120     // end bug 10864
    121 
    122     status = U_ZERO_ERROR;
    123     const UnicodeString pattern("#,##0.# FF");
    124     DecimalFormat pat(pattern, status);
    125     if(U_FAILURE(status)) {
    126         errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern)");
    127         return;
    128     }
    129 
    130     status = U_ZERO_ERROR;
    131     DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getFrench(), status);
    132     if(U_FAILURE(status)) {
    133         errln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (French)");
    134         return;
    135     }
    136 
    137     status = U_ZERO_ERROR;
    138     DecimalFormat cust1(pattern, symbols, status);
    139     if(U_FAILURE(status)) {
    140         errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
    141     }
    142 
    143     status = U_ZERO_ERROR;
    144     DecimalFormat cust2(pattern, *symbols, status);
    145     if(U_FAILURE(status)) {
    146         errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols)");
    147     }
    148 
    149     DecimalFormat copy(pat);
    150 
    151 // ======= Test clone(), assignment, and equality
    152 
    153     logln((UnicodeString)"Testing clone(), assignment and equality operators");
    154 
    155     if( ! (copy == pat) || copy != pat) {
    156         errln((UnicodeString)"ERROR: Copy constructor or == failed");
    157     }
    158 
    159     copy = cust1;
    160     if(copy != cust1) {
    161         errln((UnicodeString)"ERROR: Assignment (or !=) failed");
    162     }
    163 
    164     Format *clone = def.clone();
    165     if( ! (*clone == def) ) {
    166         errln((UnicodeString)"ERROR: Clone() failed");
    167     }
    168     delete clone;
    169 
    170 // ======= Test various format() methods
    171 
    172     logln((UnicodeString)"Testing various format() methods");
    173 
    174     double d = -10456.0037;
    175     int32_t l = 100000000;
    176     Formattable fD(d);
    177     Formattable fL(l);
    178 
    179     UnicodeString res1, res2, res3, res4;
    180     FieldPosition pos1(0), pos2(0), pos3(0), pos4(0);
    181 
    182     res1 = def.format(d, res1, pos1);
    183     logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1);
    184 
    185     res2 = pat.format(l, res2, pos2);
    186     logln((UnicodeString) "" + (int32_t) l + " formatted to " + res2);
    187 
    188     status = U_ZERO_ERROR;
    189     res3 = cust1.format(fD, res3, pos3, status);
    190     if(U_FAILURE(status)) {
    191         errln((UnicodeString)"ERROR: format(Formattable [double]) failed");
    192     }
    193     logln((UnicodeString) "" + (int32_t) fD.getDouble() + " formatted to " + res3);
    194 
    195     status = U_ZERO_ERROR;
    196     res4 = cust2.format(fL, res4, pos4, status);
    197     if(U_FAILURE(status)) {
    198         errln((UnicodeString)"ERROR: format(Formattable [long]) failed");
    199     }
    200     logln((UnicodeString) "" + fL.getLong() + " formatted to " + res4);
    201 
    202 // ======= Test parse()
    203 
    204     logln((UnicodeString)"Testing parse()");
    205 
    206     UnicodeString text("-10,456.0037");
    207     Formattable result1, result2;
    208     ParsePosition pos(0);
    209     UnicodeString patt("#,##0.#");
    210     status = U_ZERO_ERROR;
    211     pat.applyPattern(patt, status);
    212     if(U_FAILURE(status)) {
    213         errln((UnicodeString)"ERROR: applyPattern() failed");
    214     }
    215     pat.parse(text, result1, pos);
    216     if(result1.getType() != Formattable::kDouble && result1.getDouble() != d) {
    217         errln((UnicodeString)"ERROR: Roundtrip failed (via parse()) for " + text);
    218     }
    219     logln(text + " parsed into " + (int32_t) result1.getDouble());
    220 
    221     status = U_ZERO_ERROR;
    222     pat.parse(text, result2, status);
    223     if(U_FAILURE(status)) {
    224         errln((UnicodeString)"ERROR: parse() failed");
    225     }
    226     if(result2.getType() != Formattable::kDouble && result2.getDouble() != d) {
    227         errln((UnicodeString)"ERROR: Roundtrip failed (via parse()) for " + text);
    228     }
    229     logln(text + " parsed into " + (int32_t) result2.getDouble());
    230 
    231 // ======= Test getters and setters
    232 
    233     logln((UnicodeString)"Testing getters and setters");
    234 
    235     const DecimalFormatSymbols *syms = pat.getDecimalFormatSymbols();
    236     DecimalFormatSymbols *newSyms = new DecimalFormatSymbols(*syms);
    237     def.setDecimalFormatSymbols(*newSyms);
    238     def.adoptDecimalFormatSymbols(newSyms); // don't use newSyms after this
    239     if( *(pat.getDecimalFormatSymbols()) != *(def.getDecimalFormatSymbols())) {
    240         errln((UnicodeString)"ERROR: adopt or set DecimalFormatSymbols() failed");
    241     }
    242 
    243     UnicodeString posPrefix;
    244     pat.setPositivePrefix("+");
    245     posPrefix = pat.getPositivePrefix(posPrefix);
    246     logln((UnicodeString)"Positive prefix (should be +): " + posPrefix);
    247     if(posPrefix != "+") {
    248         errln((UnicodeString)"ERROR: setPositivePrefix() failed");
    249     }
    250 
    251     UnicodeString negPrefix;
    252     pat.setNegativePrefix("-");
    253     negPrefix = pat.getNegativePrefix(negPrefix);
    254     logln((UnicodeString)"Negative prefix (should be -): " + negPrefix);
    255     if(negPrefix != "-") {
    256         errln((UnicodeString)"ERROR: setNegativePrefix() failed");
    257     }
    258 
    259     UnicodeString posSuffix;
    260     pat.setPositiveSuffix("_");
    261     posSuffix = pat.getPositiveSuffix(posSuffix);
    262     logln((UnicodeString)"Positive suffix (should be _): " + posSuffix);
    263     if(posSuffix != "_") {
    264         errln((UnicodeString)"ERROR: setPositiveSuffix() failed");
    265     }
    266 
    267     UnicodeString negSuffix;
    268     pat.setNegativeSuffix("~");
    269     negSuffix = pat.getNegativeSuffix(negSuffix);
    270     logln((UnicodeString)"Negative suffix (should be ~): " + negSuffix);
    271     if(negSuffix != "~") {
    272         errln((UnicodeString)"ERROR: setNegativeSuffix() failed");
    273     }
    274 
    275     int32_t multiplier = 0;
    276     pat.setMultiplier(8);
    277     multiplier = pat.getMultiplier();
    278     logln((UnicodeString)"Multiplier (should be 8): " + multiplier);
    279     if(multiplier != 8) {
    280         errln((UnicodeString)"ERROR: setMultiplier() failed");
    281     }
    282 
    283     int32_t groupingSize = 0;
    284     pat.setGroupingSize(2);
    285     groupingSize = pat.getGroupingSize();
    286     logln((UnicodeString)"Grouping size (should be 2): " + (int32_t) groupingSize);
    287     if(groupingSize != 2) {
    288         errln((UnicodeString)"ERROR: setGroupingSize() failed");
    289     }
    290 
    291     pat.setDecimalSeparatorAlwaysShown(TRUE);
    292     UBool tf = pat.isDecimalSeparatorAlwaysShown();
    293     logln((UnicodeString)"DecimalSeparatorIsAlwaysShown (should be TRUE) is " + (UnicodeString) (tf ? "TRUE" : "FALSE"));
    294     if(tf != TRUE) {
    295         errln((UnicodeString)"ERROR: setDecimalSeparatorAlwaysShown() failed");
    296     }
    297     // Added by Ken Liu testing set/isExponentSignAlwaysShown
    298     pat.setExponentSignAlwaysShown(TRUE);
    299     UBool esas = pat.isExponentSignAlwaysShown();
    300     logln((UnicodeString)"ExponentSignAlwaysShown (should be TRUE) is " + (UnicodeString) (esas ? "TRUE" : "FALSE"));
    301     if(esas != TRUE) {
    302         errln((UnicodeString)"ERROR: ExponentSignAlwaysShown() failed");
    303     }
    304 
    305     // Added by Ken Liu testing set/isScientificNotation
    306     pat.setScientificNotation(TRUE);
    307     UBool sn = pat.isScientificNotation();
    308     logln((UnicodeString)"isScientificNotation (should be TRUE) is " + (UnicodeString) (sn ? "TRUE" : "FALSE"));
    309     if(sn != TRUE) {
    310         errln((UnicodeString)"ERROR: setScientificNotation() failed");
    311     }
    312 
    313     // Added by Ken Liu testing set/getMinimumExponentDigits
    314     int8_t MinimumExponentDigits = 0;
    315     pat.setMinimumExponentDigits(2);
    316     MinimumExponentDigits = pat.getMinimumExponentDigits();
    317     logln((UnicodeString)"MinimumExponentDigits (should be 2) is " + (int8_t) MinimumExponentDigits);
    318     if(MinimumExponentDigits != 2) {
    319         errln((UnicodeString)"ERROR: setMinimumExponentDigits() failed");
    320     }
    321 
    322     // Added by Ken Liu testing set/getRoundingIncrement
    323     double RoundingIncrement = 0.0;
    324     pat.setRoundingIncrement(2.0);
    325     RoundingIncrement = pat.getRoundingIncrement();
    326     logln((UnicodeString)"RoundingIncrement (should be 2.0) is " + (double) RoundingIncrement);
    327     if(RoundingIncrement != 2.0) {
    328         errln((UnicodeString)"ERROR: setRoundingIncrement() failed");
    329     }
    330     //end of Ken's Adding
    331 
    332     UnicodeString funkyPat;
    333     funkyPat = pat.toPattern(funkyPat);
    334     logln((UnicodeString)"Pattern is " + funkyPat);
    335 
    336     UnicodeString locPat;
    337     locPat = pat.toLocalizedPattern(locPat);
    338     logln((UnicodeString)"Localized pattern is " + locPat);
    339 
    340 // ======= Test applyPattern()
    341 
    342     logln((UnicodeString)"Testing applyPattern()");
    343 
    344     UnicodeString p1("#,##0.0#;(#,##0.0#)");
    345     logln((UnicodeString)"Applying pattern " + p1);
    346     status = U_ZERO_ERROR;
    347     pat.applyPattern(p1, status);
    348     if(U_FAILURE(status)) {
    349         errln((UnicodeString)"ERROR: applyPattern() failed with " + (int32_t) status);
    350     }
    351     UnicodeString s2;
    352     s2 = pat.toPattern(s2);
    353     logln((UnicodeString)"Extracted pattern is " + s2);
    354     if(s2 != p1) {
    355         errln((UnicodeString)"ERROR: toPattern() result did not match pattern applied");
    356     }
    357 
    358     if(pat.getSecondaryGroupingSize() != 0) {
    359         errln("FAIL: Secondary Grouping Size should be 0, not %d\n", pat.getSecondaryGroupingSize());
    360     }
    361 
    362     if(pat.getGroupingSize() != 3) {
    363         errln("FAIL: Primary Grouping Size should be 3, not %d\n", pat.getGroupingSize());
    364     }
    365 
    366     UnicodeString p2("#,##,##0.0# FF;(#,##,##0.0# FF)");
    367     logln((UnicodeString)"Applying pattern " + p2);
    368     status = U_ZERO_ERROR;
    369     pat.applyLocalizedPattern(p2, status);
    370     if(U_FAILURE(status)) {
    371         errln((UnicodeString)"ERROR: applyPattern() failed with " + (int32_t) status);
    372     }
    373     UnicodeString s3;
    374     s3 = pat.toLocalizedPattern(s3);
    375     logln((UnicodeString)"Extracted pattern is " + s3);
    376     if(s3 != p2) {
    377         errln((UnicodeString)"ERROR: toLocalizedPattern() result did not match pattern applied");
    378     }
    379 
    380     status = U_ZERO_ERROR;
    381     UParseError pe;
    382     pat.applyLocalizedPattern(p2, pe, status);
    383     if(U_FAILURE(status)) {
    384         errln((UnicodeString)"ERROR: applyPattern((with ParseError)) failed with " + (int32_t) status);
    385     }
    386     UnicodeString s4;
    387     s4 = pat.toLocalizedPattern(s3);
    388     logln((UnicodeString)"Extracted pattern is " + s4);
    389     if(s4 != p2) {
    390         errln((UnicodeString)"ERROR: toLocalizedPattern(with ParseErr) result did not match pattern applied");
    391     }
    392 
    393     if(pat.getSecondaryGroupingSize() != 2) {
    394         errln("FAIL: Secondary Grouping Size should be 2, not %d\n", pat.getSecondaryGroupingSize());
    395     }
    396 
    397     if(pat.getGroupingSize() != 3) {
    398         errln("FAIL: Primary Grouping Size should be 3, not %d\n", pat.getGroupingSize());
    399     }
    400 
    401 // ======= Test getStaticClassID()
    402 
    403     logln((UnicodeString)"Testing getStaticClassID()");
    404 
    405     status = U_ZERO_ERROR;
    406     NumberFormat *test = new DecimalFormat(status);
    407     if(U_FAILURE(status)) {
    408         errln((UnicodeString)"ERROR: Couldn't create a DecimalFormat");
    409     }
    410 
    411     if(test->getDynamicClassID() != DecimalFormat::getStaticClassID()) {
    412         errln((UnicodeString)"ERROR: getDynamicClassID() didn't return the expected value");
    413     }
    414 
    415     delete test;
    416 }
    417 
    418 void IntlTestDecimalFormatAPI::TestCurrencyPluralInfo(){
    419     UErrorCode status = U_ZERO_ERROR;
    420 
    421     CurrencyPluralInfo *cpi = new CurrencyPluralInfo(status);
    422     if(U_FAILURE(status)) {
    423         errln((UnicodeString)"ERROR: CurrencyPluralInfo(UErrorCode) could not be created");
    424     }
    425 
    426     CurrencyPluralInfo cpi1 = *cpi;
    427 
    428     if(cpi->getDynamicClassID() != CurrencyPluralInfo::getStaticClassID()){
    429         errln((UnicodeString)"ERROR: CurrencyPluralInfo::getDynamicClassID() didn't return the expected value");
    430     }
    431 
    432     cpi->setCurrencyPluralPattern("","",status);
    433     if(U_FAILURE(status)) {
    434         errln((UnicodeString)"ERROR: CurrencyPluralInfo::setCurrencyPluralPattern");
    435     }
    436 
    437     cpi->setLocale(Locale::getCanada(), status);
    438     if(U_FAILURE(status)) {
    439         errln((UnicodeString)"ERROR: CurrencyPluralInfo::setLocale");
    440     }
    441 
    442     cpi->setPluralRules("",status);
    443     if(U_FAILURE(status)) {
    444         errln((UnicodeString)"ERROR: CurrencyPluralInfo::setPluralRules");
    445     }
    446 
    447     DecimalFormat *df = new DecimalFormat(status);
    448     if(U_FAILURE(status)) {
    449         errcheckln(status, "ERROR: Could not create DecimalFormat - %s", u_errorName(status));
    450         return;
    451     }
    452 
    453     df->adoptCurrencyPluralInfo(cpi);
    454 
    455     df->getCurrencyPluralInfo();
    456 
    457     df->setCurrencyPluralInfo(cpi1);
    458 
    459     delete df;
    460 }
    461 
    462 void IntlTestDecimalFormatAPI::testRounding(/*char *par*/)
    463 {
    464     UErrorCode status = U_ZERO_ERROR;
    465     double Roundingnumber = 2.55;
    466     double Roundingnumber1 = -2.55;
    467                       //+2.55 results   -2.55 results
    468     double result[]={   3.0,            -2.0,    //  kRoundCeiling  0,
    469                         2.0,            -3.0,    //  kRoundFloor    1,
    470                         2.0,            -2.0,    //  kRoundDown     2,
    471                         3.0,            -3.0,    //  kRoundUp       3,
    472                         3.0,            -3.0,    //  kRoundHalfEven 4,
    473                         3.0,            -3.0,    //  kRoundHalfDown 5,
    474                         3.0,            -3.0     //  kRoundHalfUp   6
    475     };
    476     DecimalFormat pat(status);
    477     if(U_FAILURE(status)) {
    478       errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
    479       return;
    480     }
    481     uint16_t mode;
    482     uint16_t i=0;
    483     UnicodeString message;
    484     UnicodeString resultStr;
    485     for(mode=0;mode < 7;mode++){
    486         pat.setRoundingMode((DecimalFormat::ERoundingMode)mode);
    487         if(pat.getRoundingMode() != (DecimalFormat::ERoundingMode)mode){
    488             errln((UnicodeString)"SetRoundingMode or GetRoundingMode failed for mode=" + mode);
    489         }
    490 
    491 
    492         //for +2.55 with RoundingIncrement=1.0
    493         pat.setRoundingIncrement(1.0);
    494         pat.format(Roundingnumber, resultStr);
    495         message= (UnicodeString)"Round() failed:  round(" + (double)Roundingnumber + UnicodeString(",") + mode + UnicodeString(",FALSE) with RoundingIncrement=1.0==>");
    496         verify(message, resultStr, result[i++]);
    497         message.remove();
    498         resultStr.remove();
    499 
    500         //for -2.55 with RoundingIncrement=1.0
    501         pat.format(Roundingnumber1, resultStr);
    502         message= (UnicodeString)"Round() failed:  round(" + (double)Roundingnumber1 + UnicodeString(",") + mode + UnicodeString(",FALSE) with RoundingIncrement=1.0==>");
    503         verify(message, resultStr, result[i++]);
    504         message.remove();
    505         resultStr.remove();
    506     }
    507 
    508 }
    509 void IntlTestDecimalFormatAPI::verify(const UnicodeString& message, const UnicodeString& got, double expected){
    510     logln((UnicodeString)message + got + (UnicodeString)" Expected : " + expected);
    511     UnicodeString expectedStr("");
    512     expectedStr=expectedStr + expected;
    513     if(got != expectedStr ) {
    514             errln((UnicodeString)"ERROR: " + message + got + (UnicodeString)"  Expected : " + expectedStr);
    515         }
    516 }
    517 
    518 void IntlTestDecimalFormatAPI::verifyString(const UnicodeString& message, const UnicodeString& got, UnicodeString& expected){
    519     logln((UnicodeString)message + got + (UnicodeString)" Expected : " + expected);
    520     if(got != expected ) {
    521             errln((UnicodeString)"ERROR: " + message + got + (UnicodeString)"  Expected : " + expected);
    522         }
    523 }
    524 
    525 void IntlTestDecimalFormatAPI::testRoundingInc(/*char *par*/)
    526 {
    527     UErrorCode status = U_ZERO_ERROR;
    528     DecimalFormat pat(UnicodeString("#,##0.00"),status);
    529     if(U_FAILURE(status)) {
    530       errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
    531       return;
    532     }
    533 
    534     // get default rounding increment
    535     double roundingInc = pat.getRoundingIncrement();
    536     if (roundingInc != 0.0) {
    537       errln((UnicodeString)"ERROR: Rounding increment not zero");
    538       return;
    539     }
    540 
    541     // With rounding now being handled by decNumber, we no longer
    542     // set a rounding increment to enable non-default mode rounding,
    543     // checking of which was the original point of this test.
    544 
    545     // set rounding mode with zero increment.  Rounding
    546     // increment should not be set by this operation
    547     pat.setRoundingMode((DecimalFormat::ERoundingMode)0);
    548     roundingInc = pat.getRoundingIncrement();
    549     if (roundingInc != 0.0) {
    550       errln((UnicodeString)"ERROR: Rounding increment not zero after setRoundingMode");
    551       return;
    552     }
    553 }
    554 
    555 void IntlTestDecimalFormatAPI::TestScale()
    556 {
    557     typedef struct TestData {
    558         double inputValue;
    559         int inputScale;
    560         const char *expectedOutput;
    561     } TestData;
    562 
    563     static TestData testData[] = {
    564         { 100.0, 3,  "100,000" },
    565         { 10034.0, -2, "100.34" },
    566         { 0.86, -3, "0.0009" },
    567         { -0.000455, 1, "-0%" },
    568         { -0.000555, 1, "-1%" },
    569         { 0.000455, 1, "0%" },
    570         { 0.000555, 1, "1%" },
    571     };
    572 
    573     UErrorCode status = U_ZERO_ERROR;
    574     DecimalFormat pat(status);
    575     if(U_FAILURE(status)) {
    576       errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
    577       return;
    578     }
    579 
    580     UnicodeString message;
    581     UnicodeString resultStr;
    582     UnicodeString exp;
    583     UnicodeString percentPattern("#,##0%");
    584     pat.setMaximumFractionDigits(4);
    585 
    586     for(int32_t i=0; i < UPRV_LENGTHOF(testData); i++) {
    587         if ( i > 2 ) {
    588             pat.applyPattern(percentPattern,status);
    589         }
    590         pat.setAttribute(UNUM_SCALE,testData[i].inputScale,status);
    591         pat.format(testData[i].inputValue, resultStr);
    592         message = UnicodeString("Unexpected output for ") + testData[i].inputValue + UnicodeString(" and scale ") +
    593                   testData[i].inputScale + UnicodeString(". Got: ");
    594         exp = testData[i].expectedOutput;
    595         verifyString(message, resultStr, exp);
    596         message.remove();
    597         resultStr.remove();
    598         exp.remove();
    599     }
    600 }
    601 
    602 
    603 #define ASSERT_EQUAL(expect, actual) { char tmp[200]; sprintf(tmp, "(%g==%g)", (double)(expect), (double)(actual)); \
    604     assertTrue(tmp, ((expect)==(actual)), FALSE, TRUE, __FILE__, __LINE__); }
    605 
    606 void IntlTestDecimalFormatAPI::TestFixedDecimal() {
    607     UErrorCode status = U_ZERO_ERROR;
    608 
    609     LocalPointer<DecimalFormat> df(new DecimalFormat("###", status), status);
    610     TEST_ASSERT_STATUS(status);
    611     if (status == U_MISSING_RESOURCE_ERROR) {
    612         return;
    613     }
    614     FixedDecimal fd = df->getFixedDecimal(44, status);
    615     TEST_ASSERT_STATUS(status);
    616     ASSERT_EQUAL(44, fd.source);
    617     ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
    618     ASSERT_EQUAL(FALSE, fd.isNegative);
    619 
    620     fd = df->getFixedDecimal(-44, status);
    621     TEST_ASSERT_STATUS(status);
    622     ASSERT_EQUAL(44, fd.source);
    623     ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
    624     ASSERT_EQUAL(TRUE, fd.isNegative);
    625 
    626     df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.00##", status), status);
    627     TEST_ASSERT_STATUS(status);
    628     fd = df->getFixedDecimal(123.456, status);
    629     TEST_ASSERT_STATUS(status);
    630     ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
    631     ASSERT_EQUAL(456, fd.decimalDigits); // f
    632     ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
    633     ASSERT_EQUAL(123, fd.intValue); // i
    634     ASSERT_EQUAL(123.456, fd.source); // n
    635     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    636     ASSERT_EQUAL(FALSE, fd.isNegative);
    637 
    638     fd = df->getFixedDecimal(-123.456, status);
    639     TEST_ASSERT_STATUS(status);
    640     ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
    641     ASSERT_EQUAL(456, fd.decimalDigits); // f
    642     ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
    643     ASSERT_EQUAL(123, fd.intValue); // i
    644     ASSERT_EQUAL(123.456, fd.source); // n
    645     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    646     ASSERT_EQUAL(TRUE, fd.isNegative);
    647 
    648     // test max int digits
    649     df->setMaximumIntegerDigits(2);
    650     fd = df->getFixedDecimal(123.456, status);
    651     TEST_ASSERT_STATUS(status);
    652     ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
    653     ASSERT_EQUAL(456, fd.decimalDigits); // f
    654     ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
    655     ASSERT_EQUAL(23, fd.intValue); // i
    656     ASSERT_EQUAL(23.456, fd.source); // n
    657     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    658     ASSERT_EQUAL(FALSE, fd.isNegative);
    659 
    660     fd = df->getFixedDecimal(-123.456, status);
    661     TEST_ASSERT_STATUS(status);
    662     ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
    663     ASSERT_EQUAL(456, fd.decimalDigits); // f
    664     ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
    665     ASSERT_EQUAL(23, fd.intValue); // i
    666     ASSERT_EQUAL(23.456, fd.source); // n
    667     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    668     ASSERT_EQUAL(TRUE, fd.isNegative);
    669 
    670     // test max fraction digits
    671     df->setMaximumIntegerDigits(2000000000);
    672     df->setMaximumFractionDigits(2);
    673     fd = df->getFixedDecimal(123.456, status);
    674     TEST_ASSERT_STATUS(status);
    675     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
    676     ASSERT_EQUAL(46, fd.decimalDigits); // f
    677     ASSERT_EQUAL(46, fd.decimalDigitsWithoutTrailingZeros); // t
    678     ASSERT_EQUAL(123, fd.intValue); // i
    679     ASSERT_EQUAL(123.46, fd.source); // n
    680     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    681     ASSERT_EQUAL(FALSE, fd.isNegative);
    682 
    683     fd = df->getFixedDecimal(-123.456, status);
    684     TEST_ASSERT_STATUS(status);
    685     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
    686     ASSERT_EQUAL(46, fd.decimalDigits); // f
    687     ASSERT_EQUAL(46, fd.decimalDigitsWithoutTrailingZeros); // t
    688     ASSERT_EQUAL(123, fd.intValue); // i
    689     ASSERT_EQUAL(123.46, fd.source); // n
    690     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    691     ASSERT_EQUAL(TRUE, fd.isNegative);
    692 
    693     // test esoteric rounding
    694     df->setMaximumFractionDigits(6);
    695     df->setRoundingIncrement(7.3);
    696 
    697     fd = df->getFixedDecimal(30.0, status);
    698     TEST_ASSERT_STATUS(status);
    699     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
    700     ASSERT_EQUAL(20, fd.decimalDigits); // f
    701     ASSERT_EQUAL(2, fd.decimalDigitsWithoutTrailingZeros); // t
    702     ASSERT_EQUAL(29, fd.intValue); // i
    703     ASSERT_EQUAL(29.2, fd.source); // n
    704     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    705     ASSERT_EQUAL(FALSE, fd.isNegative);
    706 
    707     fd = df->getFixedDecimal(-30.0, status);
    708     TEST_ASSERT_STATUS(status);
    709     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
    710     ASSERT_EQUAL(20, fd.decimalDigits); // f
    711     ASSERT_EQUAL(2, fd.decimalDigitsWithoutTrailingZeros); // t
    712     ASSERT_EQUAL(29, fd.intValue); // i
    713     ASSERT_EQUAL(29.2, fd.source); // n
    714     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    715     ASSERT_EQUAL(TRUE, fd.isNegative);
    716 
    717     df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###", status), status);
    718     TEST_ASSERT_STATUS(status);
    719     fd = df->getFixedDecimal(123.456, status);
    720     TEST_ASSERT_STATUS(status);
    721     ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
    722     ASSERT_EQUAL(0, fd.decimalDigits);
    723     ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
    724     ASSERT_EQUAL(123, fd.intValue);
    725     ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
    726     ASSERT_EQUAL(FALSE, fd.isNegative);
    727 
    728     df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status);
    729     TEST_ASSERT_STATUS(status);
    730     fd = df->getFixedDecimal(123.01, status);
    731     TEST_ASSERT_STATUS(status);
    732     ASSERT_EQUAL(1, fd.visibleDecimalDigitCount);
    733     ASSERT_EQUAL(0, fd.decimalDigits);
    734     ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
    735     ASSERT_EQUAL(123, fd.intValue);
    736     ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
    737     ASSERT_EQUAL(FALSE, fd.isNegative);
    738 
    739     df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status);
    740     TEST_ASSERT_STATUS(status);
    741     fd = df->getFixedDecimal(123.06, status);
    742     TEST_ASSERT_STATUS(status);
    743     ASSERT_EQUAL(1, fd.visibleDecimalDigitCount);
    744     ASSERT_EQUAL(1, fd.decimalDigits);
    745     ASSERT_EQUAL(1, fd.decimalDigitsWithoutTrailingZeros);
    746     ASSERT_EQUAL(123, fd.intValue);
    747     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    748     ASSERT_EQUAL(FALSE, fd.isNegative);
    749 
    750     df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status);  // Significant Digits
    751     TEST_ASSERT_STATUS(status);
    752     fd = df->getFixedDecimal(123, status);
    753     TEST_ASSERT_STATUS(status);
    754     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
    755     ASSERT_EQUAL(0, fd.decimalDigits);
    756     ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
    757     ASSERT_EQUAL(123, fd.intValue);
    758     ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
    759     ASSERT_EQUAL(FALSE, fd.isNegative);
    760 
    761     df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status);  // Significant Digits
    762     TEST_ASSERT_STATUS(status);
    763     fd = df->getFixedDecimal(1.23, status);
    764     TEST_ASSERT_STATUS(status);
    765     ASSERT_EQUAL(4, fd.visibleDecimalDigitCount);
    766     ASSERT_EQUAL(2300, fd.decimalDigits);
    767     ASSERT_EQUAL(23, fd.decimalDigitsWithoutTrailingZeros);
    768     ASSERT_EQUAL(1, fd.intValue);
    769     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    770     ASSERT_EQUAL(FALSE, fd.isNegative);
    771 
    772     fd = df->getFixedDecimal(uprv_getInfinity(), status);
    773     TEST_ASSERT_STATUS(status);
    774     ASSERT_EQUAL(TRUE, fd.isNanOrInfinity);
    775     fd = df->getFixedDecimal(0.0, status);
    776     ASSERT_EQUAL(FALSE, fd.isNanOrInfinity);
    777     fd = df->getFixedDecimal(uprv_getNaN(), status);
    778     ASSERT_EQUAL(TRUE, fd.isNanOrInfinity);
    779     TEST_ASSERT_STATUS(status);
    780 
    781     // Test Big Decimal input.
    782     // 22 digits before and after decimal, will exceed the precision of a double
    783     //    and force DecimalFormat::getFixedDecimal() to work with a digit list.
    784     df.adoptInsteadAndCheckErrorCode(
    785         new DecimalFormat("#####################0.00####################", status), status);
    786     TEST_ASSERT_STATUS(status);
    787     Formattable fable("12.34", status);
    788     TEST_ASSERT_STATUS(status);
    789     fd = df->getFixedDecimal(fable, status);
    790     TEST_ASSERT_STATUS(status);
    791     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
    792     ASSERT_EQUAL(34, fd.decimalDigits);
    793     ASSERT_EQUAL(34, fd.decimalDigitsWithoutTrailingZeros);
    794     ASSERT_EQUAL(12, fd.intValue);
    795     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    796     ASSERT_EQUAL(FALSE, fd.isNegative);
    797 
    798     fable.setDecimalNumber("12.345678901234567890123456789", status);
    799     TEST_ASSERT_STATUS(status);
    800     fd = df->getFixedDecimal(fable, status);
    801     TEST_ASSERT_STATUS(status);
    802     ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
    803     ASSERT_EQUAL(345678901234567890LL, fd.decimalDigits);
    804     ASSERT_EQUAL(34567890123456789LL, fd.decimalDigitsWithoutTrailingZeros);
    805     ASSERT_EQUAL(12, fd.intValue);
    806     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    807     ASSERT_EQUAL(FALSE, fd.isNegative);
    808 
    809     // On field overflow, Integer part is truncated on the left, fraction part on the right.
    810     fable.setDecimalNumber("123456789012345678901234567890.123456789012345678901234567890", status);
    811     TEST_ASSERT_STATUS(status);
    812     fd = df->getFixedDecimal(fable, status);
    813     TEST_ASSERT_STATUS(status);
    814     ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
    815     ASSERT_EQUAL(123456789012345678LL, fd.decimalDigits);
    816     ASSERT_EQUAL(123456789012345678LL, fd.decimalDigitsWithoutTrailingZeros);
    817     ASSERT_EQUAL(345678901234567890LL, fd.intValue);
    818     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    819     ASSERT_EQUAL(FALSE, fd.isNegative);
    820 
    821     // Digits way to the right of the decimal but within the format's precision aren't truncated
    822     fable.setDecimalNumber("1.0000000000000000000012", status);
    823     TEST_ASSERT_STATUS(status);
    824     fd = df->getFixedDecimal(fable, status);
    825     TEST_ASSERT_STATUS(status);
    826     ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
    827     ASSERT_EQUAL(12, fd.decimalDigits);
    828     ASSERT_EQUAL(12, fd.decimalDigitsWithoutTrailingZeros);
    829     ASSERT_EQUAL(1, fd.intValue);
    830     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    831     ASSERT_EQUAL(FALSE, fd.isNegative);
    832 
    833     // Digits beyond the precision of the format are rounded away
    834     fable.setDecimalNumber("1.000000000000000000000012", status);
    835     TEST_ASSERT_STATUS(status);
    836     fd = df->getFixedDecimal(fable, status);
    837     TEST_ASSERT_STATUS(status);
    838     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
    839     ASSERT_EQUAL(0, fd.decimalDigits);
    840     ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
    841     ASSERT_EQUAL(1, fd.intValue);
    842     ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
    843     ASSERT_EQUAL(FALSE, fd.isNegative);
    844 
    845     // Negative numbers come through
    846     fable.setDecimalNumber("-1.0000000000000000000012", status);
    847     TEST_ASSERT_STATUS(status);
    848     fd = df->getFixedDecimal(fable, status);
    849     TEST_ASSERT_STATUS(status);
    850     ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
    851     ASSERT_EQUAL(12, fd.decimalDigits);
    852     ASSERT_EQUAL(12, fd.decimalDigitsWithoutTrailingZeros);
    853     ASSERT_EQUAL(1, fd.intValue);
    854     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    855     ASSERT_EQUAL(TRUE, fd.isNegative);
    856 
    857     // MinFractionDigits from format larger than from number.
    858     fable.setDecimalNumber("1000000000000000000000.3", status);
    859     TEST_ASSERT_STATUS(status);
    860     fd = df->getFixedDecimal(fable, status);
    861     TEST_ASSERT_STATUS(status);
    862     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
    863     ASSERT_EQUAL(30, fd.decimalDigits);
    864     ASSERT_EQUAL(3, fd.decimalDigitsWithoutTrailingZeros);
    865     ASSERT_EQUAL(100000000000000000LL, fd.intValue);
    866     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    867     ASSERT_EQUAL(FALSE, fd.isNegative);
    868 
    869     fable.setDecimalNumber("1000000000000000050000.3", status);
    870     TEST_ASSERT_STATUS(status);
    871     fd = df->getFixedDecimal(fable, status);
    872     TEST_ASSERT_STATUS(status);
    873     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
    874     ASSERT_EQUAL(30, fd.decimalDigits);
    875     ASSERT_EQUAL(3, fd.decimalDigitsWithoutTrailingZeros);
    876     ASSERT_EQUAL(50000LL, fd.intValue);
    877     ASSERT_EQUAL(FALSE, fd.hasIntegerValue);
    878     ASSERT_EQUAL(FALSE, fd.isNegative);
    879 
    880     // Test some int64_t values that are out of the range of a double
    881     fable.setInt64(4503599627370496LL);
    882     TEST_ASSERT_STATUS(status);
    883     fd = df->getFixedDecimal(fable, status);
    884     TEST_ASSERT_STATUS(status);
    885     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
    886     ASSERT_EQUAL(0, fd.decimalDigits);
    887     ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
    888     ASSERT_EQUAL(4503599627370496LL, fd.intValue);
    889     ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
    890     ASSERT_EQUAL(FALSE, fd.isNegative);
    891 
    892     fable.setInt64(4503599627370497LL);
    893     TEST_ASSERT_STATUS(status);
    894     fd = df->getFixedDecimal(fable, status);
    895     TEST_ASSERT_STATUS(status);
    896     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
    897     ASSERT_EQUAL(0, fd.decimalDigits);
    898     ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
    899     ASSERT_EQUAL(4503599627370497LL, fd.intValue);
    900     ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
    901     ASSERT_EQUAL(FALSE, fd.isNegative);
    902 
    903     fable.setInt64(9223372036854775807LL);
    904     TEST_ASSERT_STATUS(status);
    905     fd = df->getFixedDecimal(fable, status);
    906     TEST_ASSERT_STATUS(status);
    907     ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
    908     ASSERT_EQUAL(0, fd.decimalDigits);
    909     ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
    910     // note: going through DigitList path to FixedDecimal, which is trimming
    911     //       int64_t fields to 18 digits. See ticket Ticket #10374
    912     // ASSERT_EQUAL(223372036854775807LL, fd.intValue);
    913     if (!(fd.intValue == 223372036854775807LL || fd.intValue == 9223372036854775807LL)) {
    914         dataerrln("File %s, Line %d, fd.intValue = %lld", __FILE__, __LINE__, fd.intValue);
    915     }
    916     ASSERT_EQUAL(TRUE, fd.hasIntegerValue);
    917     ASSERT_EQUAL(FALSE, fd.isNegative);
    918 
    919 }
    920 
    921 void IntlTestDecimalFormatAPI::TestBadFastpath() {
    922     UErrorCode status = U_ZERO_ERROR;
    923 
    924     LocalPointer<DecimalFormat> df(new DecimalFormat("###", status), status);
    925     if (U_FAILURE(status)) {
    926         dataerrln("Error creating new DecimalFormat - %s", u_errorName(status));
    927         return;
    928     }
    929 
    930     UnicodeString fmt;
    931     fmt.remove();
    932     assertEquals("Format 1234", "1234", df->format(1234, fmt));
    933     df->setGroupingUsed(FALSE);
    934     fmt.remove();
    935     assertEquals("Format 1234", "1234", df->format(1234, fmt));
    936     df->setGroupingUsed(TRUE);
    937     df->setGroupingSize(3);
    938     fmt.remove();
    939     assertEquals("Format 1234 w/ grouping", "1,234", df->format(1234, fmt));
    940 }
    941 
    942 void IntlTestDecimalFormatAPI::TestRequiredDecimalPoint() {
    943     UErrorCode status = U_ZERO_ERROR;
    944     UnicodeString text("99");
    945     Formattable result1;
    946     UnicodeString pat1("##.0000");
    947     UnicodeString pat2("00.0");
    948 
    949     LocalPointer<DecimalFormat> df(new DecimalFormat(pat1, status), status);
    950     if (U_FAILURE(status)) {
    951         dataerrln("Error creating new DecimalFormat - %s", u_errorName(status));
    952         return;
    953     }
    954 
    955     status = U_ZERO_ERROR;
    956     df->applyPattern(pat1, status);
    957     if(U_FAILURE(status)) {
    958         errln((UnicodeString)"ERROR: applyPattern() failed");
    959     }
    960     df->parse(text, result1, status);
    961     if(U_FAILURE(status)) {
    962         errln((UnicodeString)"ERROR: parse() failed");
    963     }
    964     df->setDecimalPatternMatchRequired(TRUE);
    965     df->parse(text, result1, status);
    966     if(U_SUCCESS(status)) {
    967         errln((UnicodeString)"ERROR: unexpected parse()");
    968     }
    969 
    970 
    971     status = U_ZERO_ERROR;
    972     df->applyPattern(pat2, status);
    973     df->setDecimalPatternMatchRequired(FALSE);
    974     if(U_FAILURE(status)) {
    975         errln((UnicodeString)"ERROR: applyPattern(2) failed");
    976     }
    977     df->parse(text, result1, status);
    978     if(U_FAILURE(status)) {
    979         errln((UnicodeString)"ERROR: parse(2) failed - " + u_errorName(status));
    980     }
    981     df->setDecimalPatternMatchRequired(TRUE);
    982     df->parse(text, result1, status);
    983     if(U_SUCCESS(status)) {
    984         errln((UnicodeString)"ERROR: unexpected parse(2)");
    985     }
    986 }
    987 
    988 #endif /* #if !UCONFIG_NO_FORMATTING */
    989