1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2013, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
9 #include "unicode/utypes.h"
11 #if !UCONFIG_NO_FORMATTING
13 #include "unicode/dcfmtsym.h"
14 #include "unicode/decimfmt.h"
15 #include "unicode/unum.h"
18 void IntlTestDecimalFormatSymbols::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
21 logln("TestSuite DecimalFormatSymbols:");
24 TESTCASE_AUTO(testSymbols);
25 TESTCASE_AUTO(testLastResortData);
30 * Test the API of DecimalFormatSymbols; primarily a simple get/set set.
32 void IntlTestDecimalFormatSymbols::testSymbols(/* char *par */)
34 UErrorCode status = U_ZERO_ERROR;
36 DecimalFormatSymbols fr(Locale::getFrench(), status);
37 if(U_FAILURE(status)) {
38 errcheckln(status, "ERROR: Couldn't create French DecimalFormatSymbols - %s", u_errorName(status));
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));
49 if(en == fr || ! (en != fr) ) {
50 errln("ERROR: English DecimalFormatSymbols equal to French");
53 // just do some VERY basic tests to make sure that get/set work
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");
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");
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");
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");
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");
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");
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");
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");
104 UnicodeString nan(en.getSymbol(DecimalFormatSymbols::kNaNSymbol));
105 fr.setSymbol(DecimalFormatSymbols::kNaNSymbol, nan);
106 UnicodeString nan2(fr.getSymbol(DecimalFormatSymbols::kNaNSymbol));
108 errln("ERROR: get/set NaN failed");
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");
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");
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;
132 UnicodeString frCurrencyPattern = fr.getPatternForCurrencySpacing(
133 (UCurrencySpacing)i, TRUE, status);
134 if(U_FAILURE(status)) {
135 errln("Error: cannot get CurrencyMatch for locale:fr");
137 if (enCurrencyPattern != frCurrencyPattern) {
138 errln("ERROR: get CurrencySpacing failed");
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;
150 UnicodeString frCurrencyPattern = fr.getPatternForCurrencySpacing(
151 (UCurrencySpacing)i, FALSE, status);
152 if(U_FAILURE(status)) {
153 errln("Error: cannot get CurrencyMatch for locale:fr");
155 if (enCurrencyPattern != frCurrencyPattern) {
156 errln("ERROR: get CurrencySpacing failed");
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");
169 status = U_ZERO_ERROR;
170 DecimalFormatSymbols foo(status);
172 DecimalFormatSymbols bar(foo);
176 if(en != fr || foo != bar) {
177 errln("ERROR: Copy Constructor or Assignment failed");
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!");
187 for(i = 0; i < (int)DecimalFormatSymbols::kFormatSymbolCount; ++i) {
188 foo.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)i, UnicodeString((UChar32)(0x10330 + i)));
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) +
195 UnicodeString((UChar32)(0x10330 + i)));
199 DecimalFormatSymbols sym(Locale::getUS(), status);
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");
214 void IntlTestDecimalFormatSymbols::testLastResortData() {
215 IcuTestErrorCode errorCode(*this, "testLastResortData");
216 LocalPointer<DecimalFormatSymbols> lastResort(
217 DecimalFormatSymbols::createWithLastResortData(errorCode));
218 if(errorCode.logIfFailureAndReset("DecimalFormatSymbols::createWithLastResortData() failed")) {
221 DecimalFormatSymbols root(Locale::getRoot(), errorCode);
222 if(errorCode.logDataIfFailureAndReset("DecimalFormatSymbols(root) failed")) {
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");
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));
246 // Also, the CurrencySpacing patterns are empty in the last resort instance,
248 Verify(1234567.25, "#,##0.##", *lastResort, "1,234,567.25");
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));
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);
267 #endif /* #if !UCONFIG_NO_FORMATTING */