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