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
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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 */
testSymbols()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
testLastResortData()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
Verify(double value,const UnicodeString & pattern,const DecimalFormatSymbols & sym,const UnicodeString & expected)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