• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *******************************************************************************
3  * Copyright (C) 1996-2009, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 
8 #include "unicode/utypes.h"
9 
10 #if !UCONFIG_NO_FORMATTING
11 
12 #include "itrbnfrt.h"
13 
14 #include "unicode/fmtable.h"
15 #include <math.h> // fabs
16 #include <stdio.h>
17 
18 // current macro not in icu1.8.1
19 #define TESTCASE(id,test)             \
20     case id:                          \
21         name = #test;                 \
22         if (exec) {                   \
23             logln(#test "---");       \
24             logln((UnicodeString)""); \
25             test();                   \
26         }                             \
27         break
28 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)29 void RbnfRoundTripTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/)
30 {
31     if (exec) logln("TestSuite RuleBasedNumberFormatRT");
32     switch (index) {
33 #if U_HAVE_RBNF
34       TESTCASE(0, TestEnglishSpelloutRT);
35       TESTCASE(1, TestDurationsRT);
36       TESTCASE(2, TestSpanishSpelloutRT);
37       TESTCASE(3, TestFrenchSpelloutRT);
38       TESTCASE(4, TestSwissFrenchSpelloutRT);
39       TESTCASE(5, TestItalianSpelloutRT);
40       TESTCASE(6, TestGermanSpelloutRT);
41       TESTCASE(7, TestSwedishSpelloutRT);
42       TESTCASE(8, TestDutchSpelloutRT);
43       TESTCASE(9, TestJapaneseSpelloutRT);
44       TESTCASE(10, TestRussianSpelloutRT);
45       TESTCASE(11, TestPortugueseSpelloutRT);
46 #else
47       TESTCASE(0, TestRBNFDisabled);
48 #endif
49     default:
50       name = "";
51       break;
52     }
53 }
54 
55 #if U_HAVE_RBNF
56 
57 /**
58  * Perform an exhaustive round-trip test on the English spellout rules
59  */
60 void
TestEnglishSpelloutRT()61 RbnfRoundTripTest::TestEnglishSpelloutRT()
62 {
63   UErrorCode status = U_ZERO_ERROR;
64   RuleBasedNumberFormat* formatter
65     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
66 
67   if (U_FAILURE(status)) {
68     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
69   } else {
70     doTest(formatter, -12345678, 12345678);
71   }
72   delete formatter;
73 }
74 
75 /**
76  * Perform an exhaustive round-trip test on the duration-formatting rules
77  */
78 void
TestDurationsRT()79 RbnfRoundTripTest::TestDurationsRT()
80 {
81   UErrorCode status = U_ZERO_ERROR;
82   RuleBasedNumberFormat* formatter
83     = new RuleBasedNumberFormat(URBNF_DURATION, Locale::getUS(), status);
84 
85   if (U_FAILURE(status)) {
86     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
87   } else {
88     doTest(formatter, 0, 12345678);
89   }
90   delete formatter;
91 }
92 
93 /**
94  * Perform an exhaustive round-trip test on the Spanish spellout rules
95  */
96 void
TestSpanishSpelloutRT()97 RbnfRoundTripTest::TestSpanishSpelloutRT()
98 {
99   UErrorCode status = U_ZERO_ERROR;
100   RuleBasedNumberFormat* formatter
101     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("es", "es"), status);
102 
103   if (U_FAILURE(status)) {
104     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
105   } else {
106     doTest(formatter, -12345678, 12345678);
107   }
108   delete formatter;
109 }
110 
111 /**
112  * Perform an exhaustive round-trip test on the French spellout rules
113  */
114 void
TestFrenchSpelloutRT()115 RbnfRoundTripTest::TestFrenchSpelloutRT()
116 {
117   UErrorCode status = U_ZERO_ERROR;
118   RuleBasedNumberFormat* formatter
119     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getFrance(), status);
120 
121   if (U_FAILURE(status)) {
122     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
123   } else {
124     doTest(formatter, -12345678, 12345678);
125   }
126   delete formatter;
127 }
128 
129 /**
130  * Perform an exhaustive round-trip test on the Swiss French spellout rules
131  */
132 void
TestSwissFrenchSpelloutRT()133 RbnfRoundTripTest::TestSwissFrenchSpelloutRT()
134 {
135   UErrorCode status = U_ZERO_ERROR;
136   RuleBasedNumberFormat* formatter
137     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "CH"), status);
138 
139   if (U_FAILURE(status)) {
140     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
141   } else {
142     doTest(formatter, -12345678, 12345678);
143   }
144   delete formatter;
145 }
146 
147 /**
148  * Perform an exhaustive round-trip test on the Italian spellout rules
149  */
150 void
TestItalianSpelloutRT()151 RbnfRoundTripTest::TestItalianSpelloutRT()
152 {
153   UErrorCode status = U_ZERO_ERROR;
154   RuleBasedNumberFormat* formatter
155     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getItalian(), status);
156 
157   if (U_FAILURE(status)) {
158     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
159   } else {
160     doTest(formatter, -999999, 999999);
161   }
162   delete formatter;
163 }
164 
165 /**
166  * Perform an exhaustive round-trip test on the German spellout rules
167  */
168 void
TestGermanSpelloutRT()169 RbnfRoundTripTest::TestGermanSpelloutRT()
170 {
171   UErrorCode status = U_ZERO_ERROR;
172   RuleBasedNumberFormat* formatter
173     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getGermany(), status);
174 
175   if (U_FAILURE(status)) {
176     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
177   } else {
178     doTest(formatter, 0, 12345678);
179   }
180   delete formatter;
181 }
182 
183 /**
184  * Perform an exhaustive round-trip test on the Swedish spellout rules
185  */
186 void
TestSwedishSpelloutRT()187 RbnfRoundTripTest::TestSwedishSpelloutRT()
188 {
189   UErrorCode status = U_ZERO_ERROR;
190   RuleBasedNumberFormat* formatter
191     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("sv", "SE"), status);
192 
193   if (U_FAILURE(status)) {
194     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
195   } else {
196     doTest(formatter, 0, 12345678);
197   }
198   delete formatter;
199 }
200 
201 /**
202  * Perform an exhaustive round-trip test on the Dutch spellout rules
203  */
204 void
TestDutchSpelloutRT()205 RbnfRoundTripTest::TestDutchSpelloutRT()
206 {
207   UErrorCode status = U_ZERO_ERROR;
208   RuleBasedNumberFormat* formatter
209     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("nl", "NL"), status);
210 
211   if (U_FAILURE(status)) {
212     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
213   } else {
214     doTest(formatter, -12345678, 12345678);
215   }
216   delete formatter;
217 }
218 
219 /**
220  * Perform an exhaustive round-trip test on the Japanese spellout rules
221  */
222 void
TestJapaneseSpelloutRT()223 RbnfRoundTripTest::TestJapaneseSpelloutRT()
224 {
225   UErrorCode status = U_ZERO_ERROR;
226   RuleBasedNumberFormat* formatter
227     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getJapan(), status);
228 
229   if (U_FAILURE(status)) {
230     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
231   } else {
232     doTest(formatter, 0, 12345678);
233   }
234   delete formatter;
235 }
236 
237 /**
238  * Perform an exhaustive round-trip test on the Russian spellout rules
239  */
240 void
TestRussianSpelloutRT()241 RbnfRoundTripTest::TestRussianSpelloutRT()
242 {
243   UErrorCode status = U_ZERO_ERROR;
244   RuleBasedNumberFormat* formatter
245     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("ru", "RU"), status);
246 
247   if (U_FAILURE(status)) {
248     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
249   } else {
250     doTest(formatter, 0, 12345678);
251   }
252   delete formatter;
253 }
254 
255 /**
256  * Perform an exhaustive round-trip test on the Portuguese spellout rules
257  */
258 void
TestPortugueseSpelloutRT()259 RbnfRoundTripTest::TestPortugueseSpelloutRT()
260 {
261   UErrorCode status = U_ZERO_ERROR;
262   RuleBasedNumberFormat* formatter
263     = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("pt", "BR"), status);
264 
265   if (U_FAILURE(status)) {
266     errcheckln(status, "failed to construct formatter - %s", u_errorName(status));
267   } else {
268     doTest(formatter, -12345678, 12345678);
269   }
270   delete formatter;
271 }
272 
273 void
doTest(const RuleBasedNumberFormat * formatter,double lowLimit,double highLimit)274 RbnfRoundTripTest::doTest(const RuleBasedNumberFormat* formatter,
275                           double lowLimit,
276                           double highLimit)
277 {
278   char buf[128];
279 
280   uint32_t count = 0;
281   double increment = 1;
282   for (double i = lowLimit; i <= highLimit; i += increment) {
283     if (count % 1000 == 0) {
284       sprintf(buf, "%.12g", i);
285       logln(buf);
286     }
287 
288     if (fabs(i) <  5000)
289       increment = 1;
290     else if (fabs(i) < 500000)
291       increment = 2737;
292     else
293       increment = 267437;
294 
295     UnicodeString formatResult;
296     formatter->format(i, formatResult);
297     UErrorCode status = U_ZERO_ERROR;
298     Formattable parseResult;
299     formatter->parse(formatResult, parseResult, status);
300     if (U_FAILURE(status)) {
301       sprintf(buf, "Round-trip status failure: %.12g, status: %d", i, status);
302       errln(buf);
303       return;
304     } else {
305       double rt = (parseResult.getType() == Formattable::kDouble) ?
306         parseResult.getDouble() :
307         (double)parseResult.getLong();
308 
309       if (rt != i) {
310         sprintf(buf, "Round-trip failed: %.12g -> %.12g", i, rt);
311         errln(buf);
312         return;
313       }
314     }
315 
316     ++count;
317   }
318 
319   if (lowLimit < 0) {
320     double d = 1.234;
321     while (d < 1000) {
322       UnicodeString formatResult;
323       formatter->format(d, formatResult);
324       UErrorCode status = U_ZERO_ERROR;
325       Formattable parseResult;
326       formatter->parse(formatResult, parseResult, status);
327       if (U_FAILURE(status)) {
328         sprintf(buf, "Round-trip status failure: %.12g, status: %d", d, status);
329         errln(buf);
330         return;
331       } else {
332         double rt = (parseResult.getType() == Formattable::kDouble) ?
333           parseResult.getDouble() :
334           (double)parseResult.getLong();
335 
336         if (rt != d) {
337           UnicodeString msg;
338           sprintf(buf, "Round-trip failed: %.12g -> ", d);
339           msg.append(buf);
340           msg.append(formatResult);
341           sprintf(buf, " -> %.12g", rt);
342           msg.append(buf);
343           errln(msg);
344           return;
345         }
346       }
347 
348       d *= 10;
349     }
350   }
351 }
352 
353 /* U_HAVE_RBNF */
354 #else
355 
356 void
TestRBNFDisabled()357 RbnfRoundTripTest::TestRBNFDisabled() {
358     errln("*** RBNF currently disabled on this platform ***\n");
359 }
360 
361 /* U_HAVE_RBNF */
362 #endif
363 
364 #endif /* #if !UCONFIG_NO_FORMATTING */
365