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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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