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