Home | History | Annotate | Download | only in intltest
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 *******************************************************************************
      5 * Copyright (C) 2014-2015, International Business Machines Corporation and         *
      6 * others. All Rights Reserved.                                                *
      7 *******************************************************************************
      8 *
      9 * File numfmtspectest.cpp
     10 *
     11 *******************************************************************************
     12 */
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 
     16 #include "intltest.h"
     17 
     18 #if !UCONFIG_NO_FORMATTING
     19 
     20 #include "unicode/localpointer.h"
     21 #include "unicode/decimfmt.h"
     22 #include "unicode/dtfmtsym.h"
     23 #include "uassert.h"
     24 
     25 static const UChar kJPY[] = {0x4A, 0x50, 0x59};
     26 
     27 static void fixNonBreakingSpace(UnicodeString &str) {
     28     for (int32_t i = 0; i < str.length(); ++i) {
     29         if (str[i] == 0xa0) {
     30             str.setCharAt(i, 0x20);
     31         }
     32     }
     33 }
     34 
     35 static NumberFormat *nfWithPattern(const char *pattern) {
     36     UnicodeString upattern(pattern, -1, US_INV);
     37     upattern = upattern.unescape();
     38     UErrorCode status = U_ZERO_ERROR;
     39     DecimalFormat *result = new DecimalFormat(
     40             upattern, new DecimalFormatSymbols("fr", status), status);
     41     if (U_FAILURE(status)) {
     42         return NULL;
     43     }
     44 
     45     return result;
     46 }
     47 
     48 static UnicodeString format(double d, const NumberFormat &fmt) {
     49     UnicodeString result;
     50     fmt.format(d, result);
     51     fixNonBreakingSpace(result);
     52     return result;
     53 }
     54 
     55 class NumberFormatSpecificationTest : public IntlTest {
     56 public:
     57     NumberFormatSpecificationTest() {
     58     }
     59     void TestBasicPatterns();
     60     void TestNfSetters();
     61     void TestRounding();
     62     void TestSignificantDigits();
     63     void TestScientificNotation();
     64     void TestPercent();
     65     void TestPerMilli();
     66     void TestPadding();
     67     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
     68 private:
     69     void assertPatternFr(
     70             const char *expected, double x, const char *pattern, UBool possibleDataError=FALSE);
     71 
     72 };
     73 
     74 void NumberFormatSpecificationTest::runIndexedTest(
     75         int32_t index, UBool exec, const char *&name, char *) {
     76     if (exec) {
     77         logln("TestSuite NumberFormatSpecificationTest: ");
     78     }
     79     TESTCASE_AUTO_BEGIN;
     80     TESTCASE_AUTO(TestBasicPatterns);
     81     TESTCASE_AUTO(TestNfSetters);
     82     TESTCASE_AUTO(TestRounding);
     83     TESTCASE_AUTO(TestSignificantDigits);
     84     TESTCASE_AUTO(TestScientificNotation);
     85     TESTCASE_AUTO(TestPercent);
     86     TESTCASE_AUTO(TestPerMilli);
     87     TESTCASE_AUTO(TestPadding);
     88     TESTCASE_AUTO_END;
     89 }
     90 
     91 void NumberFormatSpecificationTest::TestBasicPatterns() {
     92     assertPatternFr("1\\u202F234,57", 1234.567, "#,##0.##", TRUE);
     93     assertPatternFr("1234,57", 1234.567, "0.##", TRUE);
     94     assertPatternFr("1235", 1234.567, "0", TRUE);
     95     assertPatternFr("1\\u202F234,567", 1234.567, "#,##0.###", TRUE);
     96     assertPatternFr("1234,567", 1234.567, "###0.#####", TRUE);
     97     assertPatternFr("1234,5670", 1234.567, "###0.0000#", TRUE);
     98     assertPatternFr("01234,5670", 1234.567, "00000.0000", TRUE);
     99     assertPatternFr("1\\u202F234,57 \\u20ac", 1234.567, "#,##0.00 \\u00a4", TRUE);
    100 }
    101 
    102 void NumberFormatSpecificationTest::TestNfSetters() {
    103     LocalPointer<NumberFormat> nf(nfWithPattern("#,##0.##"));
    104     if (nf == NULL) {
    105         dataerrln("Error creating NumberFormat");
    106         return;
    107     }
    108     nf->setMaximumIntegerDigits(5);
    109     nf->setMinimumIntegerDigits(4);
    110     assertEquals("", u"34\u202F567,89", format(1234567.89, *nf), TRUE);
    111     assertEquals("", u"0\u202F034,56", format(34.56, *nf), TRUE);
    112 }
    113 
    114 void NumberFormatSpecificationTest::TestRounding() {
    115     assertPatternFr("1,0", 1.25, "0.5", TRUE);
    116     assertPatternFr("2,0", 1.75, "0.5", TRUE);
    117     assertPatternFr("-1,0", -1.25, "0.5", TRUE);
    118     assertPatternFr("-02,0", -1.75, "00.5", TRUE);
    119     assertPatternFr("0", 2.0, "4", TRUE);
    120     assertPatternFr("8", 6.0, "4", TRUE);
    121     assertPatternFr("8", 10.0, "4", TRUE);
    122     assertPatternFr("99,90", 99.0, "2.70", TRUE);
    123     assertPatternFr("273,00", 272.0, "2.73", TRUE);
    124     assertPatternFr("1\\u202F03,60", 104.0, "#,#3.70", TRUE);
    125 }
    126 
    127 void NumberFormatSpecificationTest::TestSignificantDigits() {
    128     assertPatternFr("1230", 1234.0, "@@@", TRUE);
    129     assertPatternFr("1\\u202F234", 1234.0, "@,@@@", TRUE);
    130     assertPatternFr("1\\u202F235\\u202F000", 1234567.0, "@,@@@", TRUE);
    131     assertPatternFr("1\\u202F234\\u202F567", 1234567.0, "@@@@,@@@", TRUE);
    132     assertPatternFr("12\\u202F34\\u202F567,00", 1234567.0, "@@@@,@@,@@@", TRUE);
    133     assertPatternFr("12\\u202F34\\u202F567,0", 1234567.0, "@@@@,@@,@@#", TRUE);
    134     assertPatternFr("12\\u202F34\\u202F567", 1234567.0, "@@@@,@@,@##", TRUE);
    135     assertPatternFr("12\\u202F34\\u202F567", 1234567.001, "@@@@,@@,@##", TRUE);
    136     assertPatternFr("12\\u202F34\\u202F567", 1234567.001, "@@@@,@@,###", TRUE);
    137     assertPatternFr("1\\u202F200", 1234.0, "#,#@@", TRUE);
    138 }
    139 
    140 void NumberFormatSpecificationTest::TestScientificNotation() {
    141     assertPatternFr("1,23E4", 12345.0, "0.00E0", TRUE);
    142     assertPatternFr("123,00E2", 12300.0, "000.00E0", TRUE);
    143     assertPatternFr("123,0E2", 12300.0, "000.0#E0", TRUE);
    144     assertPatternFr("123,0E2", 12300.1, "000.0#E0", TRUE);
    145     assertPatternFr("123,01E2", 12301.0, "000.0#E0", TRUE);
    146     assertPatternFr("123,01E+02", 12301.0, "000.0#E+00", TRUE);
    147     assertPatternFr("12,3E3", 12345.0, "##0.00E0", TRUE);
    148     assertPatternFr("12,300E3", 12300.1, "##0.0000E0", TRUE);
    149     assertPatternFr("12,30E3", 12300.1, "##0.000#E0", TRUE);
    150     assertPatternFr("12,301E3", 12301.0, "##0.000#E0", TRUE);
    151     if (!logKnownIssue("11020")) {
    152         assertPatternFr("1,25E4", 12301.2, "0.05E0");
    153     }
    154     assertPatternFr("170,0E-3", 0.17, "##0.000#E0", TRUE);
    155 
    156 }
    157 
    158 void NumberFormatSpecificationTest::TestPercent() {
    159     assertPatternFr("57,3%", 0.573, "0.0%", TRUE);
    160     assertPatternFr("%57,3", 0.573, "%0.0", TRUE);
    161     assertPatternFr("p%p57,3", 0.573, "p%p0.0", TRUE);
    162     assertPatternFr("p%p0,6", 0.573, "p'%'p0.0", TRUE);
    163     assertPatternFr("%3,260", 0.0326, "%@@@@", TRUE);
    164     assertPatternFr("%1\\u202F540", 15.43, "%#,@@@", TRUE);
    165     assertPatternFr("%1\\u202F656,4", 16.55, "%#,##4.1", TRUE);
    166     assertPatternFr("%16,3E3", 162.55, "%##0.00E0", TRUE);
    167 }
    168 
    169 void NumberFormatSpecificationTest::TestPerMilli() {
    170     assertPatternFr("573,0\\u2030", 0.573, "0.0\\u2030", TRUE);
    171     assertPatternFr("\\u2030573,0", 0.573, "\\u20300.0", TRUE);
    172     assertPatternFr("p\\u2030p573,0", 0.573, "p\\u2030p0.0", TRUE);
    173     assertPatternFr("p\\u2030p0,6", 0.573, "p'\\u2030'p0.0", TRUE);
    174     assertPatternFr("\\u203032,60", 0.0326, "\\u2030@@@@", TRUE);
    175     assertPatternFr("\\u203015\\u202F400", 15.43, "\\u2030#,@@@", TRUE);
    176     assertPatternFr("\\u203016\\u202F551,7", 16.55, "\\u2030#,##4.1", TRUE);
    177     assertPatternFr("\\u2030163E3", 162.55, "\\u2030##0.00E0", TRUE);
    178 }
    179 
    180 void NumberFormatSpecificationTest::TestPadding() {
    181     assertPatternFr("$***1\\u202F234", 1234, "$**####,##0", TRUE);
    182     assertPatternFr("xxx$1\\u202F234", 1234, "*x$####,##0", TRUE);
    183     assertPatternFr("1\\u202F234xxx$", 1234, "####,##0*x$", TRUE);
    184     assertPatternFr("1\\u202F234$xxx", 1234, "####,##0$*x", TRUE);
    185     assertPatternFr("ne1\\u202F234nx", -1234, "####,##0$*x;ne#n", TRUE);
    186     assertPatternFr("n1\\u202F234*xx", -1234, "####,##0$*x;n#'*'", TRUE);
    187     assertPatternFr("yyyy%432,6", 4.33, "*y%4.2######",  TRUE);
    188     if (!logKnownIssue("11025")) {
    189         assertPatternFr("EUR *433,00", 433.0, "\\u00a4\\u00a4 **####0.00");
    190         assertPatternFr("EUR *433,00", 433.0, "\\u00a4\\u00a4 **#######0");
    191     }
    192     {
    193         UnicodeString upattern("\\u00a4\\u00a4 **#######0", -1, US_INV);
    194         upattern = upattern.unescape();
    195         UErrorCode status = U_ZERO_ERROR;
    196         UnicodeString result;
    197         DecimalFormat fmt(
    198                 upattern, new DecimalFormatSymbols("fr", status), status);
    199         if (U_FAILURE(status)) {
    200             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
    201         } else {
    202             fmt.setCurrency(kJPY);
    203             fmt.format(433.22, result);
    204             assertSuccess("", status);
    205             assertEquals("", "JPY ****433", result, TRUE);
    206         }
    207     }
    208     {
    209         UnicodeString upattern(
    210             "\\u00a4\\u00a4 **#######0;\\u00a4\\u00a4 (#)", -1, US_INV);
    211         upattern = upattern.unescape();
    212         UErrorCode status = U_ZERO_ERROR;
    213         UnicodeString result;
    214         DecimalFormat fmt(
    215                 upattern,
    216                 new DecimalFormatSymbols("en_US", status),
    217                 status);
    218         if (U_FAILURE(status)) {
    219             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
    220         } else {
    221             fmt.format(-433.22, result);
    222             assertSuccess("", status);
    223             assertEquals("", "USD (433.22)", result, TRUE);
    224         }
    225     }
    226     const char *paddedSciPattern = "QU**00.#####E0";
    227     assertPatternFr("QU***43,3E-1", 4.33, paddedSciPattern, TRUE);
    228     {
    229         UErrorCode status = U_ZERO_ERROR;
    230         DecimalFormatSymbols *sym = new DecimalFormatSymbols("fr", status);
    231         sym->setSymbol(DecimalFormatSymbols::kExponentialSymbol, "EE");
    232         DecimalFormat fmt(
    233                 paddedSciPattern,
    234                 sym,
    235                 status);
    236         if (U_FAILURE(status)) {
    237             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
    238         } else {
    239             UnicodeString result;
    240             fmt.format(4.33, result);
    241             assertSuccess("", status);
    242             assertEquals("", "QU**43,3EE-1", result, TRUE);
    243         }
    244     }
    245     // padding cannot work as intended with scientific notation.
    246     assertPatternFr("QU**43,32E-1", 4.332, paddedSciPattern, TRUE);
    247 }
    248 
    249 void NumberFormatSpecificationTest::assertPatternFr(
    250         const char *expected,
    251         double x,
    252         const char *pattern,
    253         UBool possibleDataError) {
    254     UnicodeString upattern(pattern, -1, US_INV);
    255     UnicodeString uexpected(expected, -1, US_INV);
    256     upattern = upattern.unescape();
    257     uexpected = uexpected.unescape();
    258     UErrorCode status = U_ZERO_ERROR;
    259     UnicodeString result;
    260     DecimalFormat fmt(
    261             upattern, new DecimalFormatSymbols("fr_FR", status), status);
    262     if (U_FAILURE(status)) {
    263         dataerrln("Error creating DecimalFormatSymbols - %s", u_errorName(status));
    264         return;
    265     }
    266     fmt.format(x, result);
    267     fixNonBreakingSpace(result);
    268     assertSuccess("", status);
    269     assertEquals("", uexpected, result, possibleDataError);
    270 }
    271 
    272 extern IntlTest *createNumberFormatSpecificationTest() {
    273     return new NumberFormatSpecificationTest();
    274 }
    275 
    276 #endif
    277