Home | History | Annotate | Download | only in intltest
      1 // Copyright (C) 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_END;
     27 }
     28 
     29 /**
     30  * Test the API of DecimalFormatSymbols; primarily a simple get/set set.
     31  */
     32 void IntlTestDecimalFormatSymbols::testSymbols(/* char *par */)
     33 {
     34     UErrorCode status = U_ZERO_ERROR;
     35 
     36     DecimalFormatSymbols fr(Locale::getFrench(), status);
     37     if(U_FAILURE(status)) {
     38         errcheckln(status, "ERROR: Couldn't create French DecimalFormatSymbols - %s", u_errorName(status));
     39         return;
     40     }
     41 
     42     status = U_ZERO_ERROR;
     43     DecimalFormatSymbols en(Locale::getEnglish(), status);
     44     if(U_FAILURE(status)) {
     45         errcheckln(status, "ERROR: Couldn't create English DecimalFormatSymbols - %s", u_errorName(status));
     46         return;
     47     }
     48 
     49     if(en == fr || ! (en != fr) ) {
     50         errln("ERROR: English DecimalFormatSymbols equal to French");
     51     }
     52 
     53     // just do some VERY basic tests to make sure that get/set work
     54 
     55     UnicodeString zero = en.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol);
     56     fr.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero);
     57     if(fr.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol) != en.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) {
     58         errln("ERROR: get/set ZeroDigit failed");
     59     }
     60 
     61     UnicodeString group = en.getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
     62     fr.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, group);
     63     if(fr.getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol) != en.getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) {
     64         errln("ERROR: get/set GroupingSeparator failed");
     65     }
     66 
     67     UnicodeString decimal = en.getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
     68     fr.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, decimal);
     69     if(fr.getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol) != en.getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) {
     70         errln("ERROR: get/set DecimalSeparator failed");
     71     }
     72 
     73     UnicodeString perMill = en.getSymbol(DecimalFormatSymbols::kPerMillSymbol);
     74     fr.setSymbol(DecimalFormatSymbols::kPerMillSymbol, perMill);
     75     if(fr.getSymbol(DecimalFormatSymbols::kPerMillSymbol) != en.getSymbol(DecimalFormatSymbols::kPerMillSymbol)) {
     76         errln("ERROR: get/set PerMill failed");
     77     }
     78 
     79     UnicodeString percent = en.getSymbol(DecimalFormatSymbols::kPercentSymbol);
     80     fr.setSymbol(DecimalFormatSymbols::kPercentSymbol, percent);
     81     if(fr.getSymbol(DecimalFormatSymbols::kPercentSymbol) != en.getSymbol(DecimalFormatSymbols::kPercentSymbol)) {
     82         errln("ERROR: get/set Percent failed");
     83     }
     84 
     85     UnicodeString digit(en.getSymbol(DecimalFormatSymbols::kDigitSymbol));
     86     fr.setSymbol(DecimalFormatSymbols::kDigitSymbol, digit);
     87     if(fr.getSymbol(DecimalFormatSymbols::kDigitSymbol) != en.getSymbol(DecimalFormatSymbols::kDigitSymbol)) {
     88         errln("ERROR: get/set Percent failed");
     89     }
     90 
     91     UnicodeString patternSeparator = en.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
     92     fr.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, patternSeparator);
     93     if(fr.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol) != en.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) {
     94         errln("ERROR: get/set PatternSeparator failed");
     95     }
     96 
     97     UnicodeString infinity(en.getSymbol(DecimalFormatSymbols::kInfinitySymbol));
     98     fr.setSymbol(DecimalFormatSymbols::kInfinitySymbol, infinity);
     99     UnicodeString infinity2(fr.getSymbol(DecimalFormatSymbols::kInfinitySymbol));
    100     if(infinity != infinity2) {
    101         errln("ERROR: get/set Infinity failed");
    102     }
    103 
    104     UnicodeString nan(en.getSymbol(DecimalFormatSymbols::kNaNSymbol));
    105     fr.setSymbol(DecimalFormatSymbols::kNaNSymbol, nan);
    106     UnicodeString nan2(fr.getSymbol(DecimalFormatSymbols::kNaNSymbol));
    107     if(nan != nan2) {
    108         errln("ERROR: get/set NaN failed");
    109     }
    110 
    111     UnicodeString minusSign = en.getSymbol(DecimalFormatSymbols::kMinusSignSymbol);
    112     fr.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, minusSign);
    113     if(fr.getSymbol(DecimalFormatSymbols::kMinusSignSymbol) != en.getSymbol(DecimalFormatSymbols::kMinusSignSymbol)) {
    114         errln("ERROR: get/set MinusSign failed");
    115     }
    116 
    117     UnicodeString exponential(en.getSymbol(DecimalFormatSymbols::kExponentialSymbol));
    118     fr.setSymbol(DecimalFormatSymbols::kExponentialSymbol, exponential);
    119     if(fr.getSymbol(DecimalFormatSymbols::kExponentialSymbol) != en.getSymbol(DecimalFormatSymbols::kExponentialSymbol)) {
    120         errln("ERROR: get/set Exponential failed");
    121     }
    122 
    123     // Test get currency spacing before the currency.
    124     status = U_ZERO_ERROR;
    125     for (int32_t i = 0; i < (int32_t)UNUM_CURRENCY_SPACING_COUNT; i++) {
    126         UnicodeString enCurrencyPattern = en.getPatternForCurrencySpacing(
    127              (UCurrencySpacing)i, TRUE, status);
    128         if(U_FAILURE(status)) {
    129             errln("Error: cannot get CurrencyMatch for locale:en");
    130             status = U_ZERO_ERROR;
    131         }
    132         UnicodeString frCurrencyPattern = fr.getPatternForCurrencySpacing(
    133              (UCurrencySpacing)i, TRUE, status);
    134         if(U_FAILURE(status)) {
    135             errln("Error: cannot get CurrencyMatch for locale:fr");
    136         }
    137         if (enCurrencyPattern != frCurrencyPattern) {
    138            errln("ERROR: get CurrencySpacing failed");
    139         }
    140     }
    141     // Test get currencySpacing after the currency.
    142     status = U_ZERO_ERROR;
    143     for (int32_t i = 0; i < UNUM_CURRENCY_SPACING_COUNT; i++) {
    144         UnicodeString enCurrencyPattern = en.getPatternForCurrencySpacing(
    145             (UCurrencySpacing)i, FALSE, status);
    146         if(U_FAILURE(status)) {
    147             errln("Error: cannot get CurrencyMatch for locale:en");
    148             status = U_ZERO_ERROR;
    149         }
    150         UnicodeString frCurrencyPattern = fr.getPatternForCurrencySpacing(
    151              (UCurrencySpacing)i, FALSE, status);
    152         if(U_FAILURE(status)) {
    153             errln("Error: cannot get CurrencyMatch for locale:fr");
    154         }
    155         if (enCurrencyPattern != frCurrencyPattern) {
    156             errln("ERROR: get CurrencySpacing failed");
    157         }
    158     }
    159     // Test set curerncySpacing APIs
    160     status = U_ZERO_ERROR;
    161     UnicodeString dash = UnicodeString("-");
    162     en.setPatternForCurrencySpacing(UNUM_CURRENCY_INSERT, TRUE, dash);
    163     UnicodeString enCurrencyInsert = en.getPatternForCurrencySpacing(
    164         UNUM_CURRENCY_INSERT, TRUE, status);
    165     if (dash != enCurrencyInsert) {
    166         errln("Error: Failed to setCurrencyInsert for locale:en");
    167     }
    168 
    169     status = U_ZERO_ERROR;
    170     DecimalFormatSymbols foo(status);
    171 
    172     DecimalFormatSymbols bar(foo);
    173 
    174     en = fr;
    175 
    176     if(en != fr || foo != bar) {
    177         errln("ERROR: Copy Constructor or Assignment failed");
    178     }
    179 
    180     // test get/setSymbol()
    181     if((int) UNUM_FORMAT_SYMBOL_COUNT != (int) DecimalFormatSymbols::kFormatSymbolCount) {
    182         errln("unum.h and decimfmt.h have inconsistent numbers of format symbols!");
    183         return;
    184     }
    185 
    186     int i;
    187     for(i = 0; i < (int)DecimalFormatSymbols::kFormatSymbolCount; ++i) {
    188         foo.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)i, UnicodeString((UChar32)(0x10330 + i)));
    189     }
    190     for(i = 0; i < (int)DecimalFormatSymbols::kFormatSymbolCount; ++i) {
    191         if(foo.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)i) != UnicodeString((UChar32)(0x10330 + i))) {
    192             errln("get/setSymbol did not roundtrip, got " +
    193                   foo.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)i) +
    194                   ", expected " +
    195                   UnicodeString((UChar32)(0x10330 + i)));
    196         }
    197     }
    198 
    199     DecimalFormatSymbols sym(Locale::getUS(), status);
    200 
    201     UnicodeString customDecSeperator("S");
    202     Verify(34.5, (UnicodeString)"00.00", sym, (UnicodeString)"34.50");
    203     sym.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, customDecSeperator);
    204     Verify(34.5, (UnicodeString)"00.00", sym, (UnicodeString)"34S50");
    205     sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UnicodeString)"P");
    206     Verify(34.5, (UnicodeString)"00 %", sym, (UnicodeString)"3450 P");
    207     sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, (UnicodeString)"D");
    208     Verify(34.5, CharsToUnicodeString("\\u00a4##.##"), sym, (UnicodeString)"D34.5");
    209     sym.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, (UnicodeString)"|");
    210     Verify(3456.5, (UnicodeString)"0,000.##", sym, (UnicodeString)"3|456S5");
    211 
    212 }
    213 
    214 void IntlTestDecimalFormatSymbols::testLastResortData() {
    215     IcuTestErrorCode errorCode(*this, "testLastResortData");
    216     LocalPointer<DecimalFormatSymbols> lastResort(
    217         DecimalFormatSymbols::createWithLastResortData(errorCode));
    218     if(errorCode.logIfFailureAndReset("DecimalFormatSymbols::createWithLastResortData() failed")) {
    219         return;
    220     }
    221     DecimalFormatSymbols root(Locale::getRoot(), errorCode);
    222     if(errorCode.logDataIfFailureAndReset("DecimalFormatSymbols(root) failed")) {
    223         return;
    224     }
    225     // Note: It is not necessary that the last resort data matches the root locale,
    226     // but it seems weird if most symbols did not match.
    227     // Also, one purpose for calling operator==() is to find uninitialized memory in a debug build.
    228     if(*lastResort == root) {
    229         errln("DecimalFormatSymbols last resort data unexpectedly matches root");
    230     }
    231     // Here we adjust for expected differences.
    232     assertEquals("last-resort grouping separator",
    233                  "", lastResort->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
    234     lastResort->setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, ",");
    235     assertEquals("last-resort monetary grouping separator",
    236                  "", lastResort->getSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol));
    237     lastResort->setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, ",");
    238     assertEquals("last-resort NaN",
    239                  UnicodeString((UChar)0xfffd), lastResort->getSymbol(DecimalFormatSymbols::kNaNSymbol));
    240     lastResort->setSymbol(DecimalFormatSymbols::kNaNSymbol, "NaN");
    241     // Check that now all of the symbols match root.
    242     for(int32_t i = 0; i < DecimalFormatSymbols::kFormatSymbolCount; ++i) {
    243         DecimalFormatSymbols::ENumberFormatSymbol e = (DecimalFormatSymbols::ENumberFormatSymbol)i;
    244         assertEquals("last-resort symbol vs. root", root.getSymbol(e), lastResort->getSymbol(e));
    245     }
    246     // Also, the CurrencySpacing patterns are empty in the last resort instance,
    247     // but not in root.
    248     Verify(1234567.25, "#,##0.##", *lastResort, "1,234,567.25");
    249 }
    250 
    251 void IntlTestDecimalFormatSymbols::Verify(double value, const UnicodeString& pattern,
    252                                           const DecimalFormatSymbols &sym, const UnicodeString& expected){
    253     UErrorCode status = U_ZERO_ERROR;
    254     DecimalFormat df(pattern, sym, status);
    255     if(U_FAILURE(status)){
    256         errln("ERROR: construction of decimal format failed - %s", u_errorName(status));
    257     }
    258     UnicodeString buffer;
    259     FieldPosition pos(FieldPosition::DONT_CARE);
    260     buffer = df.format(value, buffer, pos);
    261     if(buffer != expected){
    262         errln((UnicodeString)"ERROR: format() returns wrong result\n Expected " +
    263             expected + ", Got " + buffer);
    264     }
    265 }
    266 
    267 #endif /* #if !UCONFIG_NO_FORMATTING */
    268