OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * Copyright (C) 1996-2010, 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 "itrbnf.h" |
| 13 |
| 14 #include "unicode/umachine.h" |
| 15 |
| 16 #include "unicode/tblcoll.h" |
| 17 #include "unicode/coleitr.h" |
| 18 #include "unicode/ures.h" |
| 19 #include "unicode/ustring.h" |
| 20 #include "unicode/decimfmt.h" |
| 21 #include "unicode/udata.h" |
| 22 #include "testutil.h" |
| 23 |
| 24 //#include "llong.h" |
| 25 |
| 26 #include <string.h> |
| 27 |
| 28 // import com.ibm.text.RuleBasedNumberFormat; |
| 29 // import com.ibm.test.TestFmwk; |
| 30 |
| 31 // import java.util.Locale; |
| 32 // import java.text.NumberFormat; |
| 33 |
| 34 // current macro not in icu1.8.1 |
| 35 #define TESTCASE(id,test) \ |
| 36 case id: \ |
| 37 name = #test; \ |
| 38 if (exec) { \ |
| 39 logln(#test "---"); \ |
| 40 logln(); \ |
| 41 test(); \ |
| 42 } \ |
| 43 break |
| 44 |
| 45 void IntlTestRBNF::runIndexedTest(int32_t index, UBool exec, const char* &name,
char* /*par*/) |
| 46 { |
| 47 if (exec) logln("TestSuite RuleBasedNumberFormat"); |
| 48 switch (index) { |
| 49 #if U_HAVE_RBNF |
| 50 TESTCASE(0, TestEnglishSpellout); |
| 51 TESTCASE(1, TestOrdinalAbbreviations); |
| 52 TESTCASE(2, TestDurations); |
| 53 TESTCASE(3, TestSpanishSpellout); |
| 54 TESTCASE(4, TestFrenchSpellout); |
| 55 TESTCASE(5, TestSwissFrenchSpellout); |
| 56 TESTCASE(6, TestItalianSpellout); |
| 57 TESTCASE(7, TestGermanSpellout); |
| 58 TESTCASE(8, TestThaiSpellout); |
| 59 TESTCASE(9, TestAPI); |
| 60 TESTCASE(10, TestFractionalRuleSet); |
| 61 TESTCASE(11, TestSwedishSpellout); |
| 62 TESTCASE(12, TestBelgianFrenchSpellout); |
| 63 TESTCASE(13, TestSmallValues); |
| 64 TESTCASE(14, TestLocalizations); |
| 65 TESTCASE(15, TestAllLocales); |
| 66 TESTCASE(16, TestHebrewFraction); |
| 67 TESTCASE(17, TestPortugueseSpellout); |
| 68 TESTCASE(18, TestMultiplierSubstitution); |
| 69 #else |
| 70 TESTCASE(0, TestRBNFDisabled); |
| 71 #endif |
| 72 default: |
| 73 name = ""; |
| 74 break; |
| 75 } |
| 76 } |
| 77 |
| 78 #if U_HAVE_RBNF |
| 79 |
| 80 void IntlTestRBNF::TestHebrewFraction() { |
| 81 |
| 82 // this is the expected output for 123.45, with no '<' in it. |
| 83 UChar text1[] = { |
| 84 0x05de, 0x05d0, 0x05d4, 0x0020, |
| 85 0x05e2, 0x05e9, 0x05e8, 0x05d9, 0x05dd, 0x0020, |
| 86 0x05d5, 0x05e9, 0x05dc, 0x05d5, 0x05e9, 0x0020, |
| 87 0x05e0, 0x05e7, 0x05d5, 0x05d3, 0x05d4, 0x0020, |
| 88 0x05d0, 0x05e8, 0x05d1, 0x05e2, 0x0020, |
| 89 0x05d7, 0x05de, 0x05e9, 0x0000, |
| 90 }; |
| 91 UChar text2[] = { |
| 92 0x05DE, 0x05D0, 0x05D4, 0x0020, |
| 93 0x05E2, 0x05E9, 0x05E8, 0x05D9, 0x05DD, 0x0020, |
| 94 0x05D5, 0x05E9, 0x05DC, 0x05D5, 0x05E9, 0x0020, |
| 95 0x05E0, 0x05E7, 0x05D5, 0x05D3, 0x05D4, 0x0020, |
| 96 0x05D0, 0x05E4, 0x05E1, 0x0020, |
| 97 0x05D0, 0x05E4, 0x05E1, 0x0020, |
| 98 0x05D0, 0x05E8, 0x05D1, 0x05E2, 0x0020, |
| 99 0x05D7, 0x05DE, 0x05E9, 0x0000, |
| 100 }; |
| 101 UErrorCode status = U_ZERO_ERROR; |
| 102 RuleBasedNumberFormat* formatter = new RuleBasedNumberFormat(URBNF_SPELLOUT,
"he_IL", status); |
| 103 if (status == U_MISSING_RESOURCE_ERROR || status == U_FILE_ACCESS_ERROR) { |
| 104 errcheckln(status, "Failed in constructing RuleBasedNumberFormat - %s",
u_errorName(status)); |
| 105 delete formatter; |
| 106 return; |
| 107 } |
| 108 UnicodeString result; |
| 109 Formattable parseResult; |
| 110 ParsePosition pp(0); |
| 111 { |
| 112 UnicodeString expected(text1); |
| 113 formatter->format(123.45, result); |
| 114 if (result != expected) { |
| 115 errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\
nbut got: '" + TestUtility::hex(result) + "'"); |
| 116 } else { |
| 117 // formatter->parse(result, parseResult, pp); |
| 118 // if (parseResult.getDouble() != 123.45) { |
| 119 // errln("expected 123.45 but got: %g", parseResult.getDouble()); |
| 120 // } |
| 121 } |
| 122 } |
| 123 { |
| 124 UnicodeString expected(text2); |
| 125 result.remove(); |
| 126 formatter->format(123.0045, result); |
| 127 if (result != expected) { |
| 128 errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\
nbut got: '" + TestUtility::hex(result) + "'"); |
| 129 } else { |
| 130 pp.setIndex(0); |
| 131 // formatter->parse(result, parseResult, pp); |
| 132 // if (parseResult.getDouble() != 123.0045) { |
| 133 // errln("expected 123.0045 but got: %g", parseResult.getDouble()
); |
| 134 // } |
| 135 } |
| 136 } |
| 137 delete formatter; |
| 138 } |
| 139 |
| 140 void |
| 141 IntlTestRBNF::TestAPI() { |
| 142 // This test goes through the APIs that were not tested before. |
| 143 // These tests are too small to have separate test classes/functions |
| 144 |
| 145 UErrorCode status = U_ZERO_ERROR; |
| 146 RuleBasedNumberFormat* formatter |
| 147 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status); |
| 148 if (status == U_MISSING_RESOURCE_ERROR || status == U_FILE_ACCESS_ERROR) { |
| 149 dataerrln("Unable to create formatter. - %s", u_errorName(status)); |
| 150 delete formatter; |
| 151 return; |
| 152 } |
| 153 |
| 154 logln("RBNF API test starting"); |
| 155 // test clone |
| 156 { |
| 157 logln("Testing Clone"); |
| 158 RuleBasedNumberFormat* rbnfClone = (RuleBasedNumberFormat *)formatter->clone
(); |
| 159 if(rbnfClone != NULL) { |
| 160 if(!(*rbnfClone == *formatter)) { |
| 161 errln("Clone should be semantically equivalent to the original!"); |
| 162 } |
| 163 delete rbnfClone; |
| 164 } else { |
| 165 errln("Cloning failed!"); |
| 166 } |
| 167 } |
| 168 |
| 169 // test assignment |
| 170 { |
| 171 logln("Testing assignment operator"); |
| 172 RuleBasedNumberFormat assignResult(URBNF_SPELLOUT, Locale("es", "ES", ""), s
tatus); |
| 173 assignResult = *formatter; |
| 174 if(!(assignResult == *formatter)) { |
| 175 errln("Assignment result should be semantically equivalent to the original
!"); |
| 176 } |
| 177 } |
| 178 |
| 179 // test rule constructor |
| 180 { |
| 181 logln("Testing rule constructor"); |
| 182 LocalUResourceBundlePointer en(ures_open(U_ICUDATA_NAME U_TREE_SEPARATOR_STR
ING "rbnf", "en", &status)); |
| 183 if(U_FAILURE(status)) { |
| 184 errln("Unable to access resource bundle with data!"); |
| 185 } else { |
| 186 int32_t ruleLen = 0; |
| 187 int32_t len = 0; |
| 188 LocalUResourceBundlePointer rbnfRules(ures_getByKey(en.getAlias(), "RBNFRu
les", NULL, &status)); |
| 189 LocalUResourceBundlePointer ruleSets(ures_getByKey(rbnfRules.getAlias(), "
SpelloutRules", NULL, &status)); |
| 190 UnicodeString desc; |
| 191 while (ures_hasNext(ruleSets.getAlias())) { |
| 192 const UChar* currentString = ures_getNextString(ruleSets.getAlias(),
&len, NULL, &status); |
| 193 ruleLen += len; |
| 194 desc.append(currentString); |
| 195 } |
| 196 |
| 197 const UChar *spelloutRules = desc.getTerminatedBuffer(); |
| 198 |
| 199 if(U_FAILURE(status) || ruleLen == 0 || spelloutRules == NULL) { |
| 200 errln("Unable to access the rules string!"); |
| 201 } else { |
| 202 UParseError perror; |
| 203 RuleBasedNumberFormat ruleCtorResult(spelloutRules, Locale::getUS(), per
ror, status); |
| 204 if(!(ruleCtorResult == *formatter)) { |
| 205 errln("Formatter constructed from the original rules should be semanti
cally equivalent to the original!"); |
| 206 } |
| 207 |
| 208 // Jitterbug 4452, for coverage |
| 209 RuleBasedNumberFormat nf(spelloutRules, (UnicodeString)"", Locale::getUS
(), perror, status); |
| 210 if(!(nf == *formatter)) { |
| 211 errln("Formatter constructed from the original rules should be semanti
cally equivalent to the original!"); |
| 212 } |
| 213 } |
| 214 } |
| 215 } |
| 216 |
| 217 // test getRules |
| 218 { |
| 219 logln("Testing getRules function"); |
| 220 UnicodeString rules = formatter->getRules(); |
| 221 UParseError perror; |
| 222 RuleBasedNumberFormat fromRulesResult(rules, Locale::getUS(), perror, status
); |
| 223 |
| 224 if(!(fromRulesResult == *formatter)) { |
| 225 errln("Formatter constructed from rules obtained by getRules should be sem
antically equivalent to the original!"); |
| 226 } |
| 227 } |
| 228 |
| 229 |
| 230 { |
| 231 logln("Testing copy constructor"); |
| 232 RuleBasedNumberFormat copyCtorResult(*formatter); |
| 233 if(!(copyCtorResult == *formatter)) { |
| 234 errln("Copy constructor result result should be semantically equivalent to
the original!"); |
| 235 } |
| 236 } |
| 237 |
| 238 #if !UCONFIG_NO_COLLATION |
| 239 // test ruleset names |
| 240 { |
| 241 logln("Testing getNumberOfRuleSetNames, getRuleSetName and format using rule
set names"); |
| 242 int32_t noOfRuleSetNames = formatter->getNumberOfRuleSetNames(); |
| 243 if(noOfRuleSetNames == 0) { |
| 244 errln("Number of rule set names should be more than zero"); |
| 245 } |
| 246 UnicodeString ruleSetName; |
| 247 int32_t i = 0; |
| 248 int32_t intFormatNum = 34567; |
| 249 double doubleFormatNum = 893411.234; |
| 250 logln("number of rule set names is %i", noOfRuleSetNames); |
| 251 for(i = 0; i < noOfRuleSetNames; i++) { |
| 252 FieldPosition pos1, pos2; |
| 253 UnicodeString intFormatResult, doubleFormatResult; |
| 254 Formattable intParseResult, doubleParseResult; |
| 255 |
| 256 ruleSetName = formatter->getRuleSetName(i); |
| 257 log("Rule set name %i is ", i); |
| 258 log(ruleSetName); |
| 259 logln(". Format results are: "); |
| 260 intFormatResult = formatter->format(intFormatNum, ruleSetName, intFormatRe
sult, pos1, status); |
| 261 doubleFormatResult = formatter->format(doubleFormatNum, ruleSetName, doubl
eFormatResult, pos2, status); |
| 262 if(U_FAILURE(status)) { |
| 263 errln("Format using a rule set failed"); |
| 264 break; |
| 265 } |
| 266 logln(intFormatResult); |
| 267 logln(doubleFormatResult); |
| 268 formatter->setLenient(TRUE); |
| 269 formatter->parse(intFormatResult, intParseResult, status); |
| 270 formatter->parse(doubleFormatResult, doubleParseResult, status); |
| 271 |
| 272 logln("Parse results for lenient = TRUE, %i, %f", intParseResult.getLong()
, doubleParseResult.getDouble()); |
| 273 |
| 274 formatter->setLenient(FALSE); |
| 275 formatter->parse(intFormatResult, intParseResult, status); |
| 276 formatter->parse(doubleFormatResult, doubleParseResult, status); |
| 277 |
| 278 logln("Parse results for lenient = FALSE, %i, %f", intParseResult.getLong(
), doubleParseResult.getDouble()); |
| 279 |
| 280 if(U_FAILURE(status)) { |
| 281 errln("Error during parsing"); |
| 282 } |
| 283 |
| 284 intFormatResult = formatter->format(intFormatNum, "BLABLA", intFormatResul
t, pos1, status); |
| 285 if(U_SUCCESS(status)) { |
| 286 errln("Using invalid rule set name should have failed"); |
| 287 break; |
| 288 } |
| 289 status = U_ZERO_ERROR; |
| 290 doubleFormatResult = formatter->format(doubleFormatNum, "TRUC", doubleForm
atResult, pos2, status); |
| 291 if(U_SUCCESS(status)) { |
| 292 errln("Using invalid rule set name should have failed"); |
| 293 break; |
| 294 } |
| 295 status = U_ZERO_ERROR; |
| 296 } |
| 297 status = U_ZERO_ERROR; |
| 298 } |
| 299 #endif |
| 300 |
| 301 // test API |
| 302 UnicodeString expected("four point five",""); |
| 303 logln("Testing format(double)"); |
| 304 UnicodeString result; |
| 305 formatter->format(4.5,result); |
| 306 if(result != expected) { |
| 307 errln("Formatted 4.5, expected " + expected + " got " + result); |
| 308 } else { |
| 309 logln("Formatted 4.5, expected " + expected + " got " + result); |
| 310 } |
| 311 result.remove(); |
| 312 expected = "four"; |
| 313 formatter->format((int32_t)4,result); |
| 314 if(result != expected) { |
| 315 errln("Formatted 4, expected " + expected + " got " + result); |
| 316 } else { |
| 317 logln("Formatted 4, expected " + expected + " got " + result); |
| 318 } |
| 319 |
| 320 result.remove(); |
| 321 FieldPosition pos; |
| 322 formatter->format((int64_t)4, result, pos, status = U_ZERO_ERROR); |
| 323 if(result != expected) { |
| 324 errln("Formatted 4 int64_t, expected " + expected + " got " + result); |
| 325 } else { |
| 326 logln("Formatted 4 int64_t, expected " + expected + " got " + result); |
| 327 } |
| 328 |
| 329 //Jitterbug 4452, for coverage |
| 330 result.remove(); |
| 331 FieldPosition pos2; |
| 332 formatter->format((int64_t)4, formatter->getRuleSetName(0), result, pos2, stat
us = U_ZERO_ERROR); |
| 333 if(result != expected) { |
| 334 errln("Formatted 4 int64_t, expected " + expected + " got " + result); |
| 335 } else { |
| 336 logln("Formatted 4 int64_t, expected " + expected + " got " + result); |
| 337 } |
| 338 |
| 339 // clean up |
| 340 logln("Cleaning up"); |
| 341 delete formatter; |
| 342 } |
| 343 |
| 344 void IntlTestRBNF::TestFractionalRuleSet() |
| 345 { |
| 346 UnicodeString fracRules( |
| 347 "%main:\n" |
| 348 // this rule formats the number if it's 1 or more. It formats |
| 349 // the integral part using a DecimalFormat ("#,##0" puts |
| 350 // thousands separators in the right places) and the fractional |
| 351 // part using %%frac. If there is no fractional part, it |
| 352 // just shows the integral part. |
| 353 " x.0: <#,##0<[ >%%frac>];\n" |
| 354 // this rule formats the number if it's between 0 and 1. It |
| 355 // shows only the fractional part (0.5 shows up as "1/2," not |
| 356 // "0 1/2") |
| 357 " 0.x: >%%frac>;\n" |
| 358 // the fraction rule set. This works the same way as the one in the |
| 359 // preceding example: We multiply the fractional part of the number |
| 360 // being formatted by each rule's base value and use the rule that |
| 361 // produces the result closest to 0 (or the first rule that produces 0). |
| 362 // Since we only provide rules for the numbers from 2 to 10, we know |
| 363 // we'll get a fraction with a denominator between 2 and 10. |
| 364 // "<0<" causes the numerator of the fraction to be formatted |
| 365 // using numerals |
| 366 "%%frac:\n" |
| 367 " 2: 1/2;\n" |
| 368 " 3: <0</3;\n" |
| 369 " 4: <0</4;\n" |
| 370 " 5: <0</5;\n" |
| 371 " 6: <0</6;\n" |
| 372 " 7: <0</7;\n" |
| 373 " 8: <0</8;\n" |
| 374 " 9: <0</9;\n" |
| 375 " 10: <0</10;\n"); |
| 376 |
| 377 // mondo hack |
| 378 int len = fracRules.length(); |
| 379 int change = 2; |
| 380 for (int i = 0; i < len; ++i) { |
| 381 UChar ch = fracRules.charAt(i); |
| 382 if (ch == '\n') { |
| 383 change = 2; // change ok |
| 384 } else if (ch == ':') { |
| 385 change = 1; // change, but once we hit a non-space char, don't chang
e |
| 386 } else if (ch == ' ') { |
| 387 if (change != 0) { |
| 388 fracRules.setCharAt(i, (UChar)0x200e); |
| 389 } |
| 390 } else { |
| 391 if (change == 1) { |
| 392 change = 0; |
| 393 } |
| 394 } |
| 395 } |
| 396 |
| 397 UErrorCode status = U_ZERO_ERROR; |
| 398 UParseError perror; |
| 399 RuleBasedNumberFormat formatter(fracRules, Locale::getEnglish(), perror, sta
tus); |
| 400 if (U_FAILURE(status)) { |
| 401 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 402 } else { |
| 403 static const char* const testData[][2] = { |
| 404 { "0", "0" }, |
| 405 { ".1", "1/10" }, |
| 406 { ".11", "1/9" }, |
| 407 { ".125", "1/8" }, |
| 408 { ".1428", "1/7" }, |
| 409 { ".1667", "1/6" }, |
| 410 { ".2", "1/5" }, |
| 411 { ".25", "1/4" }, |
| 412 { ".333", "1/3" }, |
| 413 { ".5", "1/2" }, |
| 414 { "1.1", "1 1/10" }, |
| 415 { "2.11", "2 1/9" }, |
| 416 { "3.125", "3 1/8" }, |
| 417 { "4.1428", "4 1/7" }, |
| 418 { "5.1667", "5 1/6" }, |
| 419 { "6.2", "6 1/5" }, |
| 420 { "7.25", "7 1/4" }, |
| 421 { "8.333", "8 1/3" }, |
| 422 { "9.5", "9 1/2" }, |
| 423 { ".2222", "2/9" }, |
| 424 { ".4444", "4/9" }, |
| 425 { ".5555", "5/9" }, |
| 426 { "1.2856", "1 2/7" }, |
| 427 { NULL, NULL } |
| 428 }; |
| 429 doTest(&formatter, testData, FALSE); // exact values aren't parsable from
fractions |
| 430 } |
| 431 } |
| 432 |
| 433 #if 0 |
| 434 #define LLAssert(a) \ |
| 435 if (!(a)) errln("FAIL: " #a) |
| 436 |
| 437 void IntlTestRBNF::TestLLongConstructors() |
| 438 { |
| 439 logln("Testing constructors"); |
| 440 |
| 441 // constant (shouldn't really be public) |
| 442 LLAssert(llong(llong::kD32).asDouble() == llong::kD32); |
| 443 |
| 444 // internal constructor (shouldn't really be public) |
| 445 LLAssert(llong(0, 1).asDouble() == 1); |
| 446 LLAssert(llong(1, 0).asDouble() == llong::kD32); |
| 447 LLAssert(llong((uint32_t)-1, (uint32_t)-1).asDouble() == -1); |
| 448 |
| 449 // public empty constructor |
| 450 LLAssert(llong().asDouble() == 0); |
| 451 |
| 452 // public int32_t constructor |
| 453 LLAssert(llong((int32_t)0).asInt() == (int32_t)0); |
| 454 LLAssert(llong((int32_t)1).asInt() == (int32_t)1); |
| 455 LLAssert(llong((int32_t)-1).asInt() == (int32_t)-1); |
| 456 LLAssert(llong((int32_t)0x7fffffff).asInt() == (int32_t)0x7fffffff); |
| 457 LLAssert(llong((int32_t)0xffffffff).asInt() == (int32_t)-1); |
| 458 LLAssert(llong((int32_t)0x80000000).asInt() == (int32_t)0x80000000); |
| 459 |
| 460 // public int16_t constructor |
| 461 LLAssert(llong((int16_t)0).asInt() == (int16_t)0); |
| 462 LLAssert(llong((int16_t)1).asInt() == (int16_t)1); |
| 463 LLAssert(llong((int16_t)-1).asInt() == (int16_t)-1); |
| 464 LLAssert(llong((int16_t)0x7fff).asInt() == (int16_t)0x7fff); |
| 465 LLAssert(llong((int16_t)0xffff).asInt() == (int16_t)0xffff); |
| 466 LLAssert(llong((int16_t)0x8000).asInt() == (int16_t)0x8000); |
| 467 |
| 468 // public int8_t constructor |
| 469 LLAssert(llong((int8_t)0).asInt() == (int8_t)0); |
| 470 LLAssert(llong((int8_t)1).asInt() == (int8_t)1); |
| 471 LLAssert(llong((int8_t)-1).asInt() == (int8_t)-1); |
| 472 LLAssert(llong((int8_t)0x7f).asInt() == (int8_t)0x7f); |
| 473 LLAssert(llong((int8_t)0xff).asInt() == (int8_t)0xff); |
| 474 LLAssert(llong((int8_t)0x80).asInt() == (int8_t)0x80); |
| 475 |
| 476 // public uint16_t constructor |
| 477 LLAssert(llong((uint16_t)0).asUInt() == (uint16_t)0); |
| 478 LLAssert(llong((uint16_t)1).asUInt() == (uint16_t)1); |
| 479 LLAssert(llong((uint16_t)-1).asUInt() == (uint16_t)-1); |
| 480 LLAssert(llong((uint16_t)0x7fff).asUInt() == (uint16_t)0x7fff); |
| 481 LLAssert(llong((uint16_t)0xffff).asUInt() == (uint16_t)0xffff); |
| 482 LLAssert(llong((uint16_t)0x8000).asUInt() == (uint16_t)0x8000); |
| 483 |
| 484 // public uint32_t constructor |
| 485 LLAssert(llong((uint32_t)0).asUInt() == (uint32_t)0); |
| 486 LLAssert(llong((uint32_t)1).asUInt() == (uint32_t)1); |
| 487 LLAssert(llong((uint32_t)-1).asUInt() == (uint32_t)-1); |
| 488 LLAssert(llong((uint32_t)0x7fffffff).asUInt() == (uint32_t)0x7fffffff); |
| 489 LLAssert(llong((uint32_t)0xffffffff).asUInt() == (uint32_t)-1); |
| 490 LLAssert(llong((uint32_t)0x80000000).asUInt() == (uint32_t)0x80000000); |
| 491 |
| 492 // public double constructor |
| 493 LLAssert(llong((double)0).asDouble() == (double)0); |
| 494 LLAssert(llong((double)1).asDouble() == (double)1); |
| 495 LLAssert(llong((double)0x7fffffff).asDouble() == (double)0x7fffffff); |
| 496 LLAssert(llong((double)0x80000000).asDouble() == (double)0x80000000); |
| 497 LLAssert(llong((double)0x80000001).asDouble() == (double)0x80000001); |
| 498 |
| 499 // can't access uprv_maxmantissa, so fake it |
| 500 double maxmantissa = (llong((int32_t)1) << 40).asDouble(); |
| 501 LLAssert(llong(maxmantissa).asDouble() == maxmantissa); |
| 502 LLAssert(llong(-maxmantissa).asDouble() == -maxmantissa); |
| 503 |
| 504 // copy constructor |
| 505 LLAssert(llong(llong(0, 1)).asDouble() == 1); |
| 506 LLAssert(llong(llong(1, 0)).asDouble() == llong::kD32); |
| 507 LLAssert(llong(llong(-1, (uint32_t)-1)).asDouble() == -1); |
| 508 |
| 509 // asInt - test unsigned to signed narrowing conversion |
| 510 LLAssert(llong((uint32_t)-1).asInt() == (int32_t)0x7fffffff); |
| 511 LLAssert(llong(-1, 0).asInt() == (int32_t)0x80000000); |
| 512 |
| 513 // asUInt - test signed to unsigned narrowing conversion |
| 514 LLAssert(llong((int32_t)-1).asUInt() == (uint32_t)-1); |
| 515 LLAssert(llong((int32_t)0x80000000).asUInt() == (uint32_t)0x80000000); |
| 516 |
| 517 // asDouble already tested |
| 518 |
| 519 } |
| 520 |
| 521 void IntlTestRBNF::TestLLongSimpleOperators() |
| 522 { |
| 523 logln("Testing simple operators"); |
| 524 |
| 525 // operator== |
| 526 LLAssert(llong() == llong(0, 0)); |
| 527 LLAssert(llong(1,0) == llong(1, 0)); |
| 528 LLAssert(llong(0,1) == llong(0, 1)); |
| 529 |
| 530 // operator!= |
| 531 LLAssert(llong(1,0) != llong(1,1)); |
| 532 LLAssert(llong(0,1) != llong(1,1)); |
| 533 LLAssert(llong(0xffffffff,0xffffffff) != llong(0x7fffffff, 0xffffffff)); |
| 534 |
| 535 // unsigned > |
| 536 LLAssert(llong((int32_t)-1).ugt(llong(0x7fffffff, 0xffffffff))); |
| 537 |
| 538 // unsigned < |
| 539 LLAssert(llong(0x7fffffff, 0xffffffff).ult(llong((int32_t)-1))); |
| 540 |
| 541 // unsigned >= |
| 542 LLAssert(llong((int32_t)-1).uge(llong(0x7fffffff, 0xffffffff))); |
| 543 LLAssert(llong((int32_t)-1).uge(llong((int32_t)-1))); |
| 544 |
| 545 // unsigned <= |
| 546 LLAssert(llong(0x7fffffff, 0xffffffff).ule(llong((int32_t)-1))); |
| 547 LLAssert(llong((int32_t)-1).ule(llong((int32_t)-1))); |
| 548 |
| 549 // operator> |
| 550 LLAssert(llong(1, 1) > llong(1, 0)); |
| 551 LLAssert(llong(0, 0x80000000) > llong(0, 0x7fffffff)); |
| 552 LLAssert(llong(0x80000000, 1) > llong(0x80000000, 0)); |
| 553 LLAssert(llong(1, 0) > llong(0, 0x7fffffff)); |
| 554 LLAssert(llong(1, 0) > llong(0, 0xffffffff)); |
| 555 LLAssert(llong(0, 0) > llong(0x80000000, 1)); |
| 556 |
| 557 // operator< |
| 558 LLAssert(llong(1, 0) < llong(1, 1)); |
| 559 LLAssert(llong(0, 0x7fffffff) < llong(0, 0x80000000)); |
| 560 LLAssert(llong(0x80000000, 0) < llong(0x80000000, 1)); |
| 561 LLAssert(llong(0, 0x7fffffff) < llong(1, 0)); |
| 562 LLAssert(llong(0, 0xffffffff) < llong(1, 0)); |
| 563 LLAssert(llong(0x80000000, 1) < llong(0, 0)); |
| 564 |
| 565 // operator>= |
| 566 LLAssert(llong(1, 1) >= llong(1, 0)); |
| 567 LLAssert(llong(0, 0x80000000) >= llong(0, 0x7fffffff)); |
| 568 LLAssert(llong(0x80000000, 1) >= llong(0x80000000, 0)); |
| 569 LLAssert(llong(1, 0) >= llong(0, 0x7fffffff)); |
| 570 LLAssert(llong(1, 0) >= llong(0, 0xffffffff)); |
| 571 LLAssert(llong(0, 0) >= llong(0x80000000, 1)); |
| 572 LLAssert(llong() >= llong(0, 0)); |
| 573 LLAssert(llong(1,0) >= llong(1, 0)); |
| 574 LLAssert(llong(0,1) >= llong(0, 1)); |
| 575 |
| 576 // operator<= |
| 577 LLAssert(llong(1, 0) <= llong(1, 1)); |
| 578 LLAssert(llong(0, 0x7fffffff) <= llong(0, 0x80000000)); |
| 579 LLAssert(llong(0x80000000, 0) <= llong(0x80000000, 1)); |
| 580 LLAssert(llong(0, 0x7fffffff) <= llong(1, 0)); |
| 581 LLAssert(llong(0, 0xffffffff) <= llong(1, 0)); |
| 582 LLAssert(llong(0x80000000, 1) <= llong(0, 0)); |
| 583 LLAssert(llong() <= llong(0, 0)); |
| 584 LLAssert(llong(1,0) <= llong(1, 0)); |
| 585 LLAssert(llong(0,1) <= llong(0, 1)); |
| 586 |
| 587 // operator==(int32) |
| 588 LLAssert(llong() == (int32_t)0); |
| 589 LLAssert(llong(0,1) == (int32_t)1); |
| 590 |
| 591 // operator!=(int32) |
| 592 LLAssert(llong(1,0) != (int32_t)0); |
| 593 LLAssert(llong(0,1) != (int32_t)2); |
| 594 LLAssert(llong(0,0xffffffff) != (int32_t)-1); |
| 595 |
| 596 llong negOne(0xffffffff, 0xffffffff); |
| 597 |
| 598 // operator>(int32) |
| 599 LLAssert(llong(0, 0x80000000) > (int32_t)0x7fffffff); |
| 600 LLAssert(negOne > (int32_t)-2); |
| 601 LLAssert(llong(1, 0) > (int32_t)0x7fffffff); |
| 602 LLAssert(llong(0, 0) > (int32_t)-1); |
| 603 |
| 604 // operator<(int32) |
| 605 LLAssert(llong(0, 0x7ffffffe) < (int32_t)0x7fffffff); |
| 606 LLAssert(llong(0xffffffff, 0xfffffffe) < (int32_t)-1); |
| 607 |
| 608 // operator>=(int32) |
| 609 LLAssert(llong(0, 0x80000000) >= (int32_t)0x7fffffff); |
| 610 LLAssert(negOne >= (int32_t)-2); |
| 611 LLAssert(llong(1, 0) >= (int32_t)0x7fffffff); |
| 612 LLAssert(llong(0, 0) >= (int32_t)-1); |
| 613 LLAssert(llong() >= (int32_t)0); |
| 614 LLAssert(llong(0,1) >= (int32_t)1); |
| 615 |
| 616 // operator<=(int32) |
| 617 LLAssert(llong(0, 0x7ffffffe) <= (int32_t)0x7fffffff); |
| 618 LLAssert(llong(0xffffffff, 0xfffffffe) <= (int32_t)-1); |
| 619 LLAssert(llong() <= (int32_t)0); |
| 620 LLAssert(llong(0,1) <= (int32_t)1); |
| 621 |
| 622 // operator= |
| 623 LLAssert((llong(2,3) = llong((uint32_t)-1)).asUInt() == (uint32_t)-1); |
| 624 |
| 625 // operator <<= |
| 626 LLAssert((llong(1, 1) <<= 0) == llong(1, 1)); |
| 627 LLAssert((llong(1, 1) <<= 31) == llong(0x80000000, 0x80000000)); |
| 628 LLAssert((llong(1, 1) <<= 32) == llong(1, 0)); |
| 629 LLAssert((llong(1, 1) <<= 63) == llong(0x80000000, 0)); |
| 630 LLAssert((llong(1, 1) <<= 64) == llong(1, 1)); // only lower 6 bits are used |
| 631 LLAssert((llong(1, 1) <<= -1) == llong(0x80000000, 0)); // only lower 6 bits
are used |
| 632 |
| 633 // operator << |
| 634 LLAssert((llong((int32_t)1) << 5).asUInt() == 32); |
| 635 |
| 636 // operator >>= (sign extended) |
| 637 LLAssert((llong(0x7fffa0a0, 0xbcbcdfdf) >>= 16) == llong(0x7fff,0xa0a0bcbc))
; |
| 638 LLAssert((llong(0x8000789a, 0xbcde0000) >>= 16) == llong(0xffff8000,0x789abc
de)); |
| 639 LLAssert((llong(0x80000000, 0) >>= 63) == llong(0xffffffff, 0xffffffff)); |
| 640 LLAssert((llong(0x80000000, 0) >>= 47) == llong(0xffffffff, 0xffff0000)); |
| 641 LLAssert((llong(0x80000000, 0x80000000) >> 64) == llong(0x80000000, 0x800000
00)); // only lower 6 bits are used |
| 642 LLAssert((llong(0x80000000, 0) >>= -1) == llong(0xffffffff, 0xffffffff)); //
only lower 6 bits are used |
| 643 |
| 644 // operator >> sign extended) |
| 645 LLAssert((llong(0x8000789a, 0xbcde0000) >> 16) == llong(0xffff8000,0x789abcd
e)); |
| 646 |
| 647 // ushr (right shift without sign extension) |
| 648 LLAssert(llong(0x7fffa0a0, 0xbcbcdfdf).ushr(16) == llong(0x7fff,0xa0a0bcbc))
; |
| 649 LLAssert(llong(0x8000789a, 0xbcde0000).ushr(16) == llong(0x00008000,0x789abc
de)); |
| 650 LLAssert(llong(0x80000000, 0).ushr(63) == llong(0, 1)); |
| 651 LLAssert(llong(0x80000000, 0).ushr(47) == llong(0, 0x10000)); |
| 652 LLAssert(llong(0x80000000, 0x80000000).ushr(64) == llong(0x80000000, 0x80000
000)); // only lower 6 bits are used |
| 653 LLAssert(llong(0x80000000, 0).ushr(-1) == llong(0, 1)); // only lower 6 bits
are used |
| 654 |
| 655 // operator&(llong) |
| 656 LLAssert((llong(0x55555555, 0x55555555) & llong(0xaaaaffff, 0xffffaaaa)) ==
llong(0x00005555, 0x55550000)); |
| 657 |
| 658 // operator|(llong) |
| 659 LLAssert((llong(0x55555555, 0x55555555) | llong(0xaaaaffff, 0xffffaaaa)) ==
llong(0xffffffff, 0xffffffff)); |
| 660 |
| 661 // operator^(llong) |
| 662 LLAssert((llong(0x55555555, 0x55555555) ^ llong(0xaaaaffff, 0xffffaaaa)) ==
llong(0xffffaaaa, 0xaaaaffff)); |
| 663 |
| 664 // operator&(uint32) |
| 665 LLAssert((llong(0x55555555, 0x55555555) & (uint32_t)0xffffaaaa) == llong(0,
0x55550000)); |
| 666 |
| 667 // operator|(uint32) |
| 668 LLAssert((llong(0x55555555, 0x55555555) | (uint32_t)0xffffaaaa) == llong(0x5
5555555, 0xffffffff)); |
| 669 |
| 670 // operator^(uint32) |
| 671 LLAssert((llong(0x55555555, 0x55555555) ^ (uint32_t)0xffffaaaa) == llong(0x5
5555555, 0xaaaaffff)); |
| 672 |
| 673 // operator~ |
| 674 LLAssert(~llong(0x55555555, 0x55555555) == llong(0xaaaaaaaa, 0xaaaaaaaa)); |
| 675 |
| 676 // operator&=(llong) |
| 677 LLAssert((llong(0x55555555, 0x55555555) &= llong(0xaaaaffff, 0xffffaaaa)) ==
llong(0x00005555, 0x55550000)); |
| 678 |
| 679 // operator|=(llong) |
| 680 LLAssert((llong(0x55555555, 0x55555555) |= llong(0xaaaaffff, 0xffffaaaa)) ==
llong(0xffffffff, 0xffffffff)); |
| 681 |
| 682 // operator^=(llong) |
| 683 LLAssert((llong(0x55555555, 0x55555555) ^= llong(0xaaaaffff, 0xffffaaaa)) ==
llong(0xffffaaaa, 0xaaaaffff)); |
| 684 |
| 685 // operator&=(uint32) |
| 686 LLAssert((llong(0x55555555, 0x55555555) &= (uint32_t)0xffffaaaa) == llong(0,
0x55550000)); |
| 687 |
| 688 // operator|=(uint32) |
| 689 LLAssert((llong(0x55555555, 0x55555555) |= (uint32_t)0xffffaaaa) == llong(0x
55555555, 0xffffffff)); |
| 690 |
| 691 // operator^=(uint32) |
| 692 LLAssert((llong(0x55555555, 0x55555555) ^= (uint32_t)0xffffaaaa) == llong(0x
55555555, 0xaaaaffff)); |
| 693 |
| 694 // prefix inc |
| 695 LLAssert(llong(1, 0) == ++llong(0,0xffffffff)); |
| 696 |
| 697 // prefix dec |
| 698 LLAssert(llong(0,0xffffffff) == --llong(1, 0)); |
| 699 |
| 700 // postfix inc |
| 701 { |
| 702 llong n(0, 0xffffffff); |
| 703 LLAssert(llong(0, 0xffffffff) == n++); |
| 704 LLAssert(llong(1, 0) == n); |
| 705 } |
| 706 |
| 707 // postfix dec |
| 708 { |
| 709 llong n(1, 0); |
| 710 LLAssert(llong(1, 0) == n--); |
| 711 LLAssert(llong(0, 0xffffffff) == n); |
| 712 } |
| 713 |
| 714 // unary minus |
| 715 LLAssert(llong(0, 0) == -llong(0, 0)); |
| 716 LLAssert(llong(0xffffffff, 0xffffffff) == -llong(0, 1)); |
| 717 LLAssert(llong(0, 1) == -llong(0xffffffff, 0xffffffff)); |
| 718 LLAssert(llong(0x7fffffff, 0xffffffff) == -llong(0x80000000, 1)); |
| 719 LLAssert(llong(0x80000000, 0) == -llong(0x80000000, 0)); // !!! we don't han
dle overflow |
| 720 |
| 721 // operator-= |
| 722 { |
| 723 llong n; |
| 724 LLAssert((n -= llong(0, 1)) == llong(0xffffffff, 0xffffffff)); |
| 725 LLAssert(n == llong(0xffffffff, 0xffffffff)); |
| 726 |
| 727 n = llong(1, 0); |
| 728 LLAssert((n -= llong(0, 1)) == llong(0, 0xffffffff)); |
| 729 LLAssert(n == llong(0, 0xffffffff)); |
| 730 } |
| 731 |
| 732 // operator- |
| 733 { |
| 734 llong n; |
| 735 LLAssert((n - llong(0, 1)) == llong(0xffffffff, 0xffffffff)); |
| 736 LLAssert(n == llong(0, 0)); |
| 737 |
| 738 n = llong(1, 0); |
| 739 LLAssert((n - llong(0, 1)) == llong(0, 0xffffffff)); |
| 740 LLAssert(n == llong(1, 0)); |
| 741 } |
| 742 |
| 743 // operator+= |
| 744 { |
| 745 llong n(0xffffffff, 0xffffffff); |
| 746 LLAssert((n += llong(0, 1)) == llong(0, 0)); |
| 747 LLAssert(n == llong(0, 0)); |
| 748 |
| 749 n = llong(0, 0xffffffff); |
| 750 LLAssert((n += llong(0, 1)) == llong(1, 0)); |
| 751 LLAssert(n == llong(1, 0)); |
| 752 } |
| 753 |
| 754 // operator+ |
| 755 { |
| 756 llong n(0xffffffff, 0xffffffff); |
| 757 LLAssert((n + llong(0, 1)) == llong(0, 0)); |
| 758 LLAssert(n == llong(0xffffffff, 0xffffffff)); |
| 759 |
| 760 n = llong(0, 0xffffffff); |
| 761 LLAssert((n + llong(0, 1)) == llong(1, 0)); |
| 762 LLAssert(n == llong(0, 0xffffffff)); |
| 763 } |
| 764 |
| 765 } |
| 766 |
| 767 void IntlTestRBNF::TestLLong() |
| 768 { |
| 769 logln("Starting TestLLong"); |
| 770 |
| 771 TestLLongConstructors(); |
| 772 |
| 773 TestLLongSimpleOperators(); |
| 774 |
| 775 logln("Testing operator*=, operator*"); |
| 776 |
| 777 // operator*=, operator* |
| 778 // small and large values, positive, &NEGative, zero |
| 779 // also test commutivity |
| 780 { |
| 781 const llong ZERO; |
| 782 const llong ONE(0, 1); |
| 783 const llong NEG_ONE((int32_t)-1); |
| 784 const llong THREE(0, 3); |
| 785 const llong NEG_THREE((int32_t)-3); |
| 786 const llong TWO_TO_16(0, 0x10000); |
| 787 const llong NEG_TWO_TO_16 = -TWO_TO_16; |
| 788 const llong TWO_TO_32(1, 0); |
| 789 const llong NEG_TWO_TO_32 = -TWO_TO_32; |
| 790 |
| 791 const llong NINE(0, 9); |
| 792 const llong NEG_NINE = -NINE; |
| 793 |
| 794 const llong TWO_TO_16X3(0, 0x00030000); |
| 795 const llong NEG_TWO_TO_16X3 = -TWO_TO_16X3; |
| 796 |
| 797 const llong TWO_TO_32X3(3, 0); |
| 798 const llong NEG_TWO_TO_32X3 = -TWO_TO_32X3; |
| 799 |
| 800 const llong TWO_TO_48(0x10000, 0); |
| 801 const llong NEG_TWO_TO_48 = -TWO_TO_48; |
| 802 |
| 803 const int32_t VALUE_WIDTH = 9; |
| 804 const llong* values[VALUE_WIDTH] = { |
| 805 &ZERO, &ONE, &NEG_ONE, &THREE, &NEG_THREE, &TWO_TO_16, &NEG_TWO_TO_1
6, &TWO_TO_32, &NEG_TWO_TO_32 |
| 806 }; |
| 807 |
| 808 const llong* answers[VALUE_WIDTH*VALUE_WIDTH] = { |
| 809 &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, |
| 810 &ZERO, &ONE, &NEG_ONE, &THREE, &NEG_THREE, &TWO_TO_16, &NEG_TWO_TO
_16, &TWO_TO_32, &NEG_TWO_TO_32, |
| 811 &ZERO, &NEG_ONE, &ONE, &NEG_THREE, &THREE, &NEG_TWO_TO_16, &TWO_TO_1
6, &NEG_TWO_TO_32, &TWO_TO_32, |
| 812 &ZERO, &THREE, &NEG_THREE, &NINE, &NEG_NINE, &TWO_TO_16X3, &NEG_TWO_
TO_16X3, &TWO_TO_32X3, &NEG_TWO_TO_32X3, |
| 813 &ZERO, &NEG_THREE, &THREE, &NEG_NINE, &NINE, &NEG_TWO_TO_16X3, &TWO_
TO_16X3, &NEG_TWO_TO_32X3, &TWO_TO_32X3, |
| 814 &ZERO, &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_16X3, &NEG_TWO_TO_16X3, &
TWO_TO_32, &NEG_TWO_TO_32, &TWO_TO_48, &NEG_TWO_TO_48, |
| 815 &ZERO, &NEG_TWO_TO_16, &TWO_TO_16, &NEG_TWO_TO_16X3, &TWO_TO_16X3, &
NEG_TWO_TO_32, &TWO_TO_32, &NEG_TWO_TO_48, &TWO_TO_48, |
| 816 &ZERO, &TWO_TO_32, &NEG_TWO_TO_32, &TWO_TO_32X3, &NEG_TWO_TO_32X3, &
TWO_TO_48, &NEG_TWO_TO_48, &ZERO, &ZERO, |
| 817 &ZERO, &NEG_TWO_TO_32, &TWO_TO_32, &NEG_TWO_TO_32X3, &TWO_TO_32X3, &
NEG_TWO_TO_48, &TWO_TO_48, &ZERO, &ZERO |
| 818 }; |
| 819 |
| 820 for (int i = 0; i < VALUE_WIDTH; ++i) { |
| 821 for (int j = 0; j < VALUE_WIDTH; ++j) { |
| 822 llong lhs = *values[i]; |
| 823 llong rhs = *values[j]; |
| 824 llong ans = *answers[i*VALUE_WIDTH + j]; |
| 825 |
| 826 llong n = lhs; |
| 827 |
| 828 LLAssert((n *= rhs) == ans); |
| 829 LLAssert(n == ans); |
| 830 |
| 831 n = lhs; |
| 832 LLAssert((n * rhs) == ans); |
| 833 LLAssert(n == lhs); |
| 834 } |
| 835 } |
| 836 } |
| 837 |
| 838 logln("Testing operator/=, operator/"); |
| 839 // operator/=, operator/ |
| 840 // test num = 0, div = 0, pos/neg, > 2^32, div > num |
| 841 { |
| 842 const llong ZERO; |
| 843 const llong ONE(0, 1); |
| 844 const llong NEG_ONE = -ONE; |
| 845 const llong MAX(0x7fffffff, 0xffffffff); |
| 846 const llong MIN(0x80000000, 0); |
| 847 const llong TWO(0, 2); |
| 848 const llong NEG_TWO = -TWO; |
| 849 const llong FIVE(0, 5); |
| 850 const llong NEG_FIVE = -FIVE; |
| 851 const llong TWO_TO_32(1, 0); |
| 852 const llong NEG_TWO_TO_32 = -TWO_TO_32; |
| 853 const llong TWO_TO_32d5 = llong(TWO_TO_32.asDouble()/5.0); |
| 854 const llong NEG_TWO_TO_32d5 = -TWO_TO_32d5; |
| 855 const llong TWO_TO_32X5 = TWO_TO_32 * FIVE; |
| 856 const llong NEG_TWO_TO_32X5 = -TWO_TO_32X5; |
| 857 |
| 858 const llong* tuples[] = { // lhs, rhs, ans |
| 859 &ZERO, &ZERO, &ZERO, |
| 860 &ONE, &ZERO,&MAX, |
| 861 &NEG_ONE, &ZERO, &MIN, |
| 862 &ONE, &ONE, &ONE, |
| 863 &ONE, &NEG_ONE, &NEG_ONE, |
| 864 &NEG_ONE, &ONE, &NEG_ONE, |
| 865 &NEG_ONE, &NEG_ONE, &ONE, |
| 866 &FIVE, &TWO, &TWO, |
| 867 &FIVE, &NEG_TWO, &NEG_TWO, |
| 868 &NEG_FIVE, &TWO, &NEG_TWO, |
| 869 &NEG_FIVE, &NEG_TWO, &TWO, |
| 870 &TWO, &FIVE, &ZERO, |
| 871 &TWO, &NEG_FIVE, &ZERO, |
| 872 &NEG_TWO, &FIVE, &ZERO, |
| 873 &NEG_TWO, &NEG_FIVE, &ZERO, |
| 874 &TWO_TO_32, &TWO_TO_32, &ONE, |
| 875 &TWO_TO_32, &NEG_TWO_TO_32, &NEG_ONE, |
| 876 &NEG_TWO_TO_32, &TWO_TO_32, &NEG_ONE, |
| 877 &NEG_TWO_TO_32, &NEG_TWO_TO_32, &ONE, |
| 878 &TWO_TO_32, &FIVE, &TWO_TO_32d5, |
| 879 &TWO_TO_32, &NEG_FIVE, &NEG_TWO_TO_32d5, |
| 880 &NEG_TWO_TO_32, &FIVE, &NEG_TWO_TO_32d5, |
| 881 &NEG_TWO_TO_32, &NEG_FIVE, &TWO_TO_32d5, |
| 882 &TWO_TO_32X5, &FIVE, &TWO_TO_32, |
| 883 &TWO_TO_32X5, &NEG_FIVE, &NEG_TWO_TO_32, |
| 884 &NEG_TWO_TO_32X5, &FIVE, &NEG_TWO_TO_32, |
| 885 &NEG_TWO_TO_32X5, &NEG_FIVE, &TWO_TO_32, |
| 886 &TWO_TO_32X5, &TWO_TO_32, &FIVE, |
| 887 &TWO_TO_32X5, &NEG_TWO_TO_32, &NEG_FIVE, |
| 888 &NEG_TWO_TO_32X5, &NEG_TWO_TO_32, &FIVE, |
| 889 &NEG_TWO_TO_32X5, &TWO_TO_32, &NEG_FIVE |
| 890 }; |
| 891 const int TUPLE_WIDTH = 3; |
| 892 const int TUPLE_COUNT = (int)(sizeof(tuples)/sizeof(tuples[0]))/TUPLE_WI
DTH; |
| 893 for (int i = 0; i < TUPLE_COUNT; ++i) { |
| 894 const llong lhs = *tuples[i*TUPLE_WIDTH+0]; |
| 895 const llong rhs = *tuples[i*TUPLE_WIDTH+1]; |
| 896 const llong ans = *tuples[i*TUPLE_WIDTH+2]; |
| 897 |
| 898 llong n = lhs; |
| 899 if (!((n /= rhs) == ans)) { |
| 900 errln("fail: (n /= rhs) == ans"); |
| 901 } |
| 902 LLAssert(n == ans); |
| 903 |
| 904 n = lhs; |
| 905 LLAssert((n / rhs) == ans); |
| 906 LLAssert(n == lhs); |
| 907 } |
| 908 } |
| 909 |
| 910 logln("Testing operator%%=, operator%%"); |
| 911 //operator%=, operator% |
| 912 { |
| 913 const llong ZERO; |
| 914 const llong ONE(0, 1); |
| 915 const llong TWO(0, 2); |
| 916 const llong THREE(0,3); |
| 917 const llong FOUR(0, 4); |
| 918 const llong FIVE(0, 5); |
| 919 const llong SIX(0, 6); |
| 920 |
| 921 const llong NEG_ONE = -ONE; |
| 922 const llong NEG_TWO = -TWO; |
| 923 const llong NEG_THREE = -THREE; |
| 924 const llong NEG_FOUR = -FOUR; |
| 925 const llong NEG_FIVE = -FIVE; |
| 926 const llong NEG_SIX = -SIX; |
| 927 |
| 928 const llong NINETY_NINE(0, 99); |
| 929 const llong HUNDRED(0, 100); |
| 930 const llong HUNDRED_ONE(0, 101); |
| 931 |
| 932 const llong BIG(0x12345678, 0x9abcdef0); |
| 933 const llong BIG_FIVE(BIG * FIVE); |
| 934 const llong BIG_FIVEm1 = BIG_FIVE - ONE; |
| 935 const llong BIG_FIVEp1 = BIG_FIVE + ONE; |
| 936 |
| 937 const llong* tuples[] = { |
| 938 &ZERO, &FIVE, &ZERO, |
| 939 &ONE, &FIVE, &ONE, |
| 940 &TWO, &FIVE, &TWO, |
| 941 &THREE, &FIVE, &THREE, |
| 942 &FOUR, &FIVE, &FOUR, |
| 943 &FIVE, &FIVE, &ZERO, |
| 944 &SIX, &FIVE, &ONE, |
| 945 &ZERO, &NEG_FIVE, &ZERO, |
| 946 &ONE, &NEG_FIVE, &ONE, |
| 947 &TWO, &NEG_FIVE, &TWO, |
| 948 &THREE, &NEG_FIVE, &THREE, |
| 949 &FOUR, &NEG_FIVE, &FOUR, |
| 950 &FIVE, &NEG_FIVE, &ZERO, |
| 951 &SIX, &NEG_FIVE, &ONE, |
| 952 &NEG_ONE, &FIVE, &NEG_ONE, |
| 953 &NEG_TWO, &FIVE, &NEG_TWO, |
| 954 &NEG_THREE, &FIVE, &NEG_THREE, |
| 955 &NEG_FOUR, &FIVE, &NEG_FOUR, |
| 956 &NEG_FIVE, &FIVE, &ZERO, |
| 957 &NEG_SIX, &FIVE, &NEG_ONE, |
| 958 &NEG_ONE, &NEG_FIVE, &NEG_ONE, |
| 959 &NEG_TWO, &NEG_FIVE, &NEG_TWO, |
| 960 &NEG_THREE, &NEG_FIVE, &NEG_THREE, |
| 961 &NEG_FOUR, &NEG_FIVE, &NEG_FOUR, |
| 962 &NEG_FIVE, &NEG_FIVE, &ZERO, |
| 963 &NEG_SIX, &NEG_FIVE, &NEG_ONE, |
| 964 &NINETY_NINE, &FIVE, &FOUR, |
| 965 &HUNDRED, &FIVE, &ZERO, |
| 966 &HUNDRED_ONE, &FIVE, &ONE, |
| 967 &BIG_FIVEm1, &FIVE, &FOUR, |
| 968 &BIG_FIVE, &FIVE, &ZERO, |
| 969 &BIG_FIVEp1, &FIVE, &ONE |
| 970 }; |
| 971 const int TUPLE_WIDTH = 3; |
| 972 const int TUPLE_COUNT = (int)(sizeof(tuples)/sizeof(tuples[0]))/TUPLE_WI
DTH; |
| 973 for (int i = 0; i < TUPLE_COUNT; ++i) { |
| 974 const llong lhs = *tuples[i*TUPLE_WIDTH+0]; |
| 975 const llong rhs = *tuples[i*TUPLE_WIDTH+1]; |
| 976 const llong ans = *tuples[i*TUPLE_WIDTH+2]; |
| 977 |
| 978 llong n = lhs; |
| 979 if (!((n %= rhs) == ans)) { |
| 980 errln("fail: (n %= rhs) == ans"); |
| 981 } |
| 982 LLAssert(n == ans); |
| 983 |
| 984 n = lhs; |
| 985 LLAssert((n % rhs) == ans); |
| 986 LLAssert(n == lhs); |
| 987 } |
| 988 } |
| 989 |
| 990 logln("Testing pow"); |
| 991 // pow |
| 992 LLAssert(llong(0, 0).pow(0) == llong(0, 0)); |
| 993 LLAssert(llong(0, 0).pow(2) == llong(0, 0)); |
| 994 LLAssert(llong(0, 2).pow(0) == llong(0, 1)); |
| 995 LLAssert(llong(0, 2).pow(2) == llong(0, 4)); |
| 996 LLAssert(llong(0, 2).pow(32) == llong(1, 0)); |
| 997 LLAssert(llong(0, 5).pow(10) == llong((double)5.0 * 5 * 5 * 5 * 5 * 5 * 5 *
5 * 5 * 5)); |
| 998 |
| 999 // absolute value |
| 1000 { |
| 1001 const llong n(0xffffffff,0xffffffff); |
| 1002 LLAssert(n.abs() == llong(0, 1)); |
| 1003 } |
| 1004 |
| 1005 #ifdef RBNF_DEBUG |
| 1006 logln("Testing atoll"); |
| 1007 // atoll |
| 1008 const char empty[] = ""; |
| 1009 const char zero[] = "0"; |
| 1010 const char neg_one[] = "-1"; |
| 1011 const char neg_12345[] = "-12345"; |
| 1012 const char big1[] = "123456789abcdef0"; |
| 1013 const char big2[] = "fFfFfFfFfFfFfFfF"; |
| 1014 LLAssert(llong::atoll(empty) == llong(0, 0)); |
| 1015 LLAssert(llong::atoll(zero) == llong(0, 0)); |
| 1016 LLAssert(llong::atoll(neg_one) == llong(0xffffffff, 0xffffffff)); |
| 1017 LLAssert(llong::atoll(neg_12345) == -llong(0, 12345)); |
| 1018 LLAssert(llong::atoll(big1, 16) == llong(0x12345678, 0x9abcdef0)); |
| 1019 LLAssert(llong::atoll(big2, 16) == llong(0xffffffff, 0xffffffff)); |
| 1020 #endif |
| 1021 |
| 1022 // u_atoll |
| 1023 const UChar uempty[] = { 0 }; |
| 1024 const UChar uzero[] = { 0x30, 0 }; |
| 1025 const UChar uneg_one[] = { 0x2d, 0x31, 0 }; |
| 1026 const UChar uneg_12345[] = { 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0 }; |
| 1027 const UChar ubig1[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0 }; |
| 1028 const UChar ubig2[] = { 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66
, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0 }; |
| 1029 LLAssert(llong::utoll(uempty) == llong(0, 0)); |
| 1030 LLAssert(llong::utoll(uzero) == llong(0, 0)); |
| 1031 LLAssert(llong::utoll(uneg_one) == llong(0xffffffff, 0xffffffff)); |
| 1032 LLAssert(llong::utoll(uneg_12345) == -llong(0, 12345)); |
| 1033 LLAssert(llong::utoll(ubig1, 16) == llong(0x12345678, 0x9abcdef0)); |
| 1034 LLAssert(llong::utoll(ubig2, 16) == llong(0xffffffff, 0xffffffff)); |
| 1035 |
| 1036 #ifdef RBNF_DEBUG |
| 1037 logln("Testing lltoa"); |
| 1038 // lltoa |
| 1039 { |
| 1040 char buf[64]; // ascii |
| 1041 LLAssert((llong(0, 0).lltoa(buf, (uint32_t)sizeof(buf)) == 1) && (strcmp
(buf, zero) == 0)); |
| 1042 LLAssert((llong(0xffffffff, 0xffffffff).lltoa(buf, (uint32_t)sizeof(buf)
) == 2) && (strcmp(buf, neg_one) == 0)); |
| 1043 LLAssert(((-llong(0, 12345)).lltoa(buf, (uint32_t)sizeof(buf)) == 6) &&
(strcmp(buf, neg_12345) == 0)); |
| 1044 LLAssert((llong(0x12345678, 0x9abcdef0).lltoa(buf, (uint32_t)sizeof(buf)
, 16) == 16) && (strcmp(buf, big1) == 0)); |
| 1045 } |
| 1046 #endif |
| 1047 |
| 1048 logln("Testing u_lltoa"); |
| 1049 // u_lltoa |
| 1050 { |
| 1051 UChar buf[64]; |
| 1052 LLAssert((llong(0, 0).lltou(buf, (uint32_t)sizeof(buf)) == 1) && (u_strc
mp(buf, uzero) == 0)); |
| 1053 LLAssert((llong(0xffffffff, 0xffffffff).lltou(buf, (uint32_t)sizeof(buf)
) == 2) && (u_strcmp(buf, uneg_one) == 0)); |
| 1054 LLAssert(((-llong(0, 12345)).lltou(buf, (uint32_t)sizeof(buf)) == 6) &&
(u_strcmp(buf, uneg_12345) == 0)); |
| 1055 LLAssert((llong(0x12345678, 0x9abcdef0).lltou(buf, (uint32_t)sizeof(buf)
, 16) == 16) && (u_strcmp(buf, ubig1) == 0)); |
| 1056 } |
| 1057 } |
| 1058 |
| 1059 /* if 0 */ |
| 1060 #endif |
| 1061 |
| 1062 void |
| 1063 IntlTestRBNF::TestEnglishSpellout() |
| 1064 { |
| 1065 UErrorCode status = U_ZERO_ERROR; |
| 1066 RuleBasedNumberFormat* formatter |
| 1067 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status); |
| 1068 if (U_FAILURE(status)) { |
| 1069 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1070 } else { |
| 1071 static const char* const testData[][2] = { |
| 1072 { "1", "one" }, |
| 1073 { "2", "two" }, |
| 1074 { "15", "fifteen" }, |
| 1075 { "20", "twenty" }, |
| 1076 { "23", "twenty-three" }, |
| 1077 { "73", "seventy-three" }, |
| 1078 { "88", "eighty-eight" }, |
| 1079 { "100", "one hundred" }, |
| 1080 { "106", "one hundred six" }, |
| 1081 { "127", "one hundred twenty-seven" }, |
| 1082 { "200", "two hundred" }, |
| 1083 { "579", "five hundred seventy-nine" }, |
| 1084 { "1,000", "one thousand" }, |
| 1085 { "2,000", "two thousand" }, |
| 1086 { "3,004", "three thousand four" }, |
| 1087 { "4,567", "four thousand five hundred sixty-seven" }, |
| 1088 { "15,943", "fifteen thousand nine hundred forty-three" }, |
| 1089 { "2,345,678", "two million three hundred forty-five thousand six hu
ndred seventy-eight" }, |
| 1090 { "-36", "minus thirty-six" }, |
| 1091 { "234.567", "two hundred thirty-four point five six seven" }, |
| 1092 { NULL, NULL} |
| 1093 }; |
| 1094 |
| 1095 doTest(formatter, testData, TRUE); |
| 1096 |
| 1097 #if !UCONFIG_NO_COLLATION |
| 1098 formatter->setLenient(TRUE); |
| 1099 static const char* lpTestData[][2] = { |
| 1100 { "fifty-7", "57" }, |
| 1101 { " fifty-7", "57" }, |
| 1102 { " fifty-7", "57" }, |
| 1103 { "2 thousand six HUNDRED fifty-7", "2,657" }, |
| 1104 { "fifteen hundred and zero", "1,500" }, |
| 1105 { "FOurhundred thiRTY six", "436" }, |
| 1106 { NULL, NULL} |
| 1107 }; |
| 1108 doLenientParseTest(formatter, lpTestData); |
| 1109 #endif |
| 1110 } |
| 1111 delete formatter; |
| 1112 } |
| 1113 |
| 1114 void |
| 1115 IntlTestRBNF::TestOrdinalAbbreviations() |
| 1116 { |
| 1117 UErrorCode status = U_ZERO_ERROR; |
| 1118 RuleBasedNumberFormat* formatter |
| 1119 = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale::getUS(), status); |
| 1120 |
| 1121 if (U_FAILURE(status)) { |
| 1122 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1123 } else { |
| 1124 static const char* const testData[][2] = { |
| 1125 { "1", "1\\u02e2\\u1d57" }, |
| 1126 { "2", "2\\u207f\\u1d48" }, |
| 1127 { "3", "3\\u02b3\\u1d48" }, |
| 1128 { "4", "4\\u1d57\\u02b0" }, |
| 1129 { "7", "7\\u1d57\\u02b0" }, |
| 1130 { "10", "10\\u1d57\\u02b0" }, |
| 1131 { "11", "11\\u1d57\\u02b0" }, |
| 1132 { "13", "13\\u1d57\\u02b0" }, |
| 1133 { "20", "20\\u1d57\\u02b0" }, |
| 1134 { "21", "21\\u02e2\\u1d57" }, |
| 1135 { "22", "22\\u207f\\u1d48" }, |
| 1136 { "23", "23\\u02b3\\u1d48" }, |
| 1137 { "24", "24\\u1d57\\u02b0" }, |
| 1138 { "33", "33\\u02b3\\u1d48" }, |
| 1139 { "102", "102\\u207f\\u1d48" }, |
| 1140 { "312", "312\\u1d57\\u02b0" }, |
| 1141 { "12,345", "12,345\\u1d57\\u02b0" }, |
| 1142 { NULL, NULL} |
| 1143 }; |
| 1144 |
| 1145 doTest(formatter, testData, FALSE); |
| 1146 } |
| 1147 delete formatter; |
| 1148 } |
| 1149 |
| 1150 void |
| 1151 IntlTestRBNF::TestDurations() |
| 1152 { |
| 1153 UErrorCode status = U_ZERO_ERROR; |
| 1154 RuleBasedNumberFormat* formatter |
| 1155 = new RuleBasedNumberFormat(URBNF_DURATION, Locale::getUS(), status); |
| 1156 |
| 1157 if (U_FAILURE(status)) { |
| 1158 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1159 } else { |
| 1160 static const char* const testData[][2] = { |
| 1161 { "3,600", "1:00:00" }, //move me and I fail |
| 1162 { "0", "0 sec." }, |
| 1163 { "1", "1 sec." }, |
| 1164 { "24", "24 sec." }, |
| 1165 { "60", "1:00" }, |
| 1166 { "73", "1:13" }, |
| 1167 { "145", "2:25" }, |
| 1168 { "666", "11:06" }, |
| 1169 // { "3,600", "1:00:00" }, |
| 1170 { "3,740", "1:02:20" }, |
| 1171 { "10,293", "2:51:33" }, |
| 1172 { NULL, NULL} |
| 1173 }; |
| 1174 |
| 1175 doTest(formatter, testData, TRUE); |
| 1176 |
| 1177 #if !UCONFIG_NO_COLLATION |
| 1178 formatter->setLenient(TRUE); |
| 1179 static const char* lpTestData[][2] = { |
| 1180 { "2-51-33", "10,293" }, |
| 1181 { NULL, NULL} |
| 1182 }; |
| 1183 doLenientParseTest(formatter, lpTestData); |
| 1184 #endif |
| 1185 } |
| 1186 delete formatter; |
| 1187 } |
| 1188 |
| 1189 void |
| 1190 IntlTestRBNF::TestSpanishSpellout() |
| 1191 { |
| 1192 UErrorCode status = U_ZERO_ERROR; |
| 1193 RuleBasedNumberFormat* formatter |
| 1194 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("es", "ES", ""), stat
us); |
| 1195 |
| 1196 if (U_FAILURE(status)) { |
| 1197 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1198 } else { |
| 1199 static const char* const testData[][2] = { |
| 1200 { "1", "uno" }, |
| 1201 { "6", "seis" }, |
| 1202 { "16", "diecis\\u00e9is" }, |
| 1203 { "20", "veinte" }, |
| 1204 { "24", "veinticuatro" }, |
| 1205 { "26", "veintis\\u00e9is" }, |
| 1206 { "73", "setenta y tres" }, |
| 1207 { "88", "ochenta y ocho" }, |
| 1208 { "100", "cien" }, |
| 1209 { "106", "ciento seis" }, |
| 1210 { "127", "ciento veintisiete" }, |
| 1211 { "200", "doscientos" }, |
| 1212 { "579", "quinientos setenta y nueve" }, |
| 1213 { "1,000", "mil" }, |
| 1214 { "2,000", "dos mil" }, |
| 1215 { "3,004", "tres mil cuatro" }, |
| 1216 { "4,567", "cuatro mil quinientos sesenta y siete" }, |
| 1217 { "15,943", "quince mil novecientos cuarenta y tres" }, |
| 1218 { "2,345,678", "dos millones trescientos cuarenta y cinco mil seisci
entos setenta y ocho"}, |
| 1219 { "-36", "menos treinta y seis" }, |
| 1220 { "234.567", "doscientos treinta y cuatro coma cinco seis siete" }, |
| 1221 { NULL, NULL} |
| 1222 }; |
| 1223 |
| 1224 doTest(formatter, testData, TRUE); |
| 1225 } |
| 1226 delete formatter; |
| 1227 } |
| 1228 |
| 1229 void |
| 1230 IntlTestRBNF::TestFrenchSpellout() |
| 1231 { |
| 1232 UErrorCode status = U_ZERO_ERROR; |
| 1233 RuleBasedNumberFormat* formatter |
| 1234 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getFrance(), status)
; |
| 1235 |
| 1236 if (U_FAILURE(status)) { |
| 1237 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1238 } else { |
| 1239 static const char* const testData[][2] = { |
| 1240 { "1", "un" }, |
| 1241 { "15", "quinze" }, |
| 1242 { "20", "vingt" }, |
| 1243 { "21", "vingt-et-un" }, |
| 1244 { "23", "vingt-trois" }, |
| 1245 { "62", "soixante-deux" }, |
| 1246 { "70", "soixante-dix" }, |
| 1247 { "71", "soixante-et-onze" }, |
| 1248 { "73", "soixante-treize" }, |
| 1249 { "80", "quatre-vingts" }, |
| 1250 { "88", "quatre-vingt-huit" }, |
| 1251 { "100", "cent" }, |
| 1252 { "106", "cent-six" }, |
| 1253 { "127", "cent-vingt-sept" }, |
| 1254 { "200", "deux-cents" }, |
| 1255 { "579", "cinq-cent-soixante-dix-neuf" }, |
| 1256 { "1,000", "mille" }, |
| 1257 { "1,123", "mille-cent-vingt-trois" }, |
| 1258 { "1,594", "mille-cinq-cent-quatre-vingt-quatorze" }, |
| 1259 { "2,000", "deux-mille" }, |
| 1260 { "3,004", "trois-mille-quatre" }, |
| 1261 { "4,567", "quatre-mille-cinq-cent-soixante-sept" }, |
| 1262 { "15,943", "quinze-mille-neuf-cent-quarante-trois" }, |
| 1263 { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-six-cen
t-soixante-dix-huit" }, |
| 1264 { "-36", "moins trente-six" }, |
| 1265 { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }, |
| 1266 { NULL, NULL} |
| 1267 }; |
| 1268 |
| 1269 doTest(formatter, testData, TRUE); |
| 1270 |
| 1271 #if !UCONFIG_NO_COLLATION |
| 1272 formatter->setLenient(TRUE); |
| 1273 static const char* lpTestData[][2] = { |
| 1274 { "trente-et-un", "31" }, |
| 1275 { "un cent quatre vingt dix huit", "198" }, |
| 1276 { NULL, NULL} |
| 1277 }; |
| 1278 doLenientParseTest(formatter, lpTestData); |
| 1279 #endif |
| 1280 } |
| 1281 delete formatter; |
| 1282 } |
| 1283 |
| 1284 static const char* const swissFrenchTestData[][2] = { |
| 1285 { "1", "un" }, |
| 1286 { "15", "quinze" }, |
| 1287 { "20", "vingt" }, |
| 1288 { "21", "vingt-et-un" }, |
| 1289 { "23", "vingt-trois" }, |
| 1290 { "62", "soixante-deux" }, |
| 1291 { "70", "septante" }, |
| 1292 { "71", "septante-et-un" }, |
| 1293 { "73", "septante-trois" }, |
| 1294 { "80", "huitante" }, |
| 1295 { "88", "huitante-huit" }, |
| 1296 { "100", "cent" }, |
| 1297 { "106", "cent-six" }, |
| 1298 { "127", "cent-vingt-sept" }, |
| 1299 { "200", "deux-cents" }, |
| 1300 { "579", "cinq-cent-septante-neuf" }, |
| 1301 { "1,000", "mille" }, |
| 1302 { "1,123", "mille-cent-vingt-trois" }, |
| 1303 { "1,594", "mille-cinq-cent-nonante-quatre" }, |
| 1304 { "2,000", "deux-mille" }, |
| 1305 { "3,004", "trois-mille-quatre" }, |
| 1306 { "4,567", "quatre-mille-cinq-cent-soixante-sept" }, |
| 1307 { "15,943", "quinze-mille-neuf-cent-quarante-trois" }, |
| 1308 { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-six-cent-septan
te-huit" }, |
| 1309 { "-36", "moins trente-six" }, |
| 1310 { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }, |
| 1311 { NULL, NULL} |
| 1312 }; |
| 1313 |
| 1314 void |
| 1315 IntlTestRBNF::TestSwissFrenchSpellout() |
| 1316 { |
| 1317 UErrorCode status = U_ZERO_ERROR; |
| 1318 RuleBasedNumberFormat* formatter |
| 1319 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "CH", ""), stat
us); |
| 1320 |
| 1321 if (U_FAILURE(status)) { |
| 1322 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1323 } else { |
| 1324 doTest(formatter, swissFrenchTestData, TRUE); |
| 1325 } |
| 1326 delete formatter; |
| 1327 } |
| 1328 |
| 1329 static const char* const belgianFrenchTestData[][2] = { |
| 1330 { "1", "un" }, |
| 1331 { "15", "quinze" }, |
| 1332 { "20", "vingt" }, |
| 1333 { "21", "vingt-et-un" }, |
| 1334 { "23", "vingt-trois" }, |
| 1335 { "62", "soixante-deux" }, |
| 1336 { "70", "septante" }, |
| 1337 { "71", "septante-et-un" }, |
| 1338 { "73", "septante-trois" }, |
| 1339 { "80", "quatre-vingts" }, |
| 1340 { "88", "quatre-vingt-huit" }, |
| 1341 { "90", "nonante" }, |
| 1342 { "91", "nonante-et-un" }, |
| 1343 { "95", "nonante-cinq" }, |
| 1344 { "100", "cent" }, |
| 1345 { "106", "cent-six" }, |
| 1346 { "127", "cent-vingt-sept" }, |
| 1347 { "200", "deux-cents" }, |
| 1348 { "579", "cinq-cent-septante-neuf" }, |
| 1349 { "1,000", "mille" }, |
| 1350 { "1,123", "mille-cent-vingt-trois" }, |
| 1351 { "1,594", "mille-cinq-cent-nonante-quatre" }, |
| 1352 { "2,000", "deux-mille" }, |
| 1353 { "3,004", "trois-mille-quatre" }, |
| 1354 { "4,567", "quatre-mille-cinq-cent-soixante-sept" }, |
| 1355 { "15,943", "quinze-mille-neuf-cent-quarante-trois" }, |
| 1356 { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-six-cent-septan
te-huit" }, |
| 1357 { "-36", "moins trente-six" }, |
| 1358 { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }, |
| 1359 { NULL, NULL} |
| 1360 }; |
| 1361 |
| 1362 |
| 1363 void |
| 1364 IntlTestRBNF::TestBelgianFrenchSpellout() |
| 1365 { |
| 1366 UErrorCode status = U_ZERO_ERROR; |
| 1367 RuleBasedNumberFormat* formatter |
| 1368 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "BE", ""), stat
us); |
| 1369 |
| 1370 if (U_FAILURE(status)) { |
| 1371 errcheckln(status, "rbnf status: 0x%x (%s)\n", status, u_errorName(statu
s)); |
| 1372 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1373 } else { |
| 1374 // Belgian french should match Swiss french. |
| 1375 doTest(formatter, belgianFrenchTestData, TRUE); |
| 1376 } |
| 1377 delete formatter; |
| 1378 } |
| 1379 |
| 1380 void |
| 1381 IntlTestRBNF::TestItalianSpellout() |
| 1382 { |
| 1383 UErrorCode status = U_ZERO_ERROR; |
| 1384 RuleBasedNumberFormat* formatter |
| 1385 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getItalian(), status
); |
| 1386 |
| 1387 if (U_FAILURE(status)) { |
| 1388 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1389 } else { |
| 1390 static const char* const testData[][2] = { |
| 1391 { "1", "uno" }, |
| 1392 { "15", "quindici" }, |
| 1393 { "20", "venti" }, |
| 1394 { "23", "venti\\u00ADtr\\u00E9" }, |
| 1395 { "73", "settanta\\u00ADtr\\u00E9" }, |
| 1396 { "88", "ottant\\u00ADotto" }, |
| 1397 { "100", "cento" }, |
| 1398 { "101", "cent\\u00ADuno" }, |
| 1399 { "103", "cento\\u00ADtr\\u00E9" }, |
| 1400 { "106", "cento\\u00ADsei" }, |
| 1401 { "108", "cent\\u00ADotto" }, |
| 1402 { "127", "cento\\u00ADventi\\u00ADsette" }, |
| 1403 { "181", "cent\\u00ADottant\\u00ADuno" }, |
| 1404 { "200", "due\\u00ADcento" }, |
| 1405 { "579", "cinque\\u00ADcento\\u00ADsettanta\\u00ADnove" }, |
| 1406 { "1,000", "mille" }, |
| 1407 { "2,000", "due\\u00ADmila" }, |
| 1408 { "3,004", "tre\\u00ADmila\\u00ADquattro" }, |
| 1409 { "4,567", "quattro\\u00ADmila\\u00ADcinque\\u00ADcento\\u00ADsessan
ta\\u00ADsette" }, |
| 1410 { "15,943", "quindici\\u00ADmila\\u00ADnove\\u00ADcento\\u00ADquaran
ta\\u00ADtr\\u00E9" }, |
| 1411 { "-36", "meno trenta\\u00ADsei" }, |
| 1412 { "234.567", "due\\u00ADcento\\u00ADtrenta\\u00ADquattro virgola cin
que sei sette" }, |
| 1413 { NULL, NULL} |
| 1414 }; |
| 1415 |
| 1416 doTest(formatter, testData, TRUE); |
| 1417 } |
| 1418 delete formatter; |
| 1419 } |
| 1420 |
| 1421 void |
| 1422 IntlTestRBNF::TestPortugueseSpellout() |
| 1423 { |
| 1424 UErrorCode status = U_ZERO_ERROR; |
| 1425 RuleBasedNumberFormat* formatter |
| 1426 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("pt","BR",""), status
); |
| 1427 |
| 1428 if (U_FAILURE(status)) { |
| 1429 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1430 } else { |
| 1431 static const char* const testData[][2] = { |
| 1432 { "1", "um" }, |
| 1433 { "15", "quinze" }, |
| 1434 { "20", "vinte" }, |
| 1435 { "23", "vinte e tr\\u00EAs" }, |
| 1436 { "73", "setenta e tr\\u00EAs" }, |
| 1437 { "88", "oitenta e oito" }, |
| 1438 { "100", "cem" }, |
| 1439 { "106", "cento e seis" }, |
| 1440 { "108", "cento e oito" }, |
| 1441 { "127", "cento e vinte e sete" }, |
| 1442 { "181", "cento e oitenta e um" }, |
| 1443 { "200", "duzcentos" }, |
| 1444 { "579", "quinhentos e setenta e nove" }, |
| 1445 { "1,000", "mil" }, |
| 1446 { "2,000", "dois mil" }, |
| 1447 { "3,004", "tr\\u00EAs mil e quatro" }, |
| 1448 { "4,567", "quatro mil e quinhentos e sessenta e sete" }, |
| 1449 { "15,943", "quinze mil e novecentos e quarenta e tr\\u00EAs" }, |
| 1450 { "-36", "menos trinta e seis" }, |
| 1451 { "234.567", "duzcentos e trinta e quatro v\\u00EDrgula cinco seis s
ete" }, |
| 1452 { NULL, NULL} |
| 1453 }; |
| 1454 |
| 1455 doTest(formatter, testData, TRUE); |
| 1456 } |
| 1457 delete formatter; |
| 1458 } |
| 1459 void |
| 1460 IntlTestRBNF::TestGermanSpellout() |
| 1461 { |
| 1462 UErrorCode status = U_ZERO_ERROR; |
| 1463 RuleBasedNumberFormat* formatter |
| 1464 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getGermany(), status
); |
| 1465 |
| 1466 if (U_FAILURE(status)) { |
| 1467 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1468 } else { |
| 1469 static const char* const testData[][2] = { |
| 1470 { "1", "eins" }, |
| 1471 { "15", "f\\u00fcnfzehn" }, |
| 1472 { "20", "zwanzig" }, |
| 1473 { "23", "drei\\u00ADund\\u00ADzwanzig" }, |
| 1474 { "73", "drei\\u00ADund\\u00ADsiebzig" }, |
| 1475 { "88", "acht\\u00ADund\\u00ADachtzig" }, |
| 1476 { "100", "ein\\u00ADhundert" }, |
| 1477 { "106", "ein\\u00ADhundert\\u00ADsechs" }, |
| 1478 { "127", "ein\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADzwanzig" }, |
| 1479 { "200", "zwei\\u00ADhundert" }, |
| 1480 { "579", "f\\u00fcnf\\u00ADhundert\\u00ADneun\\u00ADund\\u00ADsiebzi
g" }, |
| 1481 { "1,000", "ein\\u00ADtausend" }, |
| 1482 { "2,000", "zwei\\u00ADtausend" }, |
| 1483 { "3,004", "drei\\u00ADtausend\\u00ADvier" }, |
| 1484 { "4,567", "vier\\u00ADtausend\\u00ADf\\u00fcnf\\u00ADhundert\\u00AD
sieben\\u00ADund\\u00ADsechzig" }, |
| 1485 { "15,943", "f\\u00fcnfzehn\\u00ADtausend\\u00ADneun\\u00ADhundert\\
u00ADdrei\\u00ADund\\u00ADvierzig" }, |
| 1486 { "2,345,678", "zwei Millionen drei\\u00ADhundert\\u00ADf\\u00fcnf\\
u00ADund\\u00ADvierzig\\u00ADtausend\\u00ADsechs\\u00ADhundert\\u00ADacht\\u00AD
und\\u00ADsiebzig" }, |
| 1487 { NULL, NULL} |
| 1488 }; |
| 1489 |
| 1490 doTest(formatter, testData, TRUE); |
| 1491 |
| 1492 #if !UCONFIG_NO_COLLATION |
| 1493 formatter->setLenient(TRUE); |
| 1494 static const char* lpTestData[][2] = { |
| 1495 { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }, |
| 1496 { NULL, NULL} |
| 1497 }; |
| 1498 doLenientParseTest(formatter, lpTestData); |
| 1499 #endif |
| 1500 } |
| 1501 delete formatter; |
| 1502 } |
| 1503 |
| 1504 void |
| 1505 IntlTestRBNF::TestThaiSpellout() |
| 1506 { |
| 1507 UErrorCode status = U_ZERO_ERROR; |
| 1508 RuleBasedNumberFormat* formatter |
| 1509 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("th"), status); |
| 1510 |
| 1511 if (U_FAILURE(status)) { |
| 1512 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1513 } else { |
| 1514 static const char* const testData[][2] = { |
| 1515 { "0", "\\u0e28\\u0e39\\u0e19\\u0e22\\u0e4c" }, |
| 1516 { "1", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" }, |
| 1517 { "10", "\\u0e2a\\u0e34\\u0e1a" }, |
| 1518 { "11", "\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" }
, |
| 1519 { "21", "\\u0e22\\u0e35\\u0e48\\u200b\\u0e2a\\u0e34\\u0e1a\\u200b\\u
0e40\\u0e2d\\u0e47\\u0e14" }, |
| 1520 { "101", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e23\\u0e49\\
u0e2d\\u0e22\\u200b\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" }, |
| 1521 { "1.234", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e08\\u0e38
\\u0e14\\u200b\\u0e2a\\u0e2d\\u0e07\\u0e2a\\u0e32\\u0e21\\u0e2a\\u0e35\\u0e48" }
, |
| 1522 { NULL, NULL} |
| 1523 }; |
| 1524 |
| 1525 doTest(formatter, testData, TRUE); |
| 1526 } |
| 1527 delete formatter; |
| 1528 } |
| 1529 |
| 1530 void |
| 1531 IntlTestRBNF::TestSwedishSpellout() |
| 1532 { |
| 1533 UErrorCode status = U_ZERO_ERROR; |
| 1534 RuleBasedNumberFormat* formatter |
| 1535 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("sv"), status); |
| 1536 |
| 1537 if (U_FAILURE(status)) { |
| 1538 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1539 } else { |
| 1540 static const char* testDataDefault[][2] = { |
| 1541 { "101", "ett\\u00adhundra\\u00adett" }, |
| 1542 { "123", "ett\\u00adhundra\\u00adtjugo\\u00adtre" }, |
| 1543 { "1,001", "et\\u00adtusen ett" }, |
| 1544 { "1,100", "et\\u00adtusen ett\\u00adhundra" }, |
| 1545 { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" }, |
| 1546 { "1,234", "et\\u00adtusen tv\\u00e5\\u00adhundra\\u00adtrettio\\u00
adfyra" }, |
| 1547 { "10,001", "tio\\u00adtusen ett" }, |
| 1548 { "11,000", "elva\\u00adtusen" }, |
| 1549 { "12,000", "tolv\\u00adtusen" }, |
| 1550 { "20,000", "tjugo\\u00adtusen" }, |
| 1551 { "21,000", "tjugo\\u00adet\\u00adtusen" }, |
| 1552 { "21,001", "tjugo\\u00adet\\u00adtusen ett" }, |
| 1553 { "200,000", "tv\\u00e5\\u00adhundra\\u00adtusen" }, |
| 1554 { "201,000", "tv\\u00e5\\u00adhundra\\u00adet\\u00adtusen" }, |
| 1555 { "200,200", "tv\\u00e5\\u00adhundra\\u00adtusen tv\\u00e5\\u00adhun
dra" }, |
| 1556 { "2,002,000", "tv\\u00e5 miljoner tv\\u00e5\\u00adtusen" }, |
| 1557 { "12,345,678", "tolv miljoner tre\\u00adhundra\\u00adfyrtio\\u00adf
em\\u00adtusen sex\\u00adhundra\\u00adsjuttio\\u00ad\\u00e5tta" }, |
| 1558 { "123,456.789", "ett\\u00adhundra\\u00adtjugo\\u00adtre\\u00adtusen
fyra\\u00adhundra\\u00adfemtio\\u00adsex komma sju \\u00e5tta nio" }, |
| 1559 { "-12,345.678", "minus tolv\\u00adtusen tre\\u00adhundra\\u00adfyrt
io\\u00adfem komma sex sju \\u00e5tta" }, |
| 1560 { NULL, NULL } |
| 1561 }; |
| 1562 doTest(formatter, testDataDefault, TRUE); |
| 1563 |
| 1564 static const char* testDataNeutrum[][2] = { |
| 1565 { "101", "ett\\u00adhundra\\u00aden" }, |
| 1566 { "1,001", "ettusen en" }, |
| 1567 { "1,101", "ettusen ett\\u00adhundra\\u00aden" }, |
| 1568 { "10,001", "tio\\u00adtusen en" }, |
| 1569 { "21,001", "tjugo\\u00aden\\u00adtusen en" }, |
| 1570 { NULL, NULL } |
| 1571 }; |
| 1572 |
| 1573 formatter->setDefaultRuleSet("%spellout-cardinal-neutre", status); |
| 1574 if (U_SUCCESS(status)) { |
| 1575 logln(" testing spellout-cardinal-neutre rules"); |
| 1576 doTest(formatter, testDataNeutrum, TRUE); |
| 1577 } |
| 1578 else { |
| 1579 errln("Can't test spellout-cardinal-neutre rules"); |
| 1580 } |
| 1581 |
| 1582 static const char* testDataYear[][2] = { |
| 1583 { "101", "ett\\u00adhundra\\u00adett" }, |
| 1584 { "900", "nio\\u00adhundra" }, |
| 1585 { "1,001", "et\\u00adtusen ett" }, |
| 1586 { "1,100", "elva\\u00adhundra" }, |
| 1587 { "1,101", "elva\\u00adhundra\\u00adett" }, |
| 1588 { "1,234", "tolv\\u00adhundra\\u00adtrettio\\u00adfyra" }, |
| 1589 { "2,001", "tjugo\\u00adhundra\\u00adett" }, |
| 1590 { "10,001", "tio\\u00adtusen ett" }, |
| 1591 { NULL, NULL } |
| 1592 }; |
| 1593 |
| 1594 formatter->setDefaultRuleSet("%spellout-numbering-year", status); |
| 1595 if (U_SUCCESS(status)) { |
| 1596 logln("testing year rules"); |
| 1597 doTest(formatter, testDataYear, TRUE); |
| 1598 } |
| 1599 else { |
| 1600 errln("Can't test year rules"); |
| 1601 } |
| 1602 |
| 1603 } |
| 1604 delete formatter; |
| 1605 } |
| 1606 |
| 1607 void |
| 1608 IntlTestRBNF::TestSmallValues() |
| 1609 { |
| 1610 UErrorCode status = U_ZERO_ERROR; |
| 1611 RuleBasedNumberFormat* formatter |
| 1612 = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("en_US"), status); |
| 1613 |
| 1614 if (U_FAILURE(status)) { |
| 1615 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1616 } else { |
| 1617 static const char* const testDataDefault[][2] = { |
| 1618 { "0.001", "zero point zero zero one" }, |
| 1619 { "0.0001", "zero point zero zero zero one" }, |
| 1620 { "0.00001", "zero point zero zero zero zero one" }, |
| 1621 { "0.000001", "zero point zero zero zero zero zero one" }, |
| 1622 { "0.0000001", "zero point zero zero zero zero zero zero one" }, |
| 1623 { "0.00000001", "zero point zero zero zero zero zero zero zero one" }, |
| 1624 { "0.000000001", "zero point zero zero zero zero zero zero zero zero one
" }, |
| 1625 { "0.0000000001", "zero point zero zero zero zero zero zero zero zero ze
ro one" }, |
| 1626 { "0.00000000001", "zero point zero zero zero zero zero zero zero zero z
ero zero one" }, |
| 1627 { "0.000000000001", "zero point zero zero zero zero zero zero zero zero
zero zero zero one" }, |
| 1628 { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero
zero zero zero zero one" }, |
| 1629 { "0.00000000000001", "zero point zero zero zero zero zero zero zero zer
o zero zero zero zero zero one" }, |
| 1630 { "0.000000000000001", "zero point zero zero zero zero zero zero zero ze
ro zero zero zero zero zero zero one" }, |
| 1631 { "10,000,000.001", "ten million point zero zero one" }, |
| 1632 { "10,000,000.0001", "ten million point zero zero zero one" }, |
| 1633 { "10,000,000.00001", "ten million point zero zero zero zero one" }, |
| 1634 { "10,000,000.000001", "ten million point zero zero zero zero zero one"
}, |
| 1635 { "10,000,000.0000001", "ten million point zero zero zero zero zero zero
one" }, |
| 1636 // { "10,000,000.00000001", "ten million point zero zero zero zero zero z
ero zero one" }, |
| 1637 // { "10,000,000.000000002", "ten million point zero zero zero zero zero
zero zero zero two" }, |
| 1638 { "10,000,000", "ten million" }, |
| 1639 // { "1,234,567,890.0987654", "one billion, two hundred and thirty-four m
illion, five hundred and sixty-seven thousand, eight hundred and ninety point ze
ro nine eight seven six five four" }, |
| 1640 // { "123,456,789.9876543", "one hundred and twenty-three million, four h
undred and fifty-six thousand, seven hundred and eighty-nine point nine eight se
ven six five four three" }, |
| 1641 // { "12,345,678.87654321", "twelve million, three hundred and forty-five
thousand, six hundred and seventy-eight point eight seven six five four three t
wo one" }, |
| 1642 { "1,234,567.7654321", "one million two hundred thirty-four thousand fiv
e hundred sixty-seven point seven six five four three two one" }, |
| 1643 { "123,456.654321", "one hundred twenty-three thousand four hundred fift
y-six point six five four three two one" }, |
| 1644 { "12,345.54321", "twelve thousand three hundred forty-five point five f
our three two one" }, |
| 1645 { "1,234.4321", "one thousand two hundred thirty-four point four three t
wo one" }, |
| 1646 { "123.321", "one hundred twenty-three point three two one" }, |
| 1647 { "0.0000000011754944", "zero point zero zero zero zero zero zero zero z
ero one one seven five four nine four four" }, |
| 1648 { "0.000001175494351", "zero point zero zero zero zero zero one one seve
n five four nine four three five one" }, |
| 1649 { NULL, NULL } |
| 1650 }; |
| 1651 |
| 1652 doTest(formatter, testDataDefault, TRUE); |
| 1653 |
| 1654 delete formatter; |
| 1655 } |
| 1656 } |
| 1657 |
| 1658 void |
| 1659 IntlTestRBNF::TestLocalizations(void) |
| 1660 { |
| 1661 int i; |
| 1662 UnicodeString rules("%main:0:no;1:some;100:a lot;1000:tons;\n" |
| 1663 "%other:0:nada;1:yah, some;100:plenty;1000:more'n you'll ever need"); |
| 1664 |
| 1665 UErrorCode status = U_ZERO_ERROR; |
| 1666 UParseError perror; |
| 1667 RuleBasedNumberFormat formatter(rules, perror, status); |
| 1668 if (U_FAILURE(status)) { |
| 1669 errcheckln(status, "FAIL: could not construct formatter - %s", u_errorNa
me(status)); |
| 1670 } else { |
| 1671 { |
| 1672 static const char* const testData[][2] = { |
| 1673 { "0", "nada" }, |
| 1674 { "5", "yah, some" }, |
| 1675 { "423", "plenty" }, |
| 1676 { "12345", "more'n you'll ever need" }, |
| 1677 { NULL, NULL } |
| 1678 }; |
| 1679 doTest(&formatter, testData, FALSE); |
| 1680 } |
| 1681 |
| 1682 { |
| 1683 UnicodeString loc("<<%main, %other>,<en, Main, Other>,<fr, leMain, l
eOther>,<de, 'das Main', 'etwas anderes'>>"); |
| 1684 static const char* const testData[][2] = { |
| 1685 { "0", "no" }, |
| 1686 { "5", "some" }, |
| 1687 { "423", "a lot" }, |
| 1688 { "12345", "tons" }, |
| 1689 { NULL, NULL } |
| 1690 }; |
| 1691 RuleBasedNumberFormat formatter0(rules, loc, perror, status); |
| 1692 if (U_FAILURE(status)) { |
| 1693 errln("failed to build second formatter"); |
| 1694 } else { |
| 1695 doTest(&formatter0, testData, FALSE); |
| 1696 |
| 1697 { |
| 1698 // exercise localization info |
| 1699 Locale locale0("en__VALLEY@turkey=gobblegobble"); |
| 1700 Locale locale1("de_DE_FOO"); |
| 1701 Locale locale2("ja_JP"); |
| 1702 UnicodeString name = formatter0.getRuleSetName(0); |
| 1703 if ( formatter0.getRuleSetDisplayName(0, locale0) == "Main" |
| 1704 && formatter0.getRuleSetDisplayName(0, locale1) == "das Ma
in" |
| 1705 && formatter0.getRuleSetDisplayName(0, locale2) == "%main" |
| 1706 && formatter0.getRuleSetDisplayName(name, locale0) == "Mai
n" |
| 1707 && formatter0.getRuleSetDisplayName(name, locale1) == "das
Main" |
| 1708 && formatter0.getRuleSetDisplayName(name, locale2) == "%ma
in"){ |
| 1709 logln("getRuleSetDisplayName tested"); |
| 1710 }else { |
| 1711 errln("failed to getRuleSetDisplayName"); |
| 1712 } |
| 1713 } |
| 1714 |
| 1715 for (i = 0; i < formatter0.getNumberOfRuleSetDisplayNameLocales(
); ++i) { |
| 1716 Locale locale = formatter0.getRuleSetDisplayNameLocale(i, st
atus); |
| 1717 if (U_SUCCESS(status)) { |
| 1718 for (int j = 0; j < formatter0.getNumberOfRuleSetNames()
; ++j) { |
| 1719 UnicodeString name = formatter0.getRuleSetName(j); |
| 1720 UnicodeString lname = formatter0.getRuleSetDisplayNa
me(j, locale); |
| 1721 UnicodeString msg = locale.getName(); |
| 1722 msg.append(": "); |
| 1723 msg.append(name); |
| 1724 msg.append(" = "); |
| 1725 msg.append(lname); |
| 1726 logln(msg); |
| 1727 } |
| 1728 } |
| 1729 } |
| 1730 } |
| 1731 } |
| 1732 |
| 1733 { |
| 1734 static const char* goodLocs[] = { |
| 1735 "", // zero-length ok, same as providing no localization data |
| 1736 "<<>>", // no public rule sets ok |
| 1737 "<<%main>>", // no localizations ok |
| 1738 "<<%main,>,<en, Main,>>", // comma before close angle ok |
| 1739 "<<%main>,<en, ',<>\" '>>", // quotes everything until next quot
e |
| 1740 "<<%main>,<'en', \"it's ok\">>", // double quotes work too |
| 1741 " \n <\n <\n %main\n >\n , \t <\t en\t , \tfoo \t\t > \
n\n > \n ", // rule whitespace ok |
| 1742 }; |
| 1743 int32_t goodLocsLen = sizeof(goodLocs)/sizeof(goodLocs[0]); |
| 1744 |
| 1745 static const char* badLocs[] = { |
| 1746 " ", // non-zero length |
| 1747 "<>", // empty array |
| 1748 "<", // unclosed outer array |
| 1749 "<<", // unclosed inner array |
| 1750 "<<,>>", // unexpected comma |
| 1751 "<<''>>", // empty string |
| 1752 " x<<%main>>", // first non space char not open angle bracket |
| 1753 "<%main>", // missing inner array |
| 1754 "<<%main %other>>", // elements missing separating commma (space
s must be quoted) |
| 1755 "<<%main><en, Main>>", // arrays missing separating comma |
| 1756 "<<%main>,<en, main, foo>>", // too many elements in locale data |
| 1757 "<<%main>,<en>>", // too few elements in locale data |
| 1758 "<<<%main>>>", // unexpected open angle |
| 1759 "<<%main<>>>", // unexpected open angle |
| 1760 "<<%main, %other>,<en,,>>", // implicit empty strings |
| 1761 "<<%main>,<en,''>>", // empty string |
| 1762 "<<%main>, < en, '>>", // unterminated quote |
| 1763 "<<%main>, < en, \"<>>", // unterminated quote |
| 1764 "<<%main\">>", // quote in string |
| 1765 "<<%main'>>", // quote in string |
| 1766 "<<%main<>>", // open angle in string |
| 1767 "<<%main>> x", // extra non-space text at end |
| 1768 |
| 1769 }; |
| 1770 int32_t badLocsLen = sizeof(badLocs)/sizeof(badLocs[0]); |
| 1771 |
| 1772 for (i = 0; i < goodLocsLen; ++i) { |
| 1773 logln("[%d] '%s'", i, goodLocs[i]); |
| 1774 UErrorCode status = U_ZERO_ERROR; |
| 1775 UnicodeString loc(goodLocs[i]); |
| 1776 RuleBasedNumberFormat fmt(rules, loc, perror, status); |
| 1777 if (U_FAILURE(status)) { |
| 1778 errln("Failed parse of good localization string: '%s'", good
Locs[i]); |
| 1779 } |
| 1780 } |
| 1781 |
| 1782 for (i = 0; i < badLocsLen; ++i) { |
| 1783 logln("[%d] '%s'", i, badLocs[i]); |
| 1784 UErrorCode status = U_ZERO_ERROR; |
| 1785 UnicodeString loc(badLocs[i]); |
| 1786 RuleBasedNumberFormat fmt(rules, loc, perror, status); |
| 1787 if (U_SUCCESS(status)) { |
| 1788 errln("Successful parse of bad localization string: '%s'", b
adLocs[i]); |
| 1789 } |
| 1790 } |
| 1791 } |
| 1792 } |
| 1793 } |
| 1794 |
| 1795 void |
| 1796 IntlTestRBNF::TestAllLocales() |
| 1797 { |
| 1798 const char* names[] = { |
| 1799 " (spellout) ", |
| 1800 " (ordinal) ", |
| 1801 " (duration) " |
| 1802 }; |
| 1803 double numbers[] = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111}; |
| 1804 |
| 1805 // RBNF parse is extremely slow when lenient option is enabled. |
| 1806 // For non-exhaustive mode, we only test a few locales. |
| 1807 const char* parseLocales[] = {"en_US", "nl_NL", "be", NULL}; |
| 1808 |
| 1809 |
| 1810 int32_t count = 0; |
| 1811 const Locale* locales = Locale::getAvailableLocales(count); |
| 1812 for (int i = 0; i < count; ++i) { |
| 1813 const Locale* loc = &locales[i]; |
| 1814 UBool testParse = TRUE; |
| 1815 if (quick) { |
| 1816 testParse = FALSE; |
| 1817 for (int k = 0; parseLocales[k] != NULL; k++) { |
| 1818 if (strcmp(loc->getLanguage(), parseLocales[k]) == 0) { |
| 1819 testParse = TRUE; |
| 1820 break; |
| 1821 } |
| 1822 } |
| 1823 } |
| 1824 |
| 1825 for (int j = 0; j < 3; ++j) { |
| 1826 UErrorCode status = U_ZERO_ERROR; |
| 1827 RuleBasedNumberFormat* f = new RuleBasedNumberFormat((URBNFRuleSetTa
g)j, *loc, status); |
| 1828 if (U_FAILURE(status)) { |
| 1829 errln(UnicodeString(loc->getName()) + names[j] |
| 1830 + "ERROR could not instantiate -> " + u_errorName(status)); |
| 1831 continue; |
| 1832 } |
| 1833 #if !UCONFIG_NO_COLLATION |
| 1834 for (unsigned int numidx = 0; numidx < sizeof(numbers)/sizeof(double
); numidx++) { |
| 1835 double n = numbers[numidx]; |
| 1836 UnicodeString str; |
| 1837 f->format(n, str); |
| 1838 |
| 1839 logln(UnicodeString(loc->getName()) + names[j] |
| 1840 + "success: " + n + " -> " + str); |
| 1841 |
| 1842 if (testParse) { |
| 1843 // We do not validate the result in this test case, |
| 1844 // because there are cases which do not round trip by design
. |
| 1845 Formattable num; |
| 1846 |
| 1847 // regular parse |
| 1848 status = U_ZERO_ERROR; |
| 1849 f->setLenient(FALSE); |
| 1850 f->parse(str, num, status); |
| 1851 if (U_FAILURE(status)) { |
| 1852 //TODO: We need to fix parse problems - see #6895 / #689
6 |
| 1853 if (status == U_INVALID_FORMAT_ERROR) { |
| 1854 logln(UnicodeString(loc->getName()) + names[j] |
| 1855 + "WARNING could not parse '" + str + "' -> " +
u_errorName(status)); |
| 1856 } else { |
| 1857 errln(UnicodeString(loc->getName()) + names[j] |
| 1858 + "ERROR could not parse '" + str + "' -> " + u_
errorName(status)); |
| 1859 } |
| 1860 } |
| 1861 // lenient parse |
| 1862 status = U_ZERO_ERROR; |
| 1863 f->setLenient(TRUE); |
| 1864 f->parse(str, num, status); |
| 1865 if (U_FAILURE(status)) { |
| 1866 //TODO: We need to fix parse problems - see #6895 / #689
6 |
| 1867 if (status == U_INVALID_FORMAT_ERROR) { |
| 1868 logln(UnicodeString(loc->getName()) + names[j] |
| 1869 + "WARNING could not parse(lenient) '" + str + "
' -> " + u_errorName(status)); |
| 1870 } else { |
| 1871 errln(UnicodeString(loc->getName()) + names[j] |
| 1872 + "ERROR could not parse(lenient) '" + str + "'
-> " + u_errorName(status)); |
| 1873 } |
| 1874 } |
| 1875 } |
| 1876 } |
| 1877 #endif |
| 1878 delete f; |
| 1879 } |
| 1880 } |
| 1881 } |
| 1882 |
| 1883 void |
| 1884 IntlTestRBNF::TestMultiplierSubstitution(void) { |
| 1885 UnicodeString rules("=#,##0=;1,000,000: <##0.###< million;"); |
| 1886 UErrorCode status = U_ZERO_ERROR; |
| 1887 UParseError parse_error; |
| 1888 RuleBasedNumberFormat *rbnf = |
| 1889 new RuleBasedNumberFormat(rules, Locale::getUS(), parse_error, status); |
| 1890 if (U_SUCCESS(status)) { |
| 1891 UnicodeString res; |
| 1892 FieldPosition pos; |
| 1893 double n = 1234000.0; |
| 1894 rbnf->format(n, res, pos); |
| 1895 delete rbnf; |
| 1896 |
| 1897 UnicodeString expected = UNICODE_STRING_SIMPLE("1.234 million"); |
| 1898 if (expected != res) { |
| 1899 UnicodeString msg = "Expected: "; |
| 1900 msg.append(expected); |
| 1901 msg.append(" but got "); |
| 1902 msg.append(res); |
| 1903 errln(msg); |
| 1904 } |
| 1905 } |
| 1906 } |
| 1907 |
| 1908 void |
| 1909 IntlTestRBNF::doTest(RuleBasedNumberFormat* formatter, const char* const testDat
a[][2], UBool testParsing) |
| 1910 { |
| 1911 // man, error reporting would be easier with printf-style syntax for unicode s
tring and formattable |
| 1912 |
| 1913 UErrorCode status = U_ZERO_ERROR; |
| 1914 DecimalFormatSymbols dfs("en", status); |
| 1915 // NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), stat
us); |
| 1916 DecimalFormat decFmt("#,###.################", dfs, status); |
| 1917 if (U_FAILURE(status)) { |
| 1918 errcheckln(status, "FAIL: could not create NumberFormat - %s", u_errorNa
me(status)); |
| 1919 } else { |
| 1920 for (int i = 0; testData[i][0]; ++i) { |
| 1921 const char* numString = testData[i][0]; |
| 1922 const char* expectedWords = testData[i][1]; |
| 1923 |
| 1924 log("[%i] %s = ", i, numString); |
| 1925 Formattable expectedNumber; |
| 1926 decFmt.parse(numString, expectedNumber, status); |
| 1927 if (U_FAILURE(status)) { |
| 1928 errln("FAIL: decFmt could not parse %s", numString); |
| 1929 break; |
| 1930 } else { |
| 1931 UnicodeString actualString; |
| 1932 FieldPosition pos; |
| 1933 formatter->format(expectedNumber, actualString/* , pos*/, status
); |
| 1934 if (U_FAILURE(status)) { |
| 1935 UnicodeString msg = "Fail: formatter could not format "; |
| 1936 decFmt.format(expectedNumber, msg, status); |
| 1937 errln(msg); |
| 1938 break; |
| 1939 } else { |
| 1940 UnicodeString expectedString = UnicodeString(expectedWords,
-1, US_INV).unescape(); |
| 1941 if (actualString != expectedString) { |
| 1942 UnicodeString msg = "FAIL: check failed for "; |
| 1943 decFmt.format(expectedNumber, msg, status); |
| 1944 msg.append(", expected "); |
| 1945 msg.append(expectedString); |
| 1946 msg.append(" but got "); |
| 1947 msg.append(actualString); |
| 1948 errln(msg); |
| 1949 break; |
| 1950 } else { |
| 1951 logln(actualString); |
| 1952 if (testParsing) { |
| 1953 Formattable parsedNumber; |
| 1954 formatter->parse(actualString, parsedNumber, status)
; |
| 1955 if (U_FAILURE(status)) { |
| 1956 UnicodeString msg = "FAIL: formatter could not p
arse "; |
| 1957 msg.append(actualString); |
| 1958 msg.append(" status code: " ); |
| 1959 msg.append(u_errorName(status)); |
| 1960 errln(msg); |
| 1961 break; |
| 1962 } else { |
| 1963 if (parsedNumber != expectedNumber) { |
| 1964 UnicodeString msg = "FAIL: parse failed for
"; |
| 1965 msg.append(actualString); |
| 1966 msg.append(", expected "); |
| 1967 decFmt.format(expectedNumber, msg, status); |
| 1968 msg.append(", but got "); |
| 1969 decFmt.format(parsedNumber, msg, status); |
| 1970 errln(msg); |
| 1971 break; |
| 1972 } |
| 1973 } |
| 1974 } |
| 1975 } |
| 1976 } |
| 1977 } |
| 1978 } |
| 1979 } |
| 1980 } |
| 1981 |
| 1982 void |
| 1983 IntlTestRBNF::doLenientParseTest(RuleBasedNumberFormat* formatter, const char* t
estData[][2]) |
| 1984 { |
| 1985 UErrorCode status = U_ZERO_ERROR; |
| 1986 NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status)
; |
| 1987 if (U_FAILURE(status)) { |
| 1988 errcheckln(status, "FAIL: could not create NumberFormat - %s", u_errorNa
me(status)); |
| 1989 } else { |
| 1990 for (int i = 0; testData[i][0]; ++i) { |
| 1991 const char* spelledNumber = testData[i][0]; // spelled-out number |
| 1992 const char* asciiUSNumber = testData[i][1]; // number as ascii digit
s formatted for US locale |
| 1993 |
| 1994 UnicodeString spelledNumberString = UnicodeString(spelledNumber).une
scape(); |
| 1995 Formattable actualNumber; |
| 1996 formatter->parse(spelledNumberString, actualNumber, status); |
| 1997 if (U_FAILURE(status)) { |
| 1998 UnicodeString msg = "FAIL: formatter could not parse "; |
| 1999 msg.append(spelledNumberString); |
| 2000 errln(msg); |
| 2001 break; |
| 2002 } else { |
| 2003 // I changed the logic of this test somewhat from Java-- instead
of comparing the |
| 2004 // strings, I compare the Formattables. Hmmm, but the Formattab
les don't compare, |
| 2005 // so change it back. |
| 2006 |
| 2007 UnicodeString asciiUSNumberString = asciiUSNumber; |
| 2008 Formattable expectedNumber; |
| 2009 decFmt->parse(asciiUSNumberString, expectedNumber, status); |
| 2010 if (U_FAILURE(status)) { |
| 2011 UnicodeString msg = "FAIL: decFmt could not parse "; |
| 2012 msg.append(asciiUSNumberString); |
| 2013 errln(msg); |
| 2014 break; |
| 2015 } else { |
| 2016 UnicodeString actualNumberString; |
| 2017 UnicodeString expectedNumberString; |
| 2018 decFmt->format(actualNumber, actualNumberString, status); |
| 2019 decFmt->format(expectedNumber, expectedNumberString, status)
; |
| 2020 if (actualNumberString != expectedNumberString) { |
| 2021 UnicodeString msg = "FAIL: parsing"; |
| 2022 msg.append(asciiUSNumberString); |
| 2023 msg.append("\n"); |
| 2024 msg.append(" lenient parse failed for "); |
| 2025 msg.append(spelledNumberString); |
| 2026 msg.append(", expected "); |
| 2027 msg.append(expectedNumberString); |
| 2028 msg.append(", but got "); |
| 2029 msg.append(actualNumberString); |
| 2030 errln(msg); |
| 2031 break; |
| 2032 } |
| 2033 } |
| 2034 } |
| 2035 } |
| 2036 delete decFmt; |
| 2037 } |
| 2038 } |
| 2039 |
| 2040 /* U_HAVE_RBNF */ |
| 2041 #else |
| 2042 |
| 2043 void |
| 2044 IntlTestRBNF::TestRBNFDisabled() { |
| 2045 errln("*** RBNF currently disabled on this platform ***\n"); |
| 2046 } |
| 2047 |
| 2048 /* U_HAVE_RBNF */ |
| 2049 #endif |
| 2050 |
| 2051 #endif /* #if !UCONFIG_NO_FORMATTING */ |
OLD | NEW |