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