1 // © 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 */