2dcb24e6227ead373e64e67939175492c2f8728e
[platform/upstream/icu.git] / source / test / intltest / tsdcfmsy.cpp
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 */