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  * COPYRIGHT:
      5  * Copyright (c) 1997-2013, International Business Machines Corporation and
      6  * others. All Rights Reserved.
      7  ********************************************************************/
      8 
      9 #include "unicode/utypes.h"
     10 
     11 #if !UCONFIG_NO_FORMATTING
     12 
     13 #include "unicode/dcfmtsym.h"
     14 #include "unicode/decimfmt.h"
     15 #include "unicode/unum.h"
     16 #include "tsdcfmsy.h"
     17 
     18 void IntlTestDecimalFormatSymbols::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
     19 {
     20     if (exec) {
     21         logln("TestSuite DecimalFormatSymbols:");
     22     }
     23     TESTCASE_AUTO_BEGIN;
     24     TESTCASE_AUTO(testSymbols);
     25     TESTCASE_AUTO(testLastResortData);
     26     TESTCASE_AUTO(testNumberingSystem);
     27     TESTCASE_AUTO_END;
     28 }
     29 
     30 /**
     31  * Test the API of DecimalFormatSymbols; primarily a simple get/set set.
     32  */
     33 void IntlTestDecimalFormatSymbols::testSymbols(/* char *par */)
     34 {
     35     UErrorCode status = U_ZERO_ERROR;
     36 
     37     DecimalFormatSymbols fr(Locale::getFrench(), status);
     38     if(U_FAILURE(status)) {
     39         errcheckln(status, "ERROR: Couldn't create French DecimalFormatSymbols - %s", u_errorName(status));
     40         return;
     41     }
     42 
     43     status = U_ZERO_ERROR;
     44     DecimalFormatSymbols en(Locale::getEnglish(), status);
     45     if(U_FAILURE(status)) {
     46         errcheckln(status, "ERROR: Couldn't create English DecimalFormatSymbols - %s", u_errorName(status));
     47         return;
     48     }
     49 
     50     if(en == fr || ! (en != fr) ) {
     51         errln("ERROR: English DecimalFormatSymbols equal to French");
     52     }
     53 
     54     // just do some VERY basic tests to make sure that get/set work
     55 
     56     UnicodeString zero = en.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol);
     57     fr.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero);
     58     if(fr.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol) != en.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) {
     59         errln("ERROR: get/set ZeroDigit failed");
     60     }
     61 
     62     UnicodeString group = en.getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
     63     fr.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, group);
     64     if(fr.getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol) != en.getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) {
     65         errln("ERROR: get/set GroupingSeparator failed");
     66     }
     67 
     68     UnicodeString decimal = en.getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
     69     fr.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, decimal);
     70     if(fr.getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol) != en.getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) {
     71         errln("ERROR: get/set DecimalSeparator failed");
     72     }
     73 
     74     UnicodeString perMill = en.getSymbol(DecimalFormatSymbols::kPerMillSymbol);
     75     fr.setSymbol(DecimalFormatSymbols::kPerMillSymbol, perMill);
     76     if(fr.getSymbol(DecimalFormatSymbols::kPerMillSymbol) != en.getSymbol(DecimalFormatSymbols::kPerMillSymbol)) {
     77         errln("ERROR: get/set PerMill failed");
     78     }
     79 
     80     UnicodeString percent = en.getSymbol(DecimalFormatSymbols::kPercentSymbol);
     81     fr.setSymbol(DecimalFormatSymbols::kPercentSymbol, percent);
     82     if(fr.getSymbol(DecimalFormatSymbols::kPercentSymbol) != en.getSymbol(DecimalFormatSymbols::kPercentSymbol)) {
     83         errln("ERROR: get/set Percent failed");
     84     }
     85 
     86     UnicodeString digit(en.getSymbol(DecimalFormatSymbols::kDigitSymbol));
     87     fr.setSymbol(DecimalFormatSymbols::kDigitSymbol, digit);
     88     if(fr.getSymbol(DecimalFormatSymbols::kDigitSymbol) != en.getSymbol(DecimalFormatSymbols::kDigitSymbol)) {
     89         errln("ERROR: get/set Percent failed");
     90     }
     91 
     92     UnicodeString patternSeparator = en.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
     93     fr.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, patternSeparator);
     94     if(fr.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol) != en.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) {
     95         errln("ERROR: get/set PatternSeparator failed");
     96     }
     97 
     98     UnicodeString infinity(en.getSymbol(DecimalFormatSymbols::kInfinitySymbol));
     99     fr.setSymbol(DecimalFormatSymbols::kInfinitySymbol, infinity);
    100     UnicodeString infinity2(fr.getSymbol(DecimalFormatSymbols::kInfinitySymbol));
    101     if(infinity != infinity2) {
    102         errln("ERROR: get/set Infinity failed");
    103     }
    104 
    105     UnicodeString nan(en.getSymbol(DecimalFormatSymbols::kNaNSymbol));
    106     fr.setSymbol(DecimalFormatSymbols::kNaNSymbol, nan);
    107     UnicodeString nan2(fr.getSymbol(DecimalFormatSymbols::kNaNSymbol));
    108     if(nan != nan2) {
    109         errln("ERROR: get/set NaN failed");
    110     }
    111 
    112     UnicodeString minusSign = en.getSymbol(DecimalFormatSymbols::kMinusSignSymbol);
    113     fr.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, minusSign);
    114     if(fr.getSymbol(DecimalFormatSymbols::kMinusSignSymbol) != en.getSymbol(DecimalFormatSymbols::kMinusSignSymbol)) {
    115         errln("ERROR: get/set MinusSign failed");
    116     }
    117 
    118     UnicodeString exponential(en.getSymbol(DecimalFormatSymbols::kExponentialSymbol));
    119     fr.setSymbol(DecimalFormatSymbols::kExponentialSymbol, exponential);
    120     if(fr.getSymbol(DecimalFormatSymbols::kExponentialSymbol) != en.getSymbol(DecimalFormatSymbols::kExponentialSymbol)) {
    121         errln("ERROR: get/set Exponential failed");
    122     }
    123 
    124     // Test get currency spacing before the currency.
    125     status = U_ZERO_ERROR;
    126     for (int32_t i = 0; i < (int32_t)UNUM_CURRENCY_SPACING_COUNT; i++) {
    127         UnicodeString enCurrencyPattern = en.getPatternForCurrencySpacing(
    128              (UCurrencySpacing)i, TRUE, status);
    129         if(U_FAILURE(status)) {
    130             errln("Error: cannot get CurrencyMatch for locale:en");
    131             status = U_ZERO_ERROR;
    132         }
    133         UnicodeString frCurrencyPattern = fr.getPatternForCurrencySpacing(
    134              (UCurrencySpacing)i, TRUE, status);
    135         if(U_FAILURE(status)) {
    136             errln("Error: cannot get CurrencyMatch for locale:fr");
    137         }
    138         if (enCurrencyPattern != frCurrencyPattern) {
    139            errln("ERROR: get CurrencySpacing failed");
    140         }
    141     }
    142     // Test get currencySpacing after the currency.
    143     status = U_ZERO_ERROR;
    144     for (int32_t i = 0; i < UNUM_CURRENCY_SPACING_COUNT; i++) {
    145         UnicodeString enCurrencyPattern = en.getPatternForCurrencySpacing(
    146             (UCurrencySpacing)i, FALSE, status);
    147         if(U_FAILURE(status)) {
    148             errln("Error: cannot get CurrencyMatch for locale:en");
    149             status = U_ZERO_ERROR;
    150         }
    151         UnicodeString frCurrencyPattern = fr.getPatternForCurrencySpacing(
    152              (UCurrencySpacing)i, FALSE, status);
    153         if(U_FAILURE(status)) {
    154             errln("Error: cannot get CurrencyMatch for locale:fr");
    155         }
    156         if (enCurrencyPattern != frCurrencyPattern) {
    157             errln("ERROR: get CurrencySpacing failed");
    158         }
    159     }
    160     // Test set curerncySpacing APIs
    161     status = U_ZERO_ERROR;
    162     UnicodeString dash = UnicodeString("-");
    163     en.setPatternForCurrencySpacing(UNUM_CURRENCY_INSERT, TRUE, dash);
    164     UnicodeString enCurrencyInsert = en.getPatternForCurrencySpacing(
    165         UNUM_CURRENCY_INSERT, TRUE, status);
    166     if (dash != enCurrencyInsert) {
    167         errln("Error: Failed to setCurrencyInsert for locale:en");
    168     }
    169 
    170     status = U_ZERO_ERROR;
    171     DecimalFormatSymbols foo(status);
    172 
    173     DecimalFormatSymbols bar(foo);
    174 
    175     en = fr;
    176 
    177     if(en != fr || foo != bar) {
    178         errln("ERROR: Copy Constructor or Assignment failed");
    179     }
    180 
    181     // test get/setSymbol()
    182     if((int) UNUM_FORMAT_SYMBOL_COUNT != (int) DecimalFormatSymbols::kFormatSymbolCount) {
    183         errln("unum.h and decimfmt.h have inconsistent numbers of format symbols!");
    184         return;
    185     }
    186 
    187     int i;
    188     for(i = 0; i < (int)DecimalFormatSymbols::kFormatSymbolCount; ++i) {
    189         foo.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)i, UnicodeString((UChar32)(0x10330 + i)));
    190     }
    191     for(i = 0; i < (int)DecimalFormatSymbols::kFormatSymbolCount; ++i) {
    192         if(foo.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)i) != UnicodeString((UChar32)(0x10330 + i))) {
    193             errln("get/setSymbol did not roundtrip, got " +
    194                   foo.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)i) +
    195                   ", expected " +
    196                   UnicodeString((UChar32)(0x10330 + i)));
    197         }
    198     }
    199 
    200     DecimalFormatSymbols sym(Locale::getUS(), status);
    201 
    202     UnicodeString customDecSeperator("S");
    203     Verify(34.5, (UnicodeString)"00.00", sym, (UnicodeString)"34.50");
    204     sym.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, customDecSeperator);
    205     Verify(34.5, (UnicodeString)"00.00", sym, (UnicodeString)"34S50");
    206     sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UnicodeString)"P");
    207     Verify(34.5, (UnicodeString)"00 %", sym, (UnicodeString)"3450 P");
    208     sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, (UnicodeString)"D");
    209     Verify(34.5, CharsToUnicodeString("\\u00a4##.##"), sym, (UnicodeString)"D34.5");
    210     sym.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, (UnicodeString)"|");
    211     Verify(3456.5, (UnicodeString)"0,000.##", sym, (UnicodeString)"3|456S5");
    212 
    213 }
    214 
    215 void IntlTestDecimalFormatSymbols::testLastResortData() {
    216     IcuTestErrorCode errorCode(*this, "testLastResortData");
    217     LocalPointer<DecimalFormatSymbols> lastResort(
    218         DecimalFormatSymbols::createWithLastResortData(errorCode));
    219     if(errorCode.logIfFailureAndReset("DecimalFormatSymbols::createWithLastResortData() failed")) {
    220         return;
    221     }
    222     DecimalFormatSymbols root(Locale::getRoot(), errorCode);
    223     if(errorCode.logDataIfFailureAndReset("DecimalFormatSymbols(root) failed")) {
    224         return;
    225     }
    226     // Note: It is not necessary that the last resort data matches the root locale,
    227     // but it seems weird if most symbols did not match.
    228     // Also, one purpose for calling operator==() is to find uninitialized memory in a debug build.
    229     if(*lastResort == root) {
    230         errln("DecimalFormatSymbols last resort data unexpectedly matches root");
    231     }
    232     // Here we adjust for expected differences.
    233     assertEquals("last-resort grouping separator",
    234                  "", lastResort->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
    235     lastResort->setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, ",");
    236     assertEquals("last-resort monetary grouping separator",
    237                  "", lastResort->getSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol));
    238     lastResort->setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, ",");
    239     assertEquals("last-resort NaN",
    240                  UnicodeString((UChar)0xfffd), lastResort->getSymbol(DecimalFormatSymbols::kNaNSymbol));
    241     lastResort->setSymbol(DecimalFormatSymbols::kNaNSymbol, "NaN");
    242     // Check that now all of the symbols match root.
    243     for(int32_t i = 0; i < DecimalFormatSymbols::kFormatSymbolCount; ++i) {
    244         DecimalFormatSymbols::ENumberFormatSymbol e = (DecimalFormatSymbols::ENumberFormatSymbol)i;
    245         assertEquals("last-resort symbol vs. root", root.getSymbol(e), lastResort->getSymbol(e));
    246     }
    247     // Also, the CurrencySpacing patterns are empty in the last resort instance,
    248     // but not in root.
    249     Verify(1234567.25, "#,##0.##", *lastResort, "1,234,567.25");
    250 }
    251 
    252 void IntlTestDecimalFormatSymbols::testNumberingSystem() {
    253     IcuTestErrorCode errorCode(*this, "testNumberingSystem");
    254     struct testcase {
    255         const char* locid;
    256         const char* nsname;
    257         const char16_t* expected1; // Expected number format string
    258         const char16_t* expected2; // Expected pattern separator
    259     };
    260     static const testcase cases[9] = {
    261             {"en", "latn", u"1,234.56", u";"},
    262             {"en", "arab", u"", u""},
    263             {"en", "mathsanb", u",.", u";"},
    264             {"en", "mymr", u",.", u";"},
    265             {"my", "latn", u"1,234.56", u";"},
    266             {"my", "arab", u"", u""},
    267             {"my", "mathsanb", u",.", u";"},
    268             {"my", "mymr", u",.", u""},
    269             {"en@numbers=thai", "mymr", u",.", u";"}, // conflicting numbering system
    270     };
    271 
    272     for (int i=0; i<8; i++) {
    273         testcase cas = cases[i];
    274         Locale loc(cas.locid);
    275         LocalPointer<NumberingSystem> ns(NumberingSystem::createInstanceByName(cas.nsname, errorCode));
    276         if (errorCode.logDataIfFailureAndReset("NumberingSystem failed")) {
    277             return;
    278         }
    279         UnicodeString expected1(cas.expected1);
    280         UnicodeString expected2(cas.expected2);
    281         DecimalFormatSymbols dfs(loc, *ns, errorCode);
    282         if (errorCode.logDataIfFailureAndReset("DecimalFormatSymbols failed")) {
    283             return;
    284         }
    285         Verify(1234.56, "#,##0.##", dfs, expected1);
    286         // The pattern separator is something that differs by numbering system in my@numbers=mymr.
    287         UnicodeString actual2 = dfs.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
    288         if (expected2 != actual2) {
    289             errln((UnicodeString)"ERROR: DecimalFormatSymbols returned pattern separator " + actual2
    290                 + " but we expected " + expected2);
    291         }
    292     }
    293 }
    294 
    295 void IntlTestDecimalFormatSymbols::Verify(double value, const UnicodeString& pattern,
    296                                           const DecimalFormatSymbols &sym, const UnicodeString& expected){
    297     UErrorCode status = U_ZERO_ERROR;
    298     DecimalFormat df(pattern, sym, status);
    299     if(U_FAILURE(status)){
    300         errln("ERROR: construction of decimal format failed - %s", u_errorName(status));
    301     }
    302     UnicodeString buffer;
    303     FieldPosition pos(FieldPosition::DONT_CARE);
    304     buffer = df.format(value, buffer, pos);
    305     if(buffer != expected){
    306         errln((UnicodeString)"ERROR: format() returns wrong result\n Expected " +
    307             expected + ", Got " + buffer);
    308     }
    309 }
    310 
    311 #endif /* #if !UCONFIG_NO_FORMATTING */
    312