• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 * Copyright (C) 2014-2015, International Business Machines Corporation and         *
4 * others. All Rights Reserved.                                                *
5 *******************************************************************************
6 *
7 * File numfmtspectest.cpp
8 *
9 *******************************************************************************
10 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 #include "intltest.h"
15 
16 #if !UCONFIG_NO_FORMATTING
17 
18 #include "unicode/localpointer.h"
19 #include "unicode/decimfmt.h"
20 #include "unicode/dtfmtsym.h"
21 #include "uassert.h"
22 
23 static const UChar kJPY[] = {0x4A, 0x50, 0x59};
24 
fixNonBreakingSpace(UnicodeString & str)25 static void fixNonBreakingSpace(UnicodeString &str) {
26     for (int32_t i = 0; i < str.length(); ++i) {
27         if (str[i] == 0xa0) {
28             str.setCharAt(i, 0x20);
29         }
30     }
31 }
32 
nfWithPattern(const char * pattern)33 static NumberFormat *nfWithPattern(const char *pattern) {
34     UnicodeString upattern(pattern, -1, US_INV);
35     upattern = upattern.unescape();
36     UErrorCode status = U_ZERO_ERROR;
37     DecimalFormat *result = new DecimalFormat(
38             upattern, new DecimalFormatSymbols("fr", status), status);
39     if (U_FAILURE(status)) {
40         return NULL;
41     }
42 
43     return result;
44 }
45 
format(double d,const NumberFormat & fmt)46 static UnicodeString format(double d, const NumberFormat &fmt) {
47     UnicodeString result;
48     fmt.format(d, result);
49     fixNonBreakingSpace(result);
50     return result;
51 }
52 
53 class NumberFormatSpecificationTest : public IntlTest {
54 public:
NumberFormatSpecificationTest()55     NumberFormatSpecificationTest() {
56     }
57     void TestBasicPatterns();
58     void TestNfSetters();
59     void TestRounding();
60     void TestSignificantDigits();
61     void TestScientificNotation();
62     void TestPercent();
63     void TestPerMilli();
64     void TestPadding();
65     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
66 private:
67     void assertPatternFr(
68             const char *expected, double x, const char *pattern, UBool possibleDataError=FALSE);
69 
70 };
71 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)72 void NumberFormatSpecificationTest::runIndexedTest(
73         int32_t index, UBool exec, const char *&name, char *) {
74     if (exec) {
75         logln("TestSuite NumberFormatSpecificationTest: ");
76     }
77     TESTCASE_AUTO_BEGIN;
78     TESTCASE_AUTO(TestBasicPatterns);
79     TESTCASE_AUTO(TestNfSetters);
80     TESTCASE_AUTO(TestRounding);
81     TESTCASE_AUTO(TestSignificantDigits);
82     TESTCASE_AUTO(TestScientificNotation);
83     TESTCASE_AUTO(TestPercent);
84     TESTCASE_AUTO(TestPerMilli);
85     TESTCASE_AUTO(TestPadding);
86     TESTCASE_AUTO_END;
87 }
88 
TestBasicPatterns()89 void NumberFormatSpecificationTest::TestBasicPatterns() {
90     assertPatternFr("1 234,57", 1234.567, "#,##0.##", TRUE);
91     assertPatternFr("1234,57", 1234.567, "0.##", TRUE);
92     assertPatternFr("1235", 1234.567, "0", TRUE);
93     assertPatternFr("1 234,567", 1234.567, "#,##0.###", TRUE);
94     assertPatternFr("1234,567", 1234.567, "###0.#####", TRUE);
95     assertPatternFr("1234,5670", 1234.567, "###0.0000#", TRUE);
96     assertPatternFr("01234,5670", 1234.567, "00000.0000", TRUE);
97     assertPatternFr("1 234,57 \\u20ac", 1234.567, "#,##0.00 \\u00a4", TRUE);
98 }
99 
TestNfSetters()100 void NumberFormatSpecificationTest::TestNfSetters() {
101     LocalPointer<NumberFormat> nf(nfWithPattern("#,##0.##"));
102     if (nf == NULL) {
103         dataerrln("Error creating NumberFormat");
104         return;
105     }
106     nf->setMaximumIntegerDigits(5);
107     nf->setMinimumIntegerDigits(4);
108     assertEquals("", "34 567,89", format(1234567.89, *nf), TRUE);
109     assertEquals("", "0 034,56", format(34.56, *nf), TRUE);
110 }
111 
TestRounding()112 void NumberFormatSpecificationTest::TestRounding() {
113     assertPatternFr("1,0", 1.25, "0.5", TRUE);
114     assertPatternFr("2,0", 1.75, "0.5", TRUE);
115     assertPatternFr("-1,0", -1.25, "0.5", TRUE);
116     assertPatternFr("-02,0", -1.75, "00.5", TRUE);
117     assertPatternFr("0", 2.0, "4", TRUE);
118     assertPatternFr("8", 6.0, "4", TRUE);
119     assertPatternFr("8", 10.0, "4", TRUE);
120     assertPatternFr("99,90", 99.0, "2.70", TRUE);
121     assertPatternFr("273,00", 272.0, "2.73", TRUE);
122     assertPatternFr("1 03,60", 104.0, "#,#3.70", TRUE);
123 }
124 
TestSignificantDigits()125 void NumberFormatSpecificationTest::TestSignificantDigits() {
126     assertPatternFr("1230", 1234.0, "@@@", TRUE);
127     assertPatternFr("1 234", 1234.0, "@,@@@", TRUE);
128     assertPatternFr("1 235 000", 1234567.0, "@,@@@", TRUE);
129     assertPatternFr("1 234 567", 1234567.0, "@@@@,@@@", TRUE);
130     assertPatternFr("12 34 567,00", 1234567.0, "@@@@,@@,@@@", TRUE);
131     assertPatternFr("12 34 567,0", 1234567.0, "@@@@,@@,@@#", TRUE);
132     assertPatternFr("12 34 567", 1234567.0, "@@@@,@@,@##", TRUE);
133     assertPatternFr("12 34 567", 1234567.001, "@@@@,@@,@##", TRUE);
134     assertPatternFr("12 34 567", 1234567.001, "@@@@,@@,###", TRUE);
135     assertPatternFr("1 200", 1234.0, "#,#@@", TRUE);
136 }
137 
TestScientificNotation()138 void NumberFormatSpecificationTest::TestScientificNotation() {
139     assertPatternFr("1,23E4", 12345.0, "0.00E0", TRUE);
140     assertPatternFr("123,00E2", 12300.0, "000.00E0", TRUE);
141     assertPatternFr("123,0E2", 12300.0, "000.0#E0", TRUE);
142     assertPatternFr("123,0E2", 12300.1, "000.0#E0", TRUE);
143     assertPatternFr("123,01E2", 12301.0, "000.0#E0", TRUE);
144     assertPatternFr("123,01E+02", 12301.0, "000.0#E+00", TRUE);
145     assertPatternFr("12,3E3", 12345.0, "##0.00E0", TRUE);
146     assertPatternFr("12,300E3", 12300.1, "##0.0000E0", TRUE);
147     assertPatternFr("12,30E3", 12300.1, "##0.000#E0", TRUE);
148     assertPatternFr("12,301E3", 12301.0, "##0.000#E0", TRUE);
149     if (!logKnownIssue("11020")) {
150         assertPatternFr("1,25E4", 12301.2, "0.05E0");
151     }
152     assertPatternFr("170,0E-3", 0.17, "##0.000#E0", TRUE);
153 
154 }
155 
TestPercent()156 void NumberFormatSpecificationTest::TestPercent() {
157     assertPatternFr("57,3%", 0.573, "0.0%", TRUE);
158     assertPatternFr("%57,3", 0.573, "%0.0", TRUE);
159     assertPatternFr("p%p57,3", 0.573, "p%p0.0", TRUE);
160     assertPatternFr("p%p0,6", 0.573, "p'%'p0.0", TRUE);
161     assertPatternFr("%3,260", 0.0326, "%@@@@", TRUE);
162     assertPatternFr("%1 540", 15.43, "%#,@@@", TRUE);
163     assertPatternFr("%1 656,4", 16.55, "%#,##4.1", TRUE);
164     assertPatternFr("%16,3E3", 162.55, "%##0.00E0", TRUE);
165 }
166 
TestPerMilli()167 void NumberFormatSpecificationTest::TestPerMilli() {
168     assertPatternFr("573,0\\u2030", 0.573, "0.0\\u2030", TRUE);
169     assertPatternFr("\\u2030573,0", 0.573, "\\u20300.0", TRUE);
170     assertPatternFr("p\\u2030p573,0", 0.573, "p\\u2030p0.0", TRUE);
171     assertPatternFr("p\\u2030p0,6", 0.573, "p'\\u2030'p0.0", TRUE);
172     assertPatternFr("\\u203032,60", 0.0326, "\\u2030@@@@", TRUE);
173     assertPatternFr("\\u203015 400", 15.43, "\\u2030#,@@@", TRUE);
174     assertPatternFr("\\u203016 551,7", 16.55, "\\u2030#,##4.1", TRUE);
175     assertPatternFr("\\u2030163E3", 162.55, "\\u2030##0.00E0", TRUE);
176 }
177 
TestPadding()178 void NumberFormatSpecificationTest::TestPadding() {
179     assertPatternFr("$***1 234", 1234, "$**####,##0", TRUE);
180     assertPatternFr("xxx$1 234", 1234, "*x$####,##0", TRUE);
181     assertPatternFr("1 234xxx$", 1234, "####,##0*x$", TRUE);
182     assertPatternFr("1 234$xxx", 1234, "####,##0$*x", TRUE);
183     assertPatternFr("ne1 234nx", -1234, "####,##0$*x;ne#n", TRUE);
184     assertPatternFr("n1 234*xx", -1234, "####,##0$*x;n#'*'", TRUE);
185     assertPatternFr("yyyy%432,6", 4.33, "*y%4.2######",  TRUE);
186     if (!logKnownIssue("11025")) {
187         assertPatternFr("EUR *433,00", 433.0, "\\u00a4\\u00a4 **####0.00");
188         assertPatternFr("EUR *433,00", 433.0, "\\u00a4\\u00a4 **#######0");
189     }
190     {
191         UnicodeString upattern("\\u00a4\\u00a4 **#######0", -1, US_INV);
192         upattern = upattern.unescape();
193         UErrorCode status = U_ZERO_ERROR;
194         UnicodeString result;
195         DecimalFormat fmt(
196                 upattern, new DecimalFormatSymbols("fr", status), status);
197         if (U_FAILURE(status)) {
198             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
199         } else {
200             fmt.setCurrency(kJPY);
201             fmt.format(433.22, result);
202             assertSuccess("", status);
203             assertEquals("", "JPY ****433", result, TRUE);
204         }
205     }
206     {
207         UnicodeString upattern(
208             "\\u00a4\\u00a4 **#######0;\\u00a4\\u00a4 (#)", -1, US_INV);
209         upattern = upattern.unescape();
210         UErrorCode status = U_ZERO_ERROR;
211         UnicodeString result;
212         DecimalFormat fmt(
213                 upattern,
214                 new DecimalFormatSymbols("en_US", status),
215                 status);
216         if (U_FAILURE(status)) {
217             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
218         } else {
219             fmt.format(-433.22, result);
220             assertSuccess("", status);
221             assertEquals("", "USD (433.22)", result, TRUE);
222         }
223     }
224     const char *paddedSciPattern = "QU**00.#####E0";
225     assertPatternFr("QU***43,3E-1", 4.33, paddedSciPattern, TRUE);
226     {
227         UErrorCode status = U_ZERO_ERROR;
228         DecimalFormatSymbols *sym = new DecimalFormatSymbols("fr", status);
229         sym->setSymbol(DecimalFormatSymbols::kExponentialSymbol, "EE");
230         DecimalFormat fmt(
231                 paddedSciPattern,
232                 sym,
233                 status);
234         if (U_FAILURE(status)) {
235             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
236         } else {
237             UnicodeString result;
238             fmt.format(4.33, result);
239             assertSuccess("", status);
240             assertEquals("", "QU**43,3EE-1", result, TRUE);
241         }
242     }
243     // padding cannot work as intended with scientific notation.
244     assertPatternFr("QU**43,32E-1", 4.332, paddedSciPattern, TRUE);
245 }
246 
assertPatternFr(const char * expected,double x,const char * pattern,UBool possibleDataError)247 void NumberFormatSpecificationTest::assertPatternFr(
248         const char *expected,
249         double x,
250         const char *pattern,
251         UBool possibleDataError) {
252     UnicodeString upattern(pattern, -1, US_INV);
253     UnicodeString uexpected(expected, -1, US_INV);
254     upattern = upattern.unescape();
255     uexpected = uexpected.unescape();
256     UErrorCode status = U_ZERO_ERROR;
257     UnicodeString result;
258     DecimalFormat fmt(
259             upattern, new DecimalFormatSymbols("fr_FR", status), status);
260     if (U_FAILURE(status)) {
261         dataerrln("Error creating DecimalFormatSymbols - %s", u_errorName(status));
262         return;
263     }
264     fmt.format(x, result);
265     fixNonBreakingSpace(result);
266     assertSuccess("", status);
267     assertEquals("", uexpected, result, possibleDataError);
268 }
269 
createNumberFormatSpecificationTest()270 extern IntlTest *createNumberFormatSpecificationTest() {
271     return new NumberFormatSpecificationTest();
272 }
273 
274 #endif
275