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