• Home
  • History
  • Annotate
  • 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