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(); \ 25 test(); \ 26 } \ 27 break 28 29void 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 */ 60void 61RbnfRoundTripTest::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 */ 78void 79RbnfRoundTripTest::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 */ 96void 97RbnfRoundTripTest::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 */ 114void 115RbnfRoundTripTest::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 */ 132void 133RbnfRoundTripTest::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 */ 150void 151RbnfRoundTripTest::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 */ 168void 169RbnfRoundTripTest::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 */ 186void 187RbnfRoundTripTest::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 */ 204void 205RbnfRoundTripTest::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 */ 222void 223RbnfRoundTripTest::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 */ 240void 241RbnfRoundTripTest::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 */ 258void 259RbnfRoundTripTest::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 273void 274RbnfRoundTripTest::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 356void 357RbnfRoundTripTest::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