1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2015, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6 /* Modification History: 7 * Date Name Description 8 * 07/15/99 helena Ported to HPUX 10/11 CC. 9 */ 10 11 #include "unicode/utypes.h" 12 13 #if !UCONFIG_NO_FORMATTING 14 15 #include "numfmtst.h" 16 #include "unicode/dcfmtsym.h" 17 #include "unicode/decimfmt.h" 18 #include "unicode/localpointer.h" 19 #include "unicode/ucurr.h" 20 #include "unicode/ustring.h" 21 #include "unicode/measfmt.h" 22 #include "unicode/curramt.h" 23 #include "digitlst.h" 24 #include "textfile.h" 25 #include "tokiter.h" 26 #include "charstr.h" 27 #include "putilimp.h" 28 #include "winnmtst.h" 29 #include <float.h> 30 #include <string.h> 31 #include <stdlib.h> 32 #include "cstring.h" 33 #include "unicode/numsys.h" 34 #include "fmtableimp.h" 35 #include "numberformattesttuple.h" 36 #include "datadrivennumberformattestsuite.h" 37 #include "unicode/msgfmt.h" 38 39 class NumberFormatTestDataDriven : public DataDrivenNumberFormatTestSuite { 40 protected: 41 UBool isFormatPass( 42 const NumberFormatTestTuple &tuple, 43 UnicodeString &appendErrorMessage, 44 UErrorCode &status); 45 UBool isToPatternPass( 46 const NumberFormatTestTuple &tuple, 47 UnicodeString &appendErrorMessage, 48 UErrorCode &status); 49 UBool isParsePass( 50 const NumberFormatTestTuple &tuple, 51 UnicodeString &appendErrorMessage, 52 UErrorCode &status); 53 UBool isParseCurrencyPass( 54 const NumberFormatTestTuple &tuple, 55 UnicodeString &appendErrorMessage, 56 UErrorCode &status); 57 }; 58 59 static DigitList &strToDigitList( 60 const UnicodeString &str, 61 DigitList &digitList, 62 UErrorCode &status) { 63 if (U_FAILURE(status)) { 64 return digitList; 65 } 66 if (str == "NaN") { 67 digitList.set(uprv_getNaN()); 68 return digitList; 69 } 70 if (str == "-Inf") { 71 digitList.set(-1*uprv_getInfinity()); 72 return digitList; 73 } 74 if (str == "Inf") { 75 digitList.set(uprv_getInfinity()); 76 return digitList; 77 } 78 CharString formatValue; 79 formatValue.appendInvariantChars(str, status); 80 digitList.set(StringPiece(formatValue.data()), status, 0); 81 return digitList; 82 } 83 84 static UnicodeString &format( 85 const DecimalFormat &fmt, 86 const DigitList &digitList, 87 UnicodeString &appendTo, 88 UErrorCode &status) { 89 if (U_FAILURE(status)) { 90 return appendTo; 91 } 92 FieldPosition fpos(FieldPosition::DONT_CARE); 93 return fmt.format(digitList, appendTo, fpos, status); 94 } 95 96 template<class T> 97 static UnicodeString &format( 98 const DecimalFormat &fmt, 99 T value, 100 UnicodeString &appendTo, 101 UErrorCode &status) { 102 if (U_FAILURE(status)) { 103 return appendTo; 104 } 105 FieldPosition fpos(FieldPosition::DONT_CARE); 106 return fmt.format(value, appendTo, fpos, status); 107 } 108 109 static void adjustDecimalFormat( 110 const NumberFormatTestTuple &tuple, 111 DecimalFormat &fmt, 112 UnicodeString &appendErrorMessage) { 113 if (tuple.minIntegerDigitsFlag) { 114 fmt.setMinimumIntegerDigits(tuple.minIntegerDigits); 115 } 116 if (tuple.maxIntegerDigitsFlag) { 117 fmt.setMaximumIntegerDigits(tuple.maxIntegerDigits); 118 } 119 if (tuple.minFractionDigitsFlag) { 120 fmt.setMinimumFractionDigits(tuple.minFractionDigits); 121 } 122 if (tuple.maxFractionDigitsFlag) { 123 fmt.setMaximumFractionDigits(tuple.maxFractionDigits); 124 } 125 if (tuple.currencyFlag) { 126 UErrorCode status = U_ZERO_ERROR; 127 UnicodeString currency(tuple.currency); 128 const UChar *terminatedCurrency = currency.getTerminatedBuffer(); 129 fmt.setCurrency(terminatedCurrency, status); 130 if (U_FAILURE(status)) { 131 appendErrorMessage.append("Error setting currency."); 132 } 133 } 134 if (tuple.minGroupingDigitsFlag) { 135 fmt.setMinimumGroupingDigits(tuple.minGroupingDigits); 136 } 137 if (tuple.useSigDigitsFlag) { 138 fmt.setSignificantDigitsUsed(tuple.useSigDigits != 0); 139 } 140 if (tuple.minSigDigitsFlag) { 141 fmt.setMinimumSignificantDigits(tuple.minSigDigits); 142 } 143 if (tuple.maxSigDigitsFlag) { 144 fmt.setMaximumSignificantDigits(tuple.maxSigDigits); 145 } 146 if (tuple.useGroupingFlag) { 147 fmt.setGroupingUsed(tuple.useGrouping != 0); 148 } 149 if (tuple.multiplierFlag) { 150 fmt.setMultiplier(tuple.multiplier); 151 } 152 if (tuple.roundingIncrementFlag) { 153 fmt.setRoundingIncrement(tuple.roundingIncrement); 154 } 155 if (tuple.formatWidthFlag) { 156 fmt.setFormatWidth(tuple.formatWidth); 157 } 158 if (tuple.padCharacterFlag) { 159 fmt.setPadCharacter(tuple.padCharacter); 160 } 161 if (tuple.useScientificFlag) { 162 fmt.setScientificNotation(tuple.useScientific != 0); 163 } 164 if (tuple.groupingFlag) { 165 fmt.setGroupingSize(tuple.grouping); 166 } 167 if (tuple.grouping2Flag) { 168 fmt.setSecondaryGroupingSize(tuple.grouping2); 169 } 170 if (tuple.roundingModeFlag) { 171 fmt.setRoundingMode(tuple.roundingMode); 172 } 173 if (tuple.currencyUsageFlag) { 174 UErrorCode status = U_ZERO_ERROR; 175 fmt.setCurrencyUsage(tuple.currencyUsage, &status); 176 if (U_FAILURE(status)) { 177 appendErrorMessage.append("CurrencyUsage: error setting."); 178 } 179 } 180 if (tuple.minimumExponentDigitsFlag) { 181 fmt.setMinimumExponentDigits(tuple.minimumExponentDigits); 182 } 183 if (tuple.exponentSignAlwaysShownFlag) { 184 fmt.setExponentSignAlwaysShown(tuple.exponentSignAlwaysShown != 0); 185 } 186 if (tuple.decimalSeparatorAlwaysShownFlag) { 187 fmt.setDecimalSeparatorAlwaysShown( 188 tuple.decimalSeparatorAlwaysShown != 0); 189 } 190 if (tuple.padPositionFlag) { 191 fmt.setPadPosition(tuple.padPosition); 192 } 193 if (tuple.positivePrefixFlag) { 194 fmt.setPositivePrefix(tuple.positivePrefix); 195 } 196 if (tuple.positiveSuffixFlag) { 197 fmt.setPositiveSuffix(tuple.positiveSuffix); 198 } 199 if (tuple.negativePrefixFlag) { 200 fmt.setNegativePrefix(tuple.negativePrefix); 201 } 202 if (tuple.negativeSuffixFlag) { 203 fmt.setNegativeSuffix(tuple.negativeSuffix); 204 } 205 if (tuple.localizedPatternFlag) { 206 UErrorCode status = U_ZERO_ERROR; 207 fmt.applyLocalizedPattern(tuple.localizedPattern, status); 208 if (U_FAILURE(status)) { 209 appendErrorMessage.append("Error setting localized pattern."); 210 } 211 } 212 fmt.setLenient(NFTT_GET_FIELD(tuple, lenient, 1) != 0); 213 if (tuple.parseIntegerOnlyFlag) { 214 fmt.setParseIntegerOnly(tuple.parseIntegerOnly != 0); 215 } 216 if (tuple.decimalPatternMatchRequiredFlag) { 217 fmt.setDecimalPatternMatchRequired( 218 tuple.decimalPatternMatchRequired != 0); 219 } 220 if (tuple.parseNoExponentFlag) { 221 UErrorCode status = U_ZERO_ERROR; 222 fmt.setAttribute( 223 UNUM_PARSE_NO_EXPONENT, 224 tuple.parseNoExponent, 225 status); 226 if (U_FAILURE(status)) { 227 appendErrorMessage.append("Error setting parse no exponent flag."); 228 } 229 } 230 } 231 232 static DecimalFormat *newDecimalFormat( 233 const Locale &locale, 234 const UnicodeString &pattern, 235 UErrorCode &status) { 236 if (U_FAILURE(status)) { 237 return NULL; 238 } 239 LocalPointer<DecimalFormatSymbols> symbols( 240 new DecimalFormatSymbols(locale, status), status); 241 if (U_FAILURE(status)) { 242 return NULL; 243 } 244 UParseError perror; 245 LocalPointer<DecimalFormat> result(new DecimalFormat( 246 pattern, symbols.getAlias(), perror, status), status); 247 if (!result.isNull()) { 248 symbols.orphan(); 249 } 250 if (U_FAILURE(status)) { 251 return NULL; 252 } 253 return result.orphan(); 254 } 255 256 static DecimalFormat *newDecimalFormat( 257 const NumberFormatTestTuple &tuple, 258 UErrorCode &status) { 259 if (U_FAILURE(status)) { 260 return NULL; 261 } 262 Locale en("en"); 263 return newDecimalFormat( 264 NFTT_GET_FIELD(tuple, locale, en), 265 NFTT_GET_FIELD(tuple, pattern, "0"), 266 status); 267 } 268 269 UBool NumberFormatTestDataDriven::isFormatPass( 270 const NumberFormatTestTuple &tuple, 271 UnicodeString &appendErrorMessage, 272 UErrorCode &status) { 273 if (U_FAILURE(status)) { 274 return FALSE; 275 } 276 LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status)); 277 if (U_FAILURE(status)) { 278 appendErrorMessage.append("Error creating DecimalFormat."); 279 return FALSE; 280 } 281 adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage); 282 if (appendErrorMessage.length() > 0) { 283 return FALSE; 284 } 285 DigitList digitList; 286 strToDigitList(tuple.format, digitList, status); 287 { 288 UnicodeString appendTo; 289 format(*fmtPtr, digitList, appendTo, status); 290 if (U_FAILURE(status)) { 291 appendErrorMessage.append("Error formatting."); 292 return FALSE; 293 } 294 if (appendTo != tuple.output) { 295 appendErrorMessage.append( 296 UnicodeString("Expected: ") + tuple.output + ", got: " + appendTo); 297 return FALSE; 298 } 299 } 300 double doubleVal = digitList.getDouble(); 301 { 302 UnicodeString appendTo; 303 format(*fmtPtr, doubleVal, appendTo, status); 304 if (U_FAILURE(status)) { 305 appendErrorMessage.append("Error formatting."); 306 return FALSE; 307 } 308 if (appendTo != tuple.output) { 309 appendErrorMessage.append( 310 UnicodeString("double Expected: ") + tuple.output + ", got: " + appendTo); 311 return FALSE; 312 } 313 } 314 if (!uprv_isNaN(doubleVal) && !uprv_isInfinite(doubleVal) && doubleVal == uprv_floor(doubleVal)) { 315 int64_t intVal = digitList.getInt64(); 316 { 317 UnicodeString appendTo; 318 format(*fmtPtr, intVal, appendTo, status); 319 if (U_FAILURE(status)) { 320 appendErrorMessage.append("Error formatting."); 321 return FALSE; 322 } 323 if (appendTo != tuple.output) { 324 appendErrorMessage.append( 325 UnicodeString("int64 Expected: ") + tuple.output + ", got: " + appendTo); 326 return FALSE; 327 } 328 } 329 } 330 return TRUE; 331 } 332 333 UBool NumberFormatTestDataDriven::isToPatternPass( 334 const NumberFormatTestTuple &tuple, 335 UnicodeString &appendErrorMessage, 336 UErrorCode &status) { 337 if (U_FAILURE(status)) { 338 return FALSE; 339 } 340 LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status)); 341 if (U_FAILURE(status)) { 342 appendErrorMessage.append("Error creating DecimalFormat."); 343 return FALSE; 344 } 345 adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage); 346 if (appendErrorMessage.length() > 0) { 347 return FALSE; 348 } 349 if (tuple.toPatternFlag) { 350 UnicodeString actual; 351 fmtPtr->toPattern(actual); 352 if (actual != tuple.toPattern) { 353 appendErrorMessage.append( 354 UnicodeString("Expected: ") + tuple.toPattern + ", got: " + actual + ". "); 355 } 356 } 357 if (tuple.toLocalizedPatternFlag) { 358 UnicodeString actual; 359 fmtPtr->toLocalizedPattern(actual); 360 if (actual != tuple.toLocalizedPattern) { 361 appendErrorMessage.append( 362 UnicodeString("Expected: ") + tuple.toLocalizedPattern + ", got: " + actual + ". "); 363 } 364 } 365 return appendErrorMessage.length() == 0; 366 } 367 368 UBool NumberFormatTestDataDriven::isParsePass( 369 const NumberFormatTestTuple &tuple, 370 UnicodeString &appendErrorMessage, 371 UErrorCode &status) { 372 if (U_FAILURE(status)) { 373 return FALSE; 374 } 375 LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status)); 376 if (U_FAILURE(status)) { 377 appendErrorMessage.append("Error creating DecimalFormat."); 378 return FALSE; 379 } 380 adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage); 381 if (appendErrorMessage.length() > 0) { 382 return FALSE; 383 } 384 Formattable result; 385 ParsePosition ppos; 386 fmtPtr->parse(tuple.parse, result, ppos); 387 if (ppos.getIndex() == 0) { 388 if (tuple.output != "fail") { 389 appendErrorMessage.append("Parse failed but was expected to succeed."); 390 return FALSE; 391 } 392 return TRUE; 393 } 394 UnicodeString resultStr(UnicodeString::fromUTF8(result.getDecimalNumber(status))); 395 if (tuple.output == "fail") { 396 appendErrorMessage.append(UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail."); 397 return FALSE; 398 } 399 DigitList expected; 400 strToDigitList(tuple.output, expected, status); 401 if (U_FAILURE(status)) { 402 appendErrorMessage.append("Error parsing."); 403 return FALSE; 404 } 405 if (expected != *result.getDigitList()) { 406 appendErrorMessage.append( 407 UnicodeString("Expected: ") + tuple.output + ", got: " + resultStr + ". "); 408 return FALSE; 409 } 410 return TRUE; 411 } 412 413 UBool NumberFormatTestDataDriven::isParseCurrencyPass( 414 const NumberFormatTestTuple &tuple, 415 UnicodeString &appendErrorMessage, 416 UErrorCode &status) { 417 if (U_FAILURE(status)) { 418 return FALSE; 419 } 420 LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status)); 421 if (U_FAILURE(status)) { 422 appendErrorMessage.append("Error creating DecimalFormat."); 423 return FALSE; 424 } 425 adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage); 426 if (appendErrorMessage.length() > 0) { 427 return FALSE; 428 } 429 ParsePosition ppos; 430 LocalPointer<CurrencyAmount> currAmt( 431 fmtPtr->parseCurrency(tuple.parse, ppos)); 432 if (ppos.getIndex() == 0) { 433 if (tuple.output != "fail") { 434 appendErrorMessage.append("Parse failed but was expected to succeed."); 435 return FALSE; 436 } 437 return TRUE; 438 } 439 UnicodeString currStr(currAmt->getISOCurrency()); 440 Formattable resultFormattable(currAmt->getNumber()); 441 UnicodeString resultStr(UnicodeString::fromUTF8(resultFormattable.getDecimalNumber(status))); 442 if (tuple.output == "fail") { 443 appendErrorMessage.append(UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail."); 444 return FALSE; 445 } 446 DigitList expected; 447 strToDigitList(tuple.output, expected, status); 448 if (U_FAILURE(status)) { 449 appendErrorMessage.append("Error parsing."); 450 return FALSE; 451 } 452 if (expected != *currAmt->getNumber().getDigitList()) { 453 appendErrorMessage.append( 454 UnicodeString("Expected: ") + tuple.output + ", got: " + resultStr + ". "); 455 return FALSE; 456 } 457 if (currStr != tuple.outputCurrency) { 458 appendErrorMessage.append(UnicodeString( 459 "Expected currency: ") + tuple.outputCurrency + ", got: " + currStr + ". "); 460 return FALSE; 461 } 462 return TRUE; 463 } 464 465 //#define NUMFMTST_CACHE_DEBUG 1 466 #include "stdio.h" /* for sprintf */ 467 // #include "iostream" // for cout 468 469 //#define NUMFMTST_DEBUG 1 470 471 static const UChar EUR[] = {69,85,82,0}; // "EUR" 472 static const UChar ISO_CURRENCY_USD[] = {0x55, 0x53, 0x44, 0}; // "USD" 473 474 475 // ***************************************************************************** 476 // class NumberFormatTest 477 // ***************************************************************************** 478 479 #define CHECK(status,str) if (U_FAILURE(status)) { errcheckln(status, UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; } 480 #define CHECK_DATA(status,str) if (U_FAILURE(status)) { dataerrln(UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; } 481 482 void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 483 { 484 TESTCASE_AUTO_BEGIN; 485 TESTCASE_AUTO(TestCurrencySign); 486 TESTCASE_AUTO(TestCurrency); 487 TESTCASE_AUTO(TestParse); 488 TESTCASE_AUTO(TestRounding487); 489 TESTCASE_AUTO(TestQuotes); 490 TESTCASE_AUTO(TestExponential); 491 TESTCASE_AUTO(TestPatterns); 492 493 // Upgrade to alphaWorks - liu 5/99 494 TESTCASE_AUTO(TestExponent); 495 TESTCASE_AUTO(TestScientific); 496 TESTCASE_AUTO(TestPad); 497 TESTCASE_AUTO(TestPatterns2); 498 TESTCASE_AUTO(TestSecondaryGrouping); 499 TESTCASE_AUTO(TestSurrogateSupport); 500 TESTCASE_AUTO(TestAPI); 501 502 TESTCASE_AUTO(TestCurrencyObject); 503 TESTCASE_AUTO(TestCurrencyPatterns); 504 //TESTCASE_AUTO(TestDigitList); 505 TESTCASE_AUTO(TestWhiteSpaceParsing); 506 TESTCASE_AUTO(TestComplexCurrency); // This test removed because CLDR no longer uses choice formats in currency symbols. 507 TESTCASE_AUTO(TestRegCurrency); 508 TESTCASE_AUTO(TestSymbolsWithBadLocale); 509 TESTCASE_AUTO(TestAdoptDecimalFormatSymbols); 510 511 TESTCASE_AUTO(TestScientific2); 512 TESTCASE_AUTO(TestScientificGrouping); 513 TESTCASE_AUTO(TestInt64); 514 515 TESTCASE_AUTO(TestPerMill); 516 TESTCASE_AUTO(TestIllegalPatterns); 517 TESTCASE_AUTO(TestCases); 518 519 TESTCASE_AUTO(TestCurrencyNames); 520 TESTCASE_AUTO(TestCurrencyAmount); 521 TESTCASE_AUTO(TestCurrencyUnit); 522 TESTCASE_AUTO(TestCoverage); 523 TESTCASE_AUTO(TestJB3832); 524 TESTCASE_AUTO(TestHost); 525 TESTCASE_AUTO(TestHostClone); 526 TESTCASE_AUTO(TestCurrencyFormat); 527 TESTCASE_AUTO(TestRounding); 528 TESTCASE_AUTO(TestNonpositiveMultiplier); 529 TESTCASE_AUTO(TestNumberingSystems); 530 TESTCASE_AUTO(TestSpaceParsing); 531 TESTCASE_AUTO(TestMultiCurrencySign); 532 TESTCASE_AUTO(TestCurrencyFormatForMixParsing); 533 TESTCASE_AUTO(TestDecimalFormatCurrencyParse); 534 TESTCASE_AUTO(TestCurrencyIsoPluralFormat); 535 TESTCASE_AUTO(TestCurrencyParsing); 536 TESTCASE_AUTO(TestParseCurrencyInUCurr); 537 TESTCASE_AUTO(TestFormatAttributes); 538 TESTCASE_AUTO(TestFieldPositionIterator); 539 TESTCASE_AUTO(TestDecimal); 540 TESTCASE_AUTO(TestCurrencyFractionDigits); 541 TESTCASE_AUTO(TestExponentParse); 542 TESTCASE_AUTO(TestExplicitParents); 543 TESTCASE_AUTO(TestLenientParse); 544 TESTCASE_AUTO(TestAvailableNumberingSystems); 545 TESTCASE_AUTO(TestRoundingPattern); 546 TESTCASE_AUTO(Test9087); 547 TESTCASE_AUTO(TestFormatFastpaths); 548 TESTCASE_AUTO(TestFormattableSize); 549 TESTCASE_AUTO(TestUFormattable); 550 TESTCASE_AUTO(TestSignificantDigits); 551 TESTCASE_AUTO(TestShowZero); 552 TESTCASE_AUTO(TestCompatibleCurrencies); 553 TESTCASE_AUTO(TestBug9936); 554 TESTCASE_AUTO(TestParseNegativeWithFaLocale); 555 TESTCASE_AUTO(TestParseNegativeWithAlternateMinusSign); 556 TESTCASE_AUTO(TestCustomCurrencySignAndSeparator); 557 TESTCASE_AUTO(TestParseSignsAndMarks); 558 TESTCASE_AUTO(Test10419RoundingWith0FractionDigits); 559 TESTCASE_AUTO(Test10468ApplyPattern); 560 TESTCASE_AUTO(TestRoundingScientific10542); 561 TESTCASE_AUTO(TestZeroScientific10547); 562 TESTCASE_AUTO(TestAccountingCurrency); 563 TESTCASE_AUTO(TestEquality); 564 TESTCASE_AUTO(TestCurrencyUsage); 565 TESTCASE_AUTO(TestNumberFormatTestTuple); 566 TESTCASE_AUTO(TestDataDriven); 567 TESTCASE_AUTO(TestDoubleLimit11439); 568 TESTCASE_AUTO(TestFastPathConsistent11524); 569 TESTCASE_AUTO(TestGetAffixes); 570 TESTCASE_AUTO(TestToPatternScientific11648); 571 TESTCASE_AUTO(TestBenchmark); 572 TESTCASE_AUTO(TestCtorApplyPatternDifference); 573 TESTCASE_AUTO(TestFractionalDigitsForCurrency); 574 TESTCASE_AUTO(TestFormatCurrencyPlural); 575 TESTCASE_AUTO(Test11868); 576 TESTCASE_AUTO(Test10727_RoundingZero); 577 TESTCASE_AUTO(Test11376_getAndSetPositivePrefix); 578 TESTCASE_AUTO(Test11475_signRecognition); 579 TESTCASE_AUTO(Test11640_getAffixes); 580 TESTCASE_AUTO(Test11649_toPatternWithMultiCurrency); 581 TESTCASE_AUTO_END; 582 } 583 584 // ------------------------------------- 585 586 // Test API (increase code coverage) 587 void 588 NumberFormatTest::TestAPI(void) 589 { 590 logln("Test API"); 591 UErrorCode status = U_ZERO_ERROR; 592 NumberFormat *test = NumberFormat::createInstance("root", status); 593 if(U_FAILURE(status)) { 594 dataerrln("unable to create format object - %s", u_errorName(status)); 595 } 596 if(test != NULL) { 597 test->setMinimumIntegerDigits(10); 598 test->setMaximumIntegerDigits(2); 599 600 test->setMinimumFractionDigits(10); 601 test->setMaximumFractionDigits(2); 602 603 UnicodeString result; 604 FieldPosition pos; 605 Formattable bla("Paja Patak"); // Donald Duck for non Serbian speakers 606 test->format(bla, result, pos, status); 607 if(U_SUCCESS(status)) { 608 errln("Yuck... Formatted a duck... As a number!"); 609 } else { 610 status = U_ZERO_ERROR; 611 } 612 613 result.remove(); 614 int64_t ll = 12; 615 test->format(ll, result); 616 if (result != "12.00"){ 617 errln("format int64_t error"); 618 } 619 620 ParsePosition ppos; 621 LocalPointer<CurrencyAmount> currAmt(test->parseCurrency("",ppos)); 622 // old test for (U_FAILURE(status)) was bogus here, method does not set status! 623 if (ppos.getIndex()) { 624 errln("Parsed empty string as currency"); 625 } 626 627 delete test; 628 } 629 } 630 631 class StubNumberFormat :public NumberFormat{ 632 public: 633 StubNumberFormat(){}; 634 virtual UnicodeString& format(double ,UnicodeString& appendTo,FieldPosition& ) const { 635 return appendTo; 636 } 637 virtual UnicodeString& format(int32_t ,UnicodeString& appendTo,FieldPosition& ) const { 638 return appendTo.append((UChar)0x0033); 639 } 640 virtual UnicodeString& format(int64_t number,UnicodeString& appendTo,FieldPosition& pos) const { 641 return NumberFormat::format(number, appendTo, pos); 642 } 643 virtual UnicodeString& format(const Formattable& , UnicodeString& appendTo, FieldPosition& , UErrorCode& ) const { 644 return appendTo; 645 } 646 virtual void parse(const UnicodeString& , 647 Formattable& , 648 ParsePosition& ) const {} 649 virtual void parse( const UnicodeString& , 650 Formattable& , 651 UErrorCode& ) const {} 652 virtual UClassID getDynamicClassID(void) const { 653 static char classID = 0; 654 return (UClassID)&classID; 655 } 656 virtual Format* clone() const {return NULL;} 657 }; 658 659 void 660 NumberFormatTest::TestCoverage(void){ 661 StubNumberFormat stub; 662 UnicodeString agent("agent"); 663 FieldPosition pos; 664 int64_t num = 4; 665 if (stub.format(num, agent, pos) != UnicodeString("agent3")){ 666 errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)"); 667 }; 668 } 669 670 // Test various patterns 671 void 672 NumberFormatTest::TestPatterns(void) 673 { 674 UErrorCode status = U_ZERO_ERROR; 675 DecimalFormatSymbols sym(Locale::getUS(), status); 676 if (U_FAILURE(status)) { errcheckln(status, "FAIL: Could not construct DecimalFormatSymbols - %s", u_errorName(status)); return; } 677 678 const char* pat[] = { "#.#", "#.", ".#", "#" }; 679 int32_t pat_length = (int32_t)(sizeof(pat) / sizeof(pat[0])); 680 const char* newpat[] = { "#0.#", "#0.", "#.0", "#" }; 681 const char* num[] = { "0", "0.", ".0", "0" }; 682 for (int32_t i=0; i<pat_length; ++i) 683 { 684 status = U_ZERO_ERROR; 685 DecimalFormat fmt(pat[i], sym, status); 686 if (U_FAILURE(status)) { errln((UnicodeString)"FAIL: DecimalFormat constructor failed for " + pat[i]); continue; } 687 UnicodeString newp; fmt.toPattern(newp); 688 if (!(newp == newpat[i])) 689 errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] + 690 "; " + newp + " seen instead"); 691 692 UnicodeString s; (*(NumberFormat*)&fmt).format((int32_t)0, s); 693 if (!(s == num[i])) 694 { 695 errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should format zero as " + num[i] + 696 "; " + s + " seen instead"); 697 logln((UnicodeString)"Min integer digits = " + fmt.getMinimumIntegerDigits()); 698 } 699 } 700 } 701 702 /* 703 icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug 704 icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug 705 icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug 706 */ 707 /* 708 void 709 NumberFormatTest::TestDigitList(void) 710 { 711 // API coverage for DigitList 712 DigitList list1; 713 list1.append('1'); 714 list1.fDecimalAt = 1; 715 DigitList list2; 716 list2.set((int32_t)1); 717 if (list1 != list2) { 718 errln("digitlist append, operator!= or set failed "); 719 } 720 if (!(list1 == list2)) { 721 errln("digitlist append, operator== or set failed "); 722 } 723 } 724 */ 725 726 // ------------------------------------- 727 728 // Test exponential pattern 729 void 730 NumberFormatTest::TestExponential(void) 731 { 732 UErrorCode status = U_ZERO_ERROR; 733 DecimalFormatSymbols sym(Locale::getUS(), status); 734 if (U_FAILURE(status)) { errcheckln(status, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status)); return; } 735 const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" }; 736 int32_t pat_length = (int32_t)(sizeof(pat) / sizeof(pat[0])); 737 738 // The following #if statements allow this test to be built and run on 739 // platforms that do not have standard IEEE numerics. For example, 740 // S/390 doubles have an exponent range of -78 to +75. For the 741 // following #if statements to work, float.h must define 742 // DBL_MAX_10_EXP to be a compile-time constant. 743 744 // This section may be expanded as needed. 745 746 #if DBL_MAX_10_EXP > 300 747 double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 }; 748 int32_t val_length = (int32_t)(sizeof(val) / sizeof(val[0])); 749 const char* valFormat[] = 750 { 751 // 0.####E0 752 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271", 753 // 00.000E00 754 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272", 755 // ##0.######E000 756 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273", 757 // 0.###E0;[0.###E0] 758 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]" 759 }; 760 double valParse[] = 761 { 762 0.01234, 123460000, 1.23E300, -3.1416E-271, 763 0.01234, 123460000, 1.23E300, -3.1416E-271, 764 0.01234, 123456800, 1.23E300, -3.141593E-271, 765 0.01234, 123500000, 1.23E300, -3.142E-271, 766 }; 767 #elif DBL_MAX_10_EXP > 70 768 double val[] = { 0.01234, 123456789, 1.23e70, -3.141592653e-71 }; 769 int32_t val_length = sizeof(val) / sizeof(val[0]); 770 char* valFormat[] = 771 { 772 // 0.####E0 773 "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71", 774 // 00.000E00 775 "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72", 776 // ##0.######E000 777 "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072", 778 // 0.###E0;[0.###E0] 779 "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]" 780 }; 781 double valParse[] = 782 { 783 0.01234, 123460000, 1.23E70, -3.1416E-71, 784 0.01234, 123460000, 1.23E70, -3.1416E-71, 785 0.01234, 123456800, 1.23E70, -3.141593E-71, 786 0.01234, 123500000, 1.23E70, -3.142E-71, 787 }; 788 #else 789 // Don't test double conversion 790 double* val = 0; 791 int32_t val_length = 0; 792 char** valFormat = 0; 793 double* valParse = 0; 794 logln("Warning: Skipping double conversion tests"); 795 #endif 796 797 int32_t lval[] = { 0, -1, 1, 123456789 }; 798 int32_t lval_length = (int32_t)(sizeof(lval) / sizeof(lval[0])); 799 const char* lvalFormat[] = 800 { 801 // 0.####E0 802 "0E0", "-1E0", "1E0", "1.2346E8", 803 // 00.000E00 804 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07", 805 // ##0.######E000 806 "0E000", "-1E000", "1E000", "123.4568E006", 807 // 0.###E0;[0.###E0] 808 "0E0", "[1E0]", "1E0", "1.235E8" 809 }; 810 int32_t lvalParse[] = 811 { 812 0, -1, 1, 123460000, 813 0, -1, 1, 123460000, 814 0, -1, 1, 123456800, 815 0, -1, 1, 123500000, 816 }; 817 int32_t ival = 0, ilval = 0; 818 for (int32_t p=0; p<pat_length; ++p) 819 { 820 DecimalFormat fmt(pat[p], sym, status); 821 if (U_FAILURE(status)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; } 822 UnicodeString pattern; 823 logln((UnicodeString)"Pattern \"" + pat[p] + "\" -toPattern-> \"" + 824 fmt.toPattern(pattern) + "\""); 825 int32_t v; 826 for (v=0; v<val_length; ++v) 827 { 828 UnicodeString s; (*(NumberFormat*)&fmt).format(val[v], s); 829 logln((UnicodeString)" " + val[v] + " -format-> " + s); 830 if (s != valFormat[v+ival]) 831 errln((UnicodeString)"FAIL: Expected " + valFormat[v+ival]); 832 833 ParsePosition pos(0); 834 Formattable af; 835 fmt.parse(s, af, pos); 836 double a; 837 UBool useEpsilon = FALSE; 838 if (af.getType() == Formattable::kLong) 839 a = af.getLong(); 840 else if (af.getType() == Formattable::kDouble) { 841 a = af.getDouble(); 842 #if U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400 843 // S/390 will show a failure like this: 844 //| -3.141592652999999e-271 -format-> -3.1416E-271 845 //| -parse-> -3.1416e-271 846 //| FAIL: Expected -3.141599999999999e-271 847 // To compensate, we use an epsilon-based equality 848 // test on S/390 only. We don't want to do this in 849 // general because it's less exacting. 850 useEpsilon = TRUE; 851 #endif 852 } 853 else { 854 errln((UnicodeString)"FAIL: Non-numeric Formattable returned"); 855 continue; 856 } 857 if (pos.getIndex() == s.length()) 858 { 859 logln((UnicodeString)" -parse-> " + a); 860 // Use epsilon comparison as necessary 861 if ((useEpsilon && 862 (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) || 863 (!useEpsilon && a != valParse[v+ival])) 864 { 865 errln((UnicodeString)"FAIL: Expected " + valParse[v+ival]); 866 } 867 } 868 else { 869 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a); 870 errln((UnicodeString)" should be (" + s.length() + " chars) -> " + valParse[v+ival]); 871 } 872 } 873 for (v=0; v<lval_length; ++v) 874 { 875 UnicodeString s; 876 (*(NumberFormat*)&fmt).format(lval[v], s); 877 logln((UnicodeString)" " + lval[v] + "L -format-> " + s); 878 if (s != lvalFormat[v+ilval]) 879 errln((UnicodeString)"ERROR: Expected " + lvalFormat[v+ilval] + " Got: " + s); 880 881 ParsePosition pos(0); 882 Formattable af; 883 fmt.parse(s, af, pos); 884 if (af.getType() == Formattable::kLong || 885 af.getType() == Formattable::kInt64) { 886 UErrorCode status = U_ZERO_ERROR; 887 int32_t a = af.getLong(status); 888 if (pos.getIndex() == s.length()) 889 { 890 logln((UnicodeString)" -parse-> " + a); 891 if (a != lvalParse[v+ilval]) 892 errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval]); 893 } 894 else 895 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a); 896 } 897 else 898 errln((UnicodeString)"FAIL: Non-long Formattable returned for " + s 899 + " Double: " + af.getDouble() 900 + ", Long: " + af.getLong()); 901 } 902 ival += val_length; 903 ilval += lval_length; 904 } 905 } 906 907 void 908 NumberFormatTest::TestScientific2() { 909 // jb 2552 910 UErrorCode status = U_ZERO_ERROR; 911 DecimalFormat* fmt = (DecimalFormat*)NumberFormat::createCurrencyInstance("en_US", status); 912 if (U_SUCCESS(status)) { 913 double num = 12.34; 914 expect(*fmt, num, "$12.34"); 915 fmt->setScientificNotation(TRUE); 916 expect(*fmt, num, "$1.23E1"); 917 fmt->setScientificNotation(FALSE); 918 expect(*fmt, num, "$12.34"); 919 } 920 delete fmt; 921 } 922 923 void 924 NumberFormatTest::TestScientificGrouping() { 925 // jb 2552 926 UErrorCode status = U_ZERO_ERROR; 927 DecimalFormat fmt("##0.00E0",status); 928 if (U_SUCCESS(status)) { 929 expect(fmt, .01234, "12.3E-3"); 930 expect(fmt, .1234, "123E-3"); 931 expect(fmt, 1.234, "1.23E0"); 932 expect(fmt, 12.34, "12.3E0"); 933 expect(fmt, 123.4, "123E0"); 934 expect(fmt, 1234., "1.23E3"); 935 } 936 } 937 938 /*static void setFromString(DigitList& dl, const char* str) { 939 char c; 940 UBool decimalSet = FALSE; 941 dl.clear(); 942 while ((c = *str++)) { 943 if (c == '-') { 944 dl.fIsPositive = FALSE; 945 } else if (c == '+') { 946 dl.fIsPositive = TRUE; 947 } else if (c == '.') { 948 dl.fDecimalAt = dl.fCount; 949 decimalSet = TRUE; 950 } else { 951 dl.append(c); 952 } 953 } 954 if (!decimalSet) { 955 dl.fDecimalAt = dl.fCount; 956 } 957 }*/ 958 959 void 960 NumberFormatTest::TestInt64() { 961 UErrorCode status = U_ZERO_ERROR; 962 DecimalFormat fmt("#.#E0",status); 963 if (U_FAILURE(status)) { 964 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 965 return; 966 } 967 fmt.setMaximumFractionDigits(20); 968 if (U_SUCCESS(status)) { 969 expect(fmt, (Formattable)(int64_t)0, "0E0"); 970 expect(fmt, (Formattable)(int64_t)-1, "-1E0"); 971 expect(fmt, (Formattable)(int64_t)1, "1E0"); 972 expect(fmt, (Formattable)(int64_t)2147483647, "2.147483647E9"); 973 expect(fmt, (Formattable)((int64_t)-2147483647-1), "-2.147483648E9"); 974 expect(fmt, (Formattable)(int64_t)U_INT64_MAX, "9.223372036854775807E18"); 975 expect(fmt, (Formattable)(int64_t)U_INT64_MIN, "-9.223372036854775808E18"); 976 } 977 978 // also test digitlist 979 /* int64_t int64max = U_INT64_MAX; 980 int64_t int64min = U_INT64_MIN; 981 const char* int64maxstr = "9223372036854775807"; 982 const char* int64minstr = "-9223372036854775808"; 983 UnicodeString fail("fail: "); 984 985 // test max int64 value 986 DigitList dl; 987 setFromString(dl, int64maxstr); 988 { 989 if (!dl.fitsIntoInt64(FALSE)) { 990 errln(fail + int64maxstr + " didn't fit"); 991 } 992 int64_t int64Value = dl.getInt64(); 993 if (int64Value != int64max) { 994 errln(fail + int64maxstr); 995 } 996 dl.set(int64Value); 997 int64Value = dl.getInt64(); 998 if (int64Value != int64max) { 999 errln(fail + int64maxstr); 1000 } 1001 } 1002 // test negative of max int64 value (1 shy of min int64 value) 1003 dl.fIsPositive = FALSE; 1004 { 1005 if (!dl.fitsIntoInt64(FALSE)) { 1006 errln(fail + "-" + int64maxstr + " didn't fit"); 1007 } 1008 int64_t int64Value = dl.getInt64(); 1009 if (int64Value != -int64max) { 1010 errln(fail + "-" + int64maxstr); 1011 } 1012 dl.set(int64Value); 1013 int64Value = dl.getInt64(); 1014 if (int64Value != -int64max) { 1015 errln(fail + "-" + int64maxstr); 1016 } 1017 } 1018 // test min int64 value 1019 setFromString(dl, int64minstr); 1020 { 1021 if (!dl.fitsIntoInt64(FALSE)) { 1022 errln(fail + "-" + int64minstr + " didn't fit"); 1023 } 1024 int64_t int64Value = dl.getInt64(); 1025 if (int64Value != int64min) { 1026 errln(fail + int64minstr); 1027 } 1028 dl.set(int64Value); 1029 int64Value = dl.getInt64(); 1030 if (int64Value != int64min) { 1031 errln(fail + int64minstr); 1032 } 1033 } 1034 // test negative of min int 64 value (1 more than max int64 value) 1035 dl.fIsPositive = TRUE; // won't fit 1036 { 1037 if (dl.fitsIntoInt64(FALSE)) { 1038 errln(fail + "-(" + int64minstr + ") didn't fit"); 1039 } 1040 }*/ 1041 } 1042 1043 // ------------------------------------- 1044 1045 // Test the handling of quotes 1046 void 1047 NumberFormatTest::TestQuotes(void) 1048 { 1049 UErrorCode status = U_ZERO_ERROR; 1050 UnicodeString *pat; 1051 DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), status); 1052 if (U_FAILURE(status)) { 1053 errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status)); 1054 delete sym; 1055 return; 1056 } 1057 pat = new UnicodeString("a'fo''o'b#"); 1058 DecimalFormat *fmt = new DecimalFormat(*pat, *sym, status); 1059 UnicodeString s; 1060 ((NumberFormat*)fmt)->format((int32_t)123, s); 1061 logln((UnicodeString)"Pattern \"" + *pat + "\""); 1062 logln((UnicodeString)" Format 123 -> " + escape(s)); 1063 if (!(s=="afo'ob123")) 1064 errln((UnicodeString)"FAIL: Expected afo'ob123"); 1065 1066 s.truncate(0); 1067 delete fmt; 1068 delete pat; 1069 1070 pat = new UnicodeString("a''b#"); 1071 fmt = new DecimalFormat(*pat, *sym, status); 1072 ((NumberFormat*)fmt)->format((int32_t)123, s); 1073 logln((UnicodeString)"Pattern \"" + *pat + "\""); 1074 logln((UnicodeString)" Format 123 -> " + escape(s)); 1075 if (!(s=="a'b123")) 1076 errln((UnicodeString)"FAIL: Expected a'b123"); 1077 delete fmt; 1078 delete pat; 1079 delete sym; 1080 } 1081 1082 /** 1083 * Test the handling of the currency symbol in patterns. 1084 */ 1085 void 1086 NumberFormatTest::TestCurrencySign(void) 1087 { 1088 UErrorCode status = U_ZERO_ERROR; 1089 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale::getUS(), status); 1090 UnicodeString pat; 1091 UChar currency = 0x00A4; 1092 if (U_FAILURE(status)) { 1093 errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status)); 1094 delete sym; 1095 return; 1096 } 1097 // "\xA4#,##0.00;-\xA4#,##0.00" 1098 pat.append(currency).append("#,##0.00;-"). 1099 append(currency).append("#,##0.00"); 1100 DecimalFormat *fmt = new DecimalFormat(pat, *sym, status); 1101 UnicodeString s; ((NumberFormat*)fmt)->format(1234.56, s); 1102 pat.truncate(0); 1103 logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\""); 1104 logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s)); 1105 if (s != "$1,234.56") dataerrln((UnicodeString)"FAIL: Expected $1,234.56"); 1106 s.truncate(0); 1107 ((NumberFormat*)fmt)->format(- 1234.56, s); 1108 logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s)); 1109 if (s != "-$1,234.56") dataerrln((UnicodeString)"FAIL: Expected -$1,234.56"); 1110 delete fmt; 1111 pat.truncate(0); 1112 // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00" 1113 pat.append(currency).append(currency). 1114 append(" #,##0.00;"). 1115 append(currency).append(currency). 1116 append(" -#,##0.00"); 1117 fmt = new DecimalFormat(pat, *sym, status); 1118 s.truncate(0); 1119 ((NumberFormat*)fmt)->format(1234.56, s); 1120 logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\""); 1121 logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s)); 1122 if (s != "USD 1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD 1,234.56"); 1123 s.truncate(0); 1124 ((NumberFormat*)fmt)->format(-1234.56, s); 1125 logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s)); 1126 if (s != "USD -1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD -1,234.56"); 1127 delete fmt; 1128 delete sym; 1129 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + u_errorName(status)); 1130 } 1131 1132 // ------------------------------------- 1133 1134 static UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); } 1135 1136 UnicodeString& 1137 NumberFormatTest::escape(UnicodeString& s) 1138 { 1139 UnicodeString buf; 1140 for (int32_t i=0; i<s.length(); ++i) 1141 { 1142 UChar c = s[(int32_t)i]; 1143 if (c <= (UChar)0x7F) buf += c; 1144 else { 1145 buf += (UChar)0x5c; buf += (UChar)0x55; 1146 buf += toHexString((c & 0xF000) >> 12); 1147 buf += toHexString((c & 0x0F00) >> 8); 1148 buf += toHexString((c & 0x00F0) >> 4); 1149 buf += toHexString(c & 0x000F); 1150 } 1151 } 1152 return (s = buf); 1153 } 1154 1155 1156 // ------------------------------------- 1157 static const char* testCases[][2]= { 1158 /* locale ID */ /* expected */ 1159 {"ca_ES_PREEURO", "\\u20A7\\u00A01.150" }, 1160 {"de_LU_PREEURO", "1,150\\u00A0F" }, 1161 {"el_GR_PREEURO", "1.150,50\\u00A0\\u0394\\u03C1\\u03C7" }, 1162 {"en_BE_PREEURO", "1.150,50\\u00A0BEF" }, 1163 {"es_ES_PREEURO", "1.150\\u00A0\\u20A7" }, 1164 {"eu_ES_PREEURO", "\\u20A7\\u00A01.150" }, 1165 {"gl_ES_PREEURO", "1.150\\u00A0\\u20A7" }, 1166 {"it_IT_PREEURO", "ITL\\u00A01.150" }, 1167 {"pt_PT_PREEURO", "1,150$50\\u00A0\\u200B"}, // per cldrbug 7670 1168 {"en_US@currency=JPY", "\\u00A51,150"}, 1169 {"en_US@currency=jpy", "\\u00A51,150"}, 1170 {"en-US-u-cu-jpy", "\\u00A51,150"} 1171 }; 1172 /** 1173 * Test localized currency patterns. 1174 */ 1175 void 1176 NumberFormatTest::TestCurrency(void) 1177 { 1178 UErrorCode status = U_ZERO_ERROR; 1179 NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status); 1180 if (U_FAILURE(status)) { 1181 dataerrln("Error calling NumberFormat::createCurrencyInstance()"); 1182 return; 1183 } 1184 1185 UnicodeString s; currencyFmt->format(1.50, s); 1186 logln((UnicodeString)"Un pauvre ici a..........." + s); 1187 if (!(s==CharsToUnicodeString("1,50\\u00A0$"))) 1188 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>$"); 1189 delete currencyFmt; 1190 s.truncate(0); 1191 char loc[256]={0}; 1192 int len = uloc_canonicalize("de_DE_PREEURO", loc, 256, &status); 1193 (void)len; // Suppress unused variable warning. 1194 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc),status); 1195 currencyFmt->format(1.50, s); 1196 logln((UnicodeString)"Un pauvre en Allemagne a.." + s); 1197 if (!(s==CharsToUnicodeString("1,50\\u00A0DM"))) 1198 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>DM"); 1199 delete currencyFmt; 1200 s.truncate(0); 1201 len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status); 1202 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status); 1203 currencyFmt->format(1.50, s); 1204 logln((UnicodeString)"Un pauvre en France a....." + s); 1205 if (!(s==CharsToUnicodeString("1,50\\u00A0F"))) 1206 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>F"); 1207 delete currencyFmt; 1208 if (U_FAILURE(status)) 1209 errln((UnicodeString)"FAIL: Status " + (int32_t)status); 1210 1211 for(int i=0; i < (int)(sizeof(testCases)/sizeof(testCases[i])); i++){ 1212 status = U_ZERO_ERROR; 1213 const char *localeID = testCases[i][0]; 1214 UnicodeString expected(testCases[i][1], -1, US_INV); 1215 expected = expected.unescape(); 1216 s.truncate(0); 1217 char loc[256]={0}; 1218 uloc_canonicalize(localeID, loc, 256, &status); 1219 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status); 1220 if(U_FAILURE(status)){ 1221 errln("Could not create currency formatter for locale %s",localeID); 1222 continue; 1223 } 1224 currencyFmt->format(1150.50, s); 1225 if(s!=expected){ 1226 errln(UnicodeString("FAIL: Expected: ")+expected 1227 + UnicodeString(" Got: ") + s 1228 + UnicodeString( " for locale: ")+ UnicodeString(localeID) ); 1229 } 1230 if (U_FAILURE(status)){ 1231 errln((UnicodeString)"FAIL: Status " + (int32_t)status); 1232 } 1233 delete currencyFmt; 1234 } 1235 } 1236 1237 // ------------------------------------- 1238 1239 /** 1240 * Test the Currency object handling, new as of ICU 2.2. 1241 */ 1242 void NumberFormatTest::TestCurrencyObject() { 1243 UErrorCode ec = U_ZERO_ERROR; 1244 NumberFormat* fmt = 1245 NumberFormat::createCurrencyInstance(Locale::getUS(), ec); 1246 1247 if (U_FAILURE(ec)) { 1248 dataerrln("FAIL: getCurrencyInstance(US) - %s", u_errorName(ec)); 1249 delete fmt; 1250 return; 1251 } 1252 1253 Locale null("", "", ""); 1254 1255 expectCurrency(*fmt, null, 1234.56, "$1,234.56"); 1256 1257 expectCurrency(*fmt, Locale::getFrance(), 1258 1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro 1259 1260 expectCurrency(*fmt, Locale::getJapan(), 1261 1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen 1262 1263 expectCurrency(*fmt, Locale("fr", "CH", ""), 1264 1234.56, "CHF1,234.56"); // no more 0.05 rounding here, see cldrbug 5548 1265 1266 expectCurrency(*fmt, Locale::getUS(), 1267 1234.56, "$1,234.56"); 1268 1269 delete fmt; 1270 fmt = NumberFormat::createCurrencyInstance(Locale::getFrance(), ec); 1271 1272 if (U_FAILURE(ec)) { 1273 errln("FAIL: getCurrencyInstance(FRANCE)"); 1274 delete fmt; 1275 return; 1276 } 1277 1278 expectCurrency(*fmt, null, 1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); 1279 1280 expectCurrency(*fmt, Locale::getJapan(), 1281 1234.56, CharsToUnicodeString("1 235 JPY")); // Yen 1282 1283 expectCurrency(*fmt, Locale("fr", "CH", ""), 1284 1234.56, "1 234,56 CHF"); // no more 0.05 rounding here, see cldrbug 5548 1285 1286 expectCurrency(*fmt, Locale::getUS(), 1287 1234.56, "1 234,56 $US"); 1288 1289 expectCurrency(*fmt, Locale::getFrance(), 1290 1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); // Euro 1291 1292 delete fmt; 1293 } 1294 1295 // ------------------------------------- 1296 1297 /** 1298 * Do rudimentary testing of parsing. 1299 */ 1300 void 1301 NumberFormatTest::TestParse(void) 1302 { 1303 UErrorCode status = U_ZERO_ERROR; 1304 UnicodeString arg("0"); 1305 DecimalFormat* format = new DecimalFormat("00", status); 1306 //try { 1307 Formattable n; format->parse(arg, n, status); 1308 logln((UnicodeString)"parse(" + arg + ") = " + n.getLong()); 1309 if (n.getType() != Formattable::kLong || 1310 n.getLong() != 0) errln((UnicodeString)"FAIL: Expected 0"); 1311 delete format; 1312 if (U_FAILURE(status)) errcheckln(status, (UnicodeString)"FAIL: Status " + u_errorName(status)); 1313 //} 1314 //catch(Exception e) { 1315 // errln((UnicodeString)"Exception caught: " + e); 1316 //} 1317 } 1318 1319 // ------------------------------------- 1320 1321 static const char *lenientAffixTestCases[] = { 1322 "(1)", 1323 "( 1)", 1324 "(1 )", 1325 "( 1 )" 1326 }; 1327 1328 static const char *lenientMinusTestCases[] = { 1329 "-5", 1330 "\\u22125", 1331 "\\u20105" 1332 }; 1333 1334 static const char *lenientCurrencyTestCases[] = { 1335 "$1,000", 1336 "$ 1,000", 1337 "$1000", 1338 "$ 1000", 1339 "$1 000.00", 1340 "$ 1 000.00", 1341 "$ 1\\u00A0000.00", 1342 "1000.00" 1343 }; 1344 1345 // changed from () to - per cldrbug 5674 1346 static const char *lenientNegativeCurrencyTestCases[] = { 1347 "-$1,000", 1348 "-$ 1,000", 1349 "-$1000", 1350 "-$ 1000", 1351 "-$1 000.00", 1352 "-$ 1 000.00", 1353 "- $ 1,000.00 ", 1354 "-$ 1\\u00A0000.00", 1355 "-1000.00" 1356 }; 1357 1358 static const char *lenientPercentTestCases[] = { 1359 "25%", 1360 " 25%", 1361 " 25 %", 1362 "25 %", 1363 "25\\u00A0%", 1364 "25" 1365 }; 1366 1367 static const char *lenientNegativePercentTestCases[] = { 1368 "-25%", 1369 " -25%", 1370 " - 25%", 1371 "- 25 %", 1372 " - 25 %", 1373 "-25 %", 1374 "-25\\u00A0%", 1375 "-25", 1376 "- 25" 1377 }; 1378 1379 static const char *strictFailureTestCases[] = { 1380 " 1000", 1381 "10,00", 1382 "1,000,.0" 1383 }; 1384 1385 #define ARRAY_SIZE(array) ((int32_t) (sizeof (array) / sizeof(array[0]))) 1386 1387 /** 1388 * Test lenient parsing. 1389 */ 1390 void 1391 NumberFormatTest::TestLenientParse(void) 1392 { 1393 UErrorCode status = U_ZERO_ERROR; 1394 DecimalFormat *format = new DecimalFormat("(#,##0)", status); 1395 Formattable n; 1396 1397 if (format == NULL || U_FAILURE(status)) { 1398 dataerrln("Unable to create DecimalFormat (#,##0) - %s", u_errorName(status)); 1399 } else { 1400 format->setLenient(TRUE); 1401 for (int32_t t = 0; t < ARRAY_SIZE (lenientAffixTestCases); t += 1) { 1402 UnicodeString testCase = ctou(lenientAffixTestCases[t]); 1403 1404 format->parse(testCase, n, status); 1405 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); 1406 1407 if (U_FAILURE(status) || n.getType() != Formattable::kLong || 1408 n.getLong() != 1) { 1409 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientAffixTestCases[t] + (UnicodeString) "\""); 1410 status = U_ZERO_ERROR; 1411 } 1412 } 1413 delete format; 1414 } 1415 1416 Locale en_US("en_US"); 1417 Locale sv_SE("sv_SE"); 1418 1419 NumberFormat *mFormat = NumberFormat::createInstance(sv_SE, UNUM_DECIMAL, status); 1420 1421 if (mFormat == NULL || U_FAILURE(status)) { 1422 dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status)); 1423 } else { 1424 mFormat->setLenient(TRUE); 1425 for (int32_t t = 0; t < ARRAY_SIZE(lenientMinusTestCases); t += 1) { 1426 UnicodeString testCase = ctou(lenientMinusTestCases[t]); 1427 1428 mFormat->parse(testCase, n, status); 1429 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); 1430 1431 if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) { 1432 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\""); 1433 status = U_ZERO_ERROR; 1434 } 1435 } 1436 delete mFormat; 1437 } 1438 1439 mFormat = NumberFormat::createInstance(en_US, UNUM_DECIMAL, status); 1440 1441 if (mFormat == NULL || U_FAILURE(status)) { 1442 dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status)); 1443 } else { 1444 mFormat->setLenient(TRUE); 1445 for (int32_t t = 0; t < ARRAY_SIZE(lenientMinusTestCases); t += 1) { 1446 UnicodeString testCase = ctou(lenientMinusTestCases[t]); 1447 1448 mFormat->parse(testCase, n, status); 1449 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); 1450 1451 if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) { 1452 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\""); 1453 status = U_ZERO_ERROR; 1454 } 1455 } 1456 delete mFormat; 1457 } 1458 1459 NumberFormat *cFormat = NumberFormat::createInstance(en_US, UNUM_CURRENCY, status); 1460 1461 if (cFormat == NULL || U_FAILURE(status)) { 1462 dataerrln("Unable to create NumberFormat (en_US, UNUM_CURRENCY) - %s", u_errorName(status)); 1463 } else { 1464 cFormat->setLenient(TRUE); 1465 for (int32_t t = 0; t < ARRAY_SIZE (lenientCurrencyTestCases); t += 1) { 1466 UnicodeString testCase = ctou(lenientCurrencyTestCases[t]); 1467 1468 cFormat->parse(testCase, n, status); 1469 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); 1470 1471 if (U_FAILURE(status) ||n.getType() != Formattable::kLong || 1472 n.getLong() != 1000) { 1473 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientCurrencyTestCases[t] + (UnicodeString) "\""); 1474 status = U_ZERO_ERROR; 1475 } 1476 } 1477 1478 for (int32_t t = 0; t < ARRAY_SIZE (lenientNegativeCurrencyTestCases); t += 1) { 1479 UnicodeString testCase = ctou(lenientNegativeCurrencyTestCases[t]); 1480 1481 cFormat->parse(testCase, n, status); 1482 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); 1483 1484 if (U_FAILURE(status) ||n.getType() != Formattable::kLong || 1485 n.getLong() != -1000) { 1486 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativeCurrencyTestCases[t] + (UnicodeString) "\""); 1487 status = U_ZERO_ERROR; 1488 } 1489 } 1490 1491 delete cFormat; 1492 } 1493 1494 NumberFormat *pFormat = NumberFormat::createPercentInstance(en_US, status); 1495 1496 if (pFormat == NULL || U_FAILURE(status)) { 1497 dataerrln("Unable to create NumberFormat::createPercentInstance (en_US) - %s", u_errorName(status)); 1498 } else { 1499 pFormat->setLenient(TRUE); 1500 for (int32_t t = 0; t < ARRAY_SIZE (lenientPercentTestCases); t += 1) { 1501 UnicodeString testCase = ctou(lenientPercentTestCases[t]); 1502 1503 pFormat->parse(testCase, n, status); 1504 logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble()); 1505 1506 if (U_FAILURE(status) ||n.getType() != Formattable::kDouble || 1507 n.getDouble() != 0.25) { 1508 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientPercentTestCases[t] + (UnicodeString) "\""); 1509 status = U_ZERO_ERROR; 1510 } 1511 } 1512 1513 for (int32_t t = 0; t < ARRAY_SIZE (lenientNegativePercentTestCases); t += 1) { 1514 UnicodeString testCase = ctou(lenientNegativePercentTestCases[t]); 1515 1516 pFormat->parse(testCase, n, status); 1517 logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble()); 1518 1519 if (U_FAILURE(status) ||n.getType() != Formattable::kDouble || 1520 n.getDouble() != -0.25) { 1521 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativePercentTestCases[t] + (UnicodeString) "\""); 1522 status = U_ZERO_ERROR; 1523 } 1524 } 1525 1526 delete pFormat; 1527 } 1528 1529 // Test cases that should fail with a strict parse and pass with a 1530 // lenient parse. 1531 NumberFormat *nFormat = NumberFormat::createInstance(en_US, status); 1532 1533 if (nFormat == NULL || U_FAILURE(status)) { 1534 dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status)); 1535 } else { 1536 // first, make sure that they fail with a strict parse 1537 for (int32_t t = 0; t < ARRAY_SIZE(strictFailureTestCases); t += 1) { 1538 UnicodeString testCase = ctou(strictFailureTestCases[t]); 1539 1540 nFormat->parse(testCase, n, status); 1541 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); 1542 1543 if (! U_FAILURE(status)) { 1544 errln((UnicodeString)"Strict Parse succeeded for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\""); 1545 } 1546 1547 status = U_ZERO_ERROR; 1548 } 1549 1550 // then, make sure that they pass with a lenient parse 1551 nFormat->setLenient(TRUE); 1552 for (int32_t t = 0; t < ARRAY_SIZE(strictFailureTestCases); t += 1) { 1553 UnicodeString testCase = ctou(strictFailureTestCases[t]); 1554 1555 nFormat->parse(testCase, n, status); 1556 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong()); 1557 1558 if (U_FAILURE(status) ||n.getType() != Formattable::kLong || 1559 n.getLong() != 1000) { 1560 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\""); 1561 status = U_ZERO_ERROR; 1562 } 1563 } 1564 1565 delete nFormat; 1566 } 1567 } 1568 1569 // ------------------------------------- 1570 1571 /** 1572 * Test proper rounding by the format method. 1573 */ 1574 void 1575 NumberFormatTest::TestRounding487(void) 1576 { 1577 UErrorCode status = U_ZERO_ERROR; 1578 NumberFormat *nf = NumberFormat::createInstance(status); 1579 if (U_FAILURE(status)) { 1580 dataerrln("Error calling NumberFormat::createInstance()"); 1581 return; 1582 } 1583 1584 roundingTest(*nf, 0.00159999, 4, "0.0016"); 1585 roundingTest(*nf, 0.00995, 4, "0.01"); 1586 1587 roundingTest(*nf, 12.3995, 3, "12.4"); 1588 1589 roundingTest(*nf, 12.4999, 0, "12"); 1590 roundingTest(*nf, - 19.5, 0, "-20"); 1591 delete nf; 1592 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status); 1593 } 1594 1595 /** 1596 * Test the functioning of the secondary grouping value. 1597 */ 1598 void NumberFormatTest::TestSecondaryGrouping(void) { 1599 UErrorCode status = U_ZERO_ERROR; 1600 DecimalFormatSymbols US(Locale::getUS(), status); 1601 CHECK(status, "DecimalFormatSymbols ct"); 1602 1603 DecimalFormat f("#,##,###", US, status); 1604 CHECK(status, "DecimalFormat ct"); 1605 1606 expect2(f, (int32_t)123456789L, "12,34,56,789"); 1607 expectPat(f, "#,##,###"); 1608 f.applyPattern("#,###", status); 1609 CHECK(status, "applyPattern"); 1610 1611 f.setSecondaryGroupingSize(4); 1612 expect2(f, (int32_t)123456789L, "12,3456,789"); 1613 expectPat(f, "#,####,###"); 1614 NumberFormat *g = NumberFormat::createInstance(Locale("hi", "IN"), status); 1615 CHECK_DATA(status, "createInstance(hi_IN)"); 1616 1617 UnicodeString out; 1618 int32_t l = (int32_t)1876543210L; 1619 g->format(l, out); 1620 delete g; 1621 // expect "1,87,65,43,210", but with Hindi digits 1622 // 01234567890123 1623 UBool ok = TRUE; 1624 if (out.length() != 14) { 1625 ok = FALSE; 1626 } else { 1627 for (int32_t i=0; i<out.length(); ++i) { 1628 UBool expectGroup = FALSE; 1629 switch (i) { 1630 case 1: 1631 case 4: 1632 case 7: 1633 case 10: 1634 expectGroup = TRUE; 1635 break; 1636 } 1637 // Later -- fix this to get the actual grouping 1638 // character from the resource bundle. 1639 UBool isGroup = (out.charAt(i) == 0x002C); 1640 if (isGroup != expectGroup) { 1641 ok = FALSE; 1642 break; 1643 } 1644 } 1645 } 1646 if (!ok) { 1647 errln((UnicodeString)"FAIL Expected " + l + 1648 " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" + 1649 escape(out) + "\""); 1650 } else { 1651 logln((UnicodeString)"Ok " + l + 1652 " x hi_IN -> \"" + 1653 escape(out) + "\""); 1654 } 1655 } 1656 1657 void NumberFormatTest::TestWhiteSpaceParsing(void) { 1658 UErrorCode ec = U_ZERO_ERROR; 1659 DecimalFormatSymbols US(Locale::getUS(), ec); 1660 DecimalFormat fmt("a b#0c ", US, ec); 1661 if (U_FAILURE(ec)) { 1662 errcheckln(ec, "FAIL: Constructor - %s", u_errorName(ec)); 1663 return; 1664 } 1665 int32_t n = 1234; 1666 expect(fmt, "a b1234c ", n); 1667 expect(fmt, "a b1234c ", n); 1668 } 1669 1670 /** 1671 * Test currencies whose display name is a ChoiceFormat. 1672 */ 1673 void NumberFormatTest::TestComplexCurrency() { 1674 1675 // UErrorCode ec = U_ZERO_ERROR; 1676 // Locale loc("kn", "IN", ""); 1677 // NumberFormat* fmt = NumberFormat::createCurrencyInstance(loc, ec); 1678 // if (U_SUCCESS(ec)) { 1679 // expect2(*fmt, 1.0, CharsToUnicodeString("Re.\\u00A01.00")); 1680 // Use .00392625 because that's 2^-8. Any value less than 0.005 is fine. 1681 // expect(*fmt, 1.00390625, CharsToUnicodeString("Re.\\u00A01.00")); // tricky 1682 // expect2(*fmt, 12345678.0, CharsToUnicodeString("Rs.\\u00A01,23,45,678.00")); 1683 // expect2(*fmt, 0.5, CharsToUnicodeString("Rs.\\u00A00.50")); 1684 // expect2(*fmt, -1.0, CharsToUnicodeString("-Re.\\u00A01.00")); 1685 // expect2(*fmt, -10.0, CharsToUnicodeString("-Rs.\\u00A010.00")); 1686 // } else { 1687 // errln("FAIL: getCurrencyInstance(kn_IN)"); 1688 // } 1689 // delete fmt; 1690 1691 } 1692 1693 // ------------------------------------- 1694 1695 void 1696 NumberFormatTest::roundingTest(NumberFormat& nf, double x, int32_t maxFractionDigits, const char* expected) 1697 { 1698 nf.setMaximumFractionDigits(maxFractionDigits); 1699 UnicodeString out; nf.format(x, out); 1700 logln((UnicodeString)"" + x + " formats with " + maxFractionDigits + " fractional digits to " + out); 1701 if (!(out==expected)) errln((UnicodeString)"FAIL: Expected " + expected); 1702 } 1703 1704 /** 1705 * Upgrade to alphaWorks 1706 */ 1707 void NumberFormatTest::TestExponent(void) { 1708 UErrorCode status = U_ZERO_ERROR; 1709 DecimalFormatSymbols US(Locale::getUS(), status); 1710 CHECK(status, "DecimalFormatSymbols constructor"); 1711 DecimalFormat fmt1(UnicodeString("0.###E0"), US, status); 1712 CHECK(status, "DecimalFormat(0.###E0)"); 1713 DecimalFormat fmt2(UnicodeString("0.###E+0"), US, status); 1714 CHECK(status, "DecimalFormat(0.###E+0)"); 1715 int32_t n = 1234; 1716 expect2(fmt1, n, "1.234E3"); 1717 expect2(fmt2, n, "1.234E+3"); 1718 expect(fmt1, "1.234E+3", n); // Either format should parse "E+3" 1719 } 1720 1721 /** 1722 * Upgrade to alphaWorks 1723 */ 1724 void NumberFormatTest::TestScientific(void) { 1725 UErrorCode status = U_ZERO_ERROR; 1726 DecimalFormatSymbols US(Locale::getUS(), status); 1727 CHECK(status, "DecimalFormatSymbols constructor"); 1728 1729 // Test pattern round-trip 1730 const char* PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000", 1731 "0.###E0;[0.###E0]" }; 1732 int32_t PAT_length = (int32_t)(sizeof(PAT) / sizeof(PAT[0])); 1733 int32_t DIGITS[] = { 1734 // min int, max int, min frac, max frac 1735 0, 1, 0, 0, // "#E0" 1736 1, 1, 0, 4, // "0.####E0" 1737 2, 2, 3, 3, // "00.000E00" 1738 1, 3, 0, 4, // "##0.####E000" 1739 1, 1, 0, 3, // "0.###E0;[0.###E0]" 1740 }; 1741 for (int32_t i=0; i<PAT_length; ++i) { 1742 UnicodeString pat(PAT[i]); 1743 DecimalFormat df(pat, US, status); 1744 CHECK(status, "DecimalFormat constructor"); 1745 UnicodeString pat2; 1746 df.toPattern(pat2); 1747 if (pat == pat2) { 1748 logln(UnicodeString("Ok Pattern rt \"") + 1749 pat + "\" -> \"" + 1750 pat2 + "\""); 1751 } else { 1752 errln(UnicodeString("FAIL Pattern rt \"") + 1753 pat + "\" -> \"" + 1754 pat2 + "\""); 1755 } 1756 // Make sure digit counts match what we expect 1757 if (df.getMinimumIntegerDigits() != DIGITS[4*i] || 1758 df.getMaximumIntegerDigits() != DIGITS[4*i+1] || 1759 df.getMinimumFractionDigits() != DIGITS[4*i+2] || 1760 df.getMaximumFractionDigits() != DIGITS[4*i+3]) { 1761 errln(UnicodeString("FAIL \"" + pat + 1762 "\" min/max int; min/max frac = ") + 1763 df.getMinimumIntegerDigits() + "/" + 1764 df.getMaximumIntegerDigits() + ";" + 1765 df.getMinimumFractionDigits() + "/" + 1766 df.getMaximumFractionDigits() + ", expect " + 1767 DIGITS[4*i] + "/" + 1768 DIGITS[4*i+1] + ";" + 1769 DIGITS[4*i+2] + "/" + 1770 DIGITS[4*i+3]); 1771 } 1772 } 1773 1774 1775 // Test the constructor for default locale. We have to 1776 // manually set the default locale, as there is no 1777 // guarantee that the default locale has the same 1778 // scientific format. 1779 Locale def = Locale::getDefault(); 1780 Locale::setDefault(Locale::getUS(), status); 1781 expect2(NumberFormat::createScientificInstance(status), 1782 12345.678901, 1783 "1.2345678901E4", status); 1784 Locale::setDefault(def, status); 1785 1786 expect2(new DecimalFormat("#E0", US, status), 1787 12345.0, 1788 "1.2345E4", status); 1789 expect(new DecimalFormat("0E0", US, status), 1790 12345.0, 1791 "1E4", status); 1792 expect2(NumberFormat::createScientificInstance(Locale::getUS(), status), 1793 12345.678901, 1794 "1.2345678901E4", status); 1795 expect(new DecimalFormat("##0.###E0", US, status), 1796 12345.0, 1797 "12.34E3", status); 1798 expect(new DecimalFormat("##0.###E0", US, status), 1799 12345.00001, 1800 "12.35E3", status); 1801 expect2(new DecimalFormat("##0.####E0", US, status), 1802 (int32_t) 12345, 1803 "12.345E3", status); 1804 expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status), 1805 12345.678901, 1806 "1,2345678901E4", status); 1807 expect(new DecimalFormat("##0.####E0", US, status), 1808 789.12345e-9, 1809 "789.12E-9", status); 1810 expect2(new DecimalFormat("##0.####E0", US, status), 1811 780.e-9, 1812 "780E-9", status); 1813 expect(new DecimalFormat(".###E0", US, status), 1814 45678.0, 1815 ".457E5", status); 1816 expect2(new DecimalFormat(".###E0", US, status), 1817 (int32_t) 0, 1818 ".0E0", status); 1819 /* 1820 expect(new DecimalFormat[] { new DecimalFormat("#E0", US), 1821 new DecimalFormat("##E0", US), 1822 new DecimalFormat("####E0", US), 1823 new DecimalFormat("0E0", US), 1824 new DecimalFormat("00E0", US), 1825 new DecimalFormat("000E0", US), 1826 }, 1827 new Long(45678000), 1828 new String[] { "4.5678E7", 1829 "45.678E6", 1830 "4567.8E4", 1831 "5E7", 1832 "46E6", 1833 "457E5", 1834 } 1835 ); 1836 ! 1837 ! Unroll this test into individual tests below... 1838 ! 1839 */ 1840 expect2(new DecimalFormat("#E0", US, status), 1841 (int32_t) 45678000, "4.5678E7", status); 1842 expect2(new DecimalFormat("##E0", US, status), 1843 (int32_t) 45678000, "45.678E6", status); 1844 expect2(new DecimalFormat("####E0", US, status), 1845 (int32_t) 45678000, "4567.8E4", status); 1846 expect(new DecimalFormat("0E0", US, status), 1847 (int32_t) 45678000, "5E7", status); 1848 expect(new DecimalFormat("00E0", US, status), 1849 (int32_t) 45678000, "46E6", status); 1850 expect(new DecimalFormat("000E0", US, status), 1851 (int32_t) 45678000, "457E5", status); 1852 /* 1853 expect(new DecimalFormat("###E0", US, status), 1854 new Object[] { new Double(0.0000123), "12.3E-6", 1855 new Double(0.000123), "123E-6", 1856 new Double(0.00123), "1.23E-3", 1857 new Double(0.0123), "12.3E-3", 1858 new Double(0.123), "123E-3", 1859 new Double(1.23), "1.23E0", 1860 new Double(12.3), "12.3E0", 1861 new Double(123), "123E0", 1862 new Double(1230), "1.23E3", 1863 }); 1864 ! 1865 ! Unroll this test into individual tests below... 1866 ! 1867 */ 1868 expect2(new DecimalFormat("###E0", US, status), 1869 0.0000123, "12.3E-6", status); 1870 expect2(new DecimalFormat("###E0", US, status), 1871 0.000123, "123E-6", status); 1872 expect2(new DecimalFormat("###E0", US, status), 1873 0.00123, "1.23E-3", status); 1874 expect2(new DecimalFormat("###E0", US, status), 1875 0.0123, "12.3E-3", status); 1876 expect2(new DecimalFormat("###E0", US, status), 1877 0.123, "123E-3", status); 1878 expect2(new DecimalFormat("###E0", US, status), 1879 1.23, "1.23E0", status); 1880 expect2(new DecimalFormat("###E0", US, status), 1881 12.3, "12.3E0", status); 1882 expect2(new DecimalFormat("###E0", US, status), 1883 123.0, "123E0", status); 1884 expect2(new DecimalFormat("###E0", US, status), 1885 1230.0, "1.23E3", status); 1886 /* 1887 expect(new DecimalFormat("0.#E+00", US, status), 1888 new Object[] { new Double(0.00012), "1.2E-04", 1889 new Long(12000), "1.2E+04", 1890 }); 1891 ! 1892 ! Unroll this test into individual tests below... 1893 ! 1894 */ 1895 expect2(new DecimalFormat("0.#E+00", US, status), 1896 0.00012, "1.2E-04", status); 1897 expect2(new DecimalFormat("0.#E+00", US, status), 1898 (int32_t) 12000, "1.2E+04", status); 1899 } 1900 1901 /** 1902 * Upgrade to alphaWorks 1903 */ 1904 void NumberFormatTest::TestPad(void) { 1905 UErrorCode status = U_ZERO_ERROR; 1906 DecimalFormatSymbols US(Locale::getUS(), status); 1907 CHECK(status, "DecimalFormatSymbols constructor"); 1908 1909 expect2(new DecimalFormat("*^##.##", US, status), 1910 int32_t(0), "^^^^0", status); 1911 expect2(new DecimalFormat("*^##.##", US, status), 1912 -1.3, "^-1.3", status); 1913 expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status), 1914 int32_t(0), "0.0E0______ g-m/s^2", status); 1915 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status), 1916 1.0/3, "333.333E-3_ g-m/s^2", status); 1917 expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status), 1918 int32_t(0), "0.0______ g-m/s^2", status); 1919 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status), 1920 1.0/3, "0.33333__ g-m/s^2", status); 1921 1922 // Test padding before a sign 1923 const char *formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)"; 1924 expect2(new DecimalFormat(formatStr, US, status), 1925 int32_t(-10), "xxxxxxxxxx(10.0)", status); 1926 expect2(new DecimalFormat(formatStr, US, status), 1927 int32_t(-1000),"xxxxxxx(1,000.0)", status); 1928 expect2(new DecimalFormat(formatStr, US, status), 1929 int32_t(-1000000),"xxx(1,000,000.0)", status); 1930 expect2(new DecimalFormat(formatStr, US, status), 1931 -100.37, "xxxxxxxx(100.37)", status); 1932 expect2(new DecimalFormat(formatStr, US, status), 1933 -10456.37, "xxxxx(10,456.37)", status); 1934 expect2(new DecimalFormat(formatStr, US, status), 1935 -1120456.37, "xx(1,120,456.37)", status); 1936 expect2(new DecimalFormat(formatStr, US, status), 1937 -112045600.37, "(112,045,600.37)", status); 1938 expect2(new DecimalFormat(formatStr, US, status), 1939 -1252045600.37,"(1,252,045,600.37)", status); 1940 1941 expect2(new DecimalFormat(formatStr, US, status), 1942 int32_t(10), "xxxxxxxxxxxx10.0", status); 1943 expect2(new DecimalFormat(formatStr, US, status), 1944 int32_t(1000),"xxxxxxxxx1,000.0", status); 1945 expect2(new DecimalFormat(formatStr, US, status), 1946 int32_t(1000000),"xxxxx1,000,000.0", status); 1947 expect2(new DecimalFormat(formatStr, US, status), 1948 100.37, "xxxxxxxxxx100.37", status); 1949 expect2(new DecimalFormat(formatStr, US, status), 1950 10456.37, "xxxxxxx10,456.37", status); 1951 expect2(new DecimalFormat(formatStr, US, status), 1952 1120456.37, "xxxx1,120,456.37", status); 1953 expect2(new DecimalFormat(formatStr, US, status), 1954 112045600.37, "xx112,045,600.37", status); 1955 expect2(new DecimalFormat(formatStr, US, status), 1956 10252045600.37,"10,252,045,600.37", status); 1957 1958 1959 // Test padding between a sign and a number 1960 const char *formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)"; 1961 expect2(new DecimalFormat(formatStr2, US, status), 1962 int32_t(-10), "(10.0xxxxxxxxxx)", status); 1963 expect2(new DecimalFormat(formatStr2, US, status), 1964 int32_t(-1000),"(1,000.0xxxxxxx)", status); 1965 expect2(new DecimalFormat(formatStr2, US, status), 1966 int32_t(-1000000),"(1,000,000.0xxx)", status); 1967 expect2(new DecimalFormat(formatStr2, US, status), 1968 -100.37, "(100.37xxxxxxxx)", status); 1969 expect2(new DecimalFormat(formatStr2, US, status), 1970 -10456.37, "(10,456.37xxxxx)", status); 1971 expect2(new DecimalFormat(formatStr2, US, status), 1972 -1120456.37, "(1,120,456.37xx)", status); 1973 expect2(new DecimalFormat(formatStr2, US, status), 1974 -112045600.37, "(112,045,600.37)", status); 1975 expect2(new DecimalFormat(formatStr2, US, status), 1976 -1252045600.37,"(1,252,045,600.37)", status); 1977 1978 expect2(new DecimalFormat(formatStr2, US, status), 1979 int32_t(10), "10.0xxxxxxxxxxxx", status); 1980 expect2(new DecimalFormat(formatStr2, US, status), 1981 int32_t(1000),"1,000.0xxxxxxxxx", status); 1982 expect2(new DecimalFormat(formatStr2, US, status), 1983 int32_t(1000000),"1,000,000.0xxxxx", status); 1984 expect2(new DecimalFormat(formatStr2, US, status), 1985 100.37, "100.37xxxxxxxxxx", status); 1986 expect2(new DecimalFormat(formatStr2, US, status), 1987 10456.37, "10,456.37xxxxxxx", status); 1988 expect2(new DecimalFormat(formatStr2, US, status), 1989 1120456.37, "1,120,456.37xxxx", status); 1990 expect2(new DecimalFormat(formatStr2, US, status), 1991 112045600.37, "112,045,600.37xx", status); 1992 expect2(new DecimalFormat(formatStr2, US, status), 1993 10252045600.37,"10,252,045,600.37", status); 1994 1995 //testing the setPadCharacter(UnicodeString) and getPadCharacterString() 1996 DecimalFormat fmt("#", US, status); 1997 CHECK(status, "DecimalFormat constructor"); 1998 UnicodeString padString("P"); 1999 fmt.setPadCharacter(padString); 2000 expectPad(fmt, "*P##.##", DecimalFormat::kPadBeforePrefix, 5, padString); 2001 fmt.setPadCharacter((UnicodeString)"^"); 2002 expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, (UnicodeString)"^"); 2003 //commented untill implementation is complete 2004 /* fmt.setPadCharacter((UnicodeString)"^^^"); 2005 expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^"); 2006 padString.remove(); 2007 padString.append((UChar)0x0061); 2008 padString.append((UChar)0x0302); 2009 fmt.setPadCharacter(padString); 2010 UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000}; 2011 UnicodeString pattern(patternChars); 2012 expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString); 2013 */ 2014 2015 } 2016 2017 /** 2018 * Upgrade to alphaWorks 2019 */ 2020 void NumberFormatTest::TestPatterns2(void) { 2021 UErrorCode status = U_ZERO_ERROR; 2022 DecimalFormatSymbols US(Locale::getUS(), status); 2023 CHECK(status, "DecimalFormatSymbols constructor"); 2024 2025 DecimalFormat fmt("#", US, status); 2026 CHECK(status, "DecimalFormat constructor"); 2027 2028 UChar hat = 0x005E; /*^*/ 2029 2030 expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, hat); 2031 expectPad(fmt, "$*^#", DecimalFormat::kPadAfterPrefix, 2, hat); 2032 expectPad(fmt, "#*^", DecimalFormat::kPadBeforeSuffix, 1, hat); 2033 expectPad(fmt, "#$*^", DecimalFormat::kPadAfterSuffix, 2, hat); 2034 expectPad(fmt, "$*^$#", ILLEGAL); 2035 expectPad(fmt, "#$*^$", ILLEGAL); 2036 expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix, 2037 12, (UChar)0x0078 /*x*/); 2038 expectPad(fmt, "''#0*x", DecimalFormat::kPadBeforeSuffix, 2039 3, (UChar)0x0078 /*x*/); 2040 expectPad(fmt, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix, 2041 10, (UChar)0x0061 /*a*/); 2042 2043 fmt.applyPattern("AA#,##0.00ZZ", status); 2044 CHECK(status, "applyPattern"); 2045 fmt.setPadCharacter(hat); 2046 2047 fmt.setFormatWidth(10); 2048 2049 fmt.setPadPosition(DecimalFormat::kPadBeforePrefix); 2050 expectPat(fmt, "*^AA#,##0.00ZZ"); 2051 2052 fmt.setPadPosition(DecimalFormat::kPadBeforeSuffix); 2053 expectPat(fmt, "AA#,##0.00*^ZZ"); 2054 2055 fmt.setPadPosition(DecimalFormat::kPadAfterSuffix); 2056 expectPat(fmt, "AA#,##0.00ZZ*^"); 2057 2058 // 12 3456789012 2059 UnicodeString exp("AA*^#,##0.00ZZ", ""); 2060 fmt.setFormatWidth(12); 2061 fmt.setPadPosition(DecimalFormat::kPadAfterPrefix); 2062 expectPat(fmt, exp); 2063 2064 fmt.setFormatWidth(13); 2065 // 12 34567890123 2066 expectPat(fmt, "AA*^##,##0.00ZZ"); 2067 2068 fmt.setFormatWidth(14); 2069 // 12 345678901234 2070 expectPat(fmt, "AA*^###,##0.00ZZ"); 2071 2072 fmt.setFormatWidth(15); 2073 // 12 3456789012345 2074 expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case 2075 2076 fmt.setFormatWidth(16); 2077 // 12 34567890123456 2078 expectPat(fmt, "AA*^#,###,##0.00ZZ"); 2079 } 2080 2081 void NumberFormatTest::TestSurrogateSupport(void) { 2082 UErrorCode status = U_ZERO_ERROR; 2083 DecimalFormatSymbols custom(Locale::getUS(), status); 2084 CHECK(status, "DecimalFormatSymbols constructor"); 2085 2086 custom.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, "decimal"); 2087 custom.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, "plus"); 2088 custom.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, " minus "); 2089 custom.setSymbol(DecimalFormatSymbols::kExponentialSymbol, "exponent"); 2090 2091 UnicodeString patternStr("*\\U00010000##.##", ""); 2092 patternStr = patternStr.unescape(); 2093 UnicodeString expStr("\\U00010000\\U00010000\\U00010000\\U000100000", ""); 2094 expStr = expStr.unescape(); 2095 expect2(new DecimalFormat(patternStr, custom, status), 2096 int32_t(0), expStr, status); 2097 2098 status = U_ZERO_ERROR; 2099 expect2(new DecimalFormat("*^##.##", custom, status), 2100 int32_t(0), "^^^^0", status); 2101 status = U_ZERO_ERROR; 2102 expect2(new DecimalFormat("##.##", custom, status), 2103 -1.3, " minus 1decimal3", status); 2104 status = U_ZERO_ERROR; 2105 expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status), 2106 int32_t(0), "0decimal0exponent0 g-m/s^2", status); 2107 status = U_ZERO_ERROR; 2108 expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status), 2109 1.0/3, "333decimal333exponent minus 3 g-m/s^2", status); 2110 status = U_ZERO_ERROR; 2111 expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status), 2112 int32_t(0), "0decimal0 g-m/s^2", status); 2113 status = U_ZERO_ERROR; 2114 expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status), 2115 1.0/3, "0decimal33333 g-m/s^2", status); 2116 2117 UnicodeString zero((UChar32)0x10000); 2118 UnicodeString one((UChar32)0x10001); 2119 UnicodeString two((UChar32)0x10002); 2120 UnicodeString five((UChar32)0x10005); 2121 custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero); 2122 custom.setSymbol(DecimalFormatSymbols::kOneDigitSymbol, one); 2123 custom.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol, two); 2124 custom.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol, five); 2125 expStr = UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", ""); 2126 expStr = expStr.unescape(); 2127 status = U_ZERO_ERROR; 2128 expect2(new DecimalFormat("##0.000", custom, status), 2129 1.25, expStr, status); 2130 2131 custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, (UChar)0x30); 2132 custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "units of money"); 2133 custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, "money separator"); 2134 patternStr = UNICODE_STRING_SIMPLE("0.00 \\u00A4' in your bank account'"); 2135 patternStr = patternStr.unescape(); 2136 expStr = UnicodeString(" minus 20money separator00 units of money in your bank account", ""); 2137 status = U_ZERO_ERROR; 2138 expect2(new DecimalFormat(patternStr, custom, status), 2139 int32_t(-20), expStr, status); 2140 2141 custom.setSymbol(DecimalFormatSymbols::kPercentSymbol, "percent"); 2142 patternStr = "'You''ve lost ' -0.00 %' of your money today'"; 2143 patternStr = patternStr.unescape(); 2144 expStr = UnicodeString(" minus You've lost minus 2000decimal00 percent of your money today", ""); 2145 status = U_ZERO_ERROR; 2146 expect2(new DecimalFormat(patternStr, custom, status), 2147 int32_t(-20), expStr, status); 2148 } 2149 2150 void NumberFormatTest::TestCurrencyPatterns(void) { 2151 int32_t i, locCount; 2152 const Locale* locs = NumberFormat::getAvailableLocales(locCount); 2153 for (i=0; i<locCount; ++i) { 2154 UErrorCode ec = U_ZERO_ERROR; 2155 NumberFormat* nf = NumberFormat::createCurrencyInstance(locs[i], ec); 2156 if (U_FAILURE(ec)) { 2157 errln("FAIL: Can't create NumberFormat(%s) - %s", locs[i].getName(), u_errorName(ec)); 2158 } else { 2159 // Make sure currency formats do not have a variable number 2160 // of fraction digits 2161 int32_t min = nf->getMinimumFractionDigits(); 2162 int32_t max = nf->getMaximumFractionDigits(); 2163 if (min != max) { 2164 UnicodeString a, b; 2165 nf->format(1.0, a); 2166 nf->format(1.125, b); 2167 errln((UnicodeString)"FAIL: " + locs[i].getName() + 2168 " min fraction digits != max fraction digits; " 2169 "x 1.0 => " + escape(a) + 2170 "; x 1.125 => " + escape(b)); 2171 } 2172 2173 // Make sure EURO currency formats have exactly 2 fraction digits 2174 DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf); 2175 if (df != NULL) { 2176 if (u_strcmp(EUR, df->getCurrency()) == 0) { 2177 if (min != 2 || max != 2) { 2178 UnicodeString a; 2179 nf->format(1.0, a); 2180 errln((UnicodeString)"FAIL: " + locs[i].getName() + 2181 " is a EURO format but it does not have 2 fraction digits; " 2182 "x 1.0 => " + 2183 escape(a)); 2184 } 2185 } 2186 } 2187 } 2188 delete nf; 2189 } 2190 } 2191 2192 void NumberFormatTest::TestRegCurrency(void) { 2193 #if !UCONFIG_NO_SERVICE 2194 UErrorCode status = U_ZERO_ERROR; 2195 UChar USD[4]; 2196 ucurr_forLocale("en_US", USD, 4, &status); 2197 UChar YEN[4]; 2198 ucurr_forLocale("ja_JP", YEN, 4, &status); 2199 UChar TMP[4]; 2200 static const UChar QQQ[] = {0x51, 0x51, 0x51, 0}; 2201 if(U_FAILURE(status)) { 2202 errcheckln(status, "Unable to get currency for locale, error %s", u_errorName(status)); 2203 return; 2204 } 2205 2206 UCurrRegistryKey enkey = ucurr_register(YEN, "en_US", &status); 2207 UCurrRegistryKey enUSEUROkey = ucurr_register(QQQ, "en_US_EURO", &status); 2208 2209 ucurr_forLocale("en_US", TMP, 4, &status); 2210 if (u_strcmp(YEN, TMP) != 0) { 2211 errln("FAIL: didn't return YEN registered for en_US"); 2212 } 2213 2214 ucurr_forLocale("en_US_EURO", TMP, 4, &status); 2215 if (u_strcmp(QQQ, TMP) != 0) { 2216 errln("FAIL: didn't return QQQ for en_US_EURO"); 2217 } 2218 2219 int32_t fallbackLen = ucurr_forLocale("en_XX_BAR", TMP, 4, &status); 2220 if (fallbackLen) { 2221 errln("FAIL: tried to fallback en_XX_BAR"); 2222 } 2223 status = U_ZERO_ERROR; // reset 2224 2225 if (!ucurr_unregister(enkey, &status)) { 2226 errln("FAIL: couldn't unregister enkey"); 2227 } 2228 2229 ucurr_forLocale("en_US", TMP, 4, &status); 2230 if (u_strcmp(USD, TMP) != 0) { 2231 errln("FAIL: didn't return USD for en_US after unregister of en_US"); 2232 } 2233 status = U_ZERO_ERROR; // reset 2234 2235 ucurr_forLocale("en_US_EURO", TMP, 4, &status); 2236 if (u_strcmp(QQQ, TMP) != 0) { 2237 errln("FAIL: didn't return QQQ for en_US_EURO after unregister of en_US"); 2238 } 2239 2240 ucurr_forLocale("en_US_BLAH", TMP, 4, &status); 2241 if (u_strcmp(USD, TMP) != 0) { 2242 errln("FAIL: could not find USD for en_US_BLAH after unregister of en"); 2243 } 2244 status = U_ZERO_ERROR; // reset 2245 2246 if (!ucurr_unregister(enUSEUROkey, &status)) { 2247 errln("FAIL: couldn't unregister enUSEUROkey"); 2248 } 2249 2250 ucurr_forLocale("en_US_EURO", TMP, 4, &status); 2251 if (u_strcmp(EUR, TMP) != 0) { 2252 errln("FAIL: didn't return EUR for en_US_EURO after unregister of en_US_EURO"); 2253 } 2254 status = U_ZERO_ERROR; // reset 2255 #endif 2256 } 2257 2258 void NumberFormatTest::TestCurrencyNames(void) { 2259 // Do a basic check of getName() 2260 // USD { "US$", "US Dollar" } // 04/04/1792- 2261 UErrorCode ec = U_ZERO_ERROR; 2262 static const UChar USD[] = {0x55, 0x53, 0x44, 0}; /*USD*/ 2263 static const UChar USX[] = {0x55, 0x53, 0x58, 0}; /*USX*/ 2264 static const UChar CAD[] = {0x43, 0x41, 0x44, 0}; /*CAD*/ 2265 static const UChar ITL[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/ 2266 UBool isChoiceFormat; 2267 int32_t len; 2268 const UBool possibleDataError = TRUE; 2269 // Warning: HARD-CODED LOCALE DATA in this test. If it fails, CHECK 2270 // THE LOCALE DATA before diving into the code. 2271 assertEquals("USD.getName(SYMBOL_NAME)", 2272 UnicodeString("$"), 2273 UnicodeString(ucurr_getName(USD, "en", 2274 UCURR_SYMBOL_NAME, 2275 &isChoiceFormat, &len, &ec)), 2276 possibleDataError); 2277 assertEquals("USD.getName(LONG_NAME)", 2278 UnicodeString("US Dollar"), 2279 UnicodeString(ucurr_getName(USD, "en", 2280 UCURR_LONG_NAME, 2281 &isChoiceFormat, &len, &ec)), 2282 possibleDataError); 2283 assertEquals("CAD.getName(SYMBOL_NAME)", 2284 UnicodeString("CA$"), 2285 UnicodeString(ucurr_getName(CAD, "en", 2286 UCURR_SYMBOL_NAME, 2287 &isChoiceFormat, &len, &ec)), 2288 possibleDataError); 2289 assertEquals("CAD.getName(SYMBOL_NAME)", 2290 UnicodeString("$"), 2291 UnicodeString(ucurr_getName(CAD, "en_CA", 2292 UCURR_SYMBOL_NAME, 2293 &isChoiceFormat, &len, &ec)), 2294 possibleDataError); 2295 assertEquals("USD.getName(SYMBOL_NAME) in en_NZ", 2296 UnicodeString("US$"), 2297 UnicodeString(ucurr_getName(USD, "en_NZ", 2298 UCURR_SYMBOL_NAME, 2299 &isChoiceFormat, &len, &ec)), 2300 possibleDataError); 2301 assertEquals("CAD.getName(SYMBOL_NAME)", 2302 UnicodeString("CA$"), 2303 UnicodeString(ucurr_getName(CAD, "en_NZ", 2304 UCURR_SYMBOL_NAME, 2305 &isChoiceFormat, &len, &ec)), 2306 possibleDataError); 2307 assertEquals("USX.getName(LONG_NAME)", 2308 UnicodeString("USX"), 2309 UnicodeString(ucurr_getName(USX, "en_US", 2310 UCURR_LONG_NAME, 2311 &isChoiceFormat, &len, &ec)), 2312 possibleDataError); 2313 assertSuccess("ucurr_getName", ec); 2314 2315 ec = U_ZERO_ERROR; 2316 2317 // Test that a default or fallback warning is being returned. JB 4239. 2318 ucurr_getName(CAD, "es_ES", UCURR_LONG_NAME, &isChoiceFormat, 2319 &len, &ec); 2320 assertTrue("ucurr_getName (es_ES fallback)", 2321 U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError); 2322 2323 ucurr_getName(CAD, "zh_TW", UCURR_LONG_NAME, &isChoiceFormat, 2324 &len, &ec); 2325 assertTrue("ucurr_getName (zh_TW fallback)", 2326 U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError); 2327 2328 ucurr_getName(CAD, "en_US", UCURR_LONG_NAME, &isChoiceFormat, 2329 &len, &ec); 2330 assertTrue("ucurr_getName (en_US default)", 2331 U_USING_DEFAULT_WARNING == ec || U_USING_FALLBACK_WARNING == ec, TRUE); 2332 2333 ucurr_getName(CAD, "ti", UCURR_LONG_NAME, &isChoiceFormat, 2334 &len, &ec); 2335 assertTrue("ucurr_getName (ti default)", 2336 U_USING_DEFAULT_WARNING == ec, TRUE); 2337 2338 // Test that a default warning is being returned when falling back to root. JB 4536. 2339 ucurr_getName(ITL, "cy", UCURR_LONG_NAME, &isChoiceFormat, 2340 &len, &ec); 2341 assertTrue("ucurr_getName (cy default to root)", 2342 U_USING_DEFAULT_WARNING == ec, TRUE); 2343 2344 // TODO add more tests later 2345 } 2346 2347 void NumberFormatTest::TestCurrencyUnit(void){ 2348 UErrorCode ec = U_ZERO_ERROR; 2349 static const UChar USD[] = {85, 83, 68, 0}; /*USD*/ 2350 static const UChar BAD[] = {63, 63, 63, 0}; /*???*/ 2351 static const UChar BAD2[] = {63, 63, 65, 0}; /*???*/ 2352 CurrencyUnit cu(USD, ec); 2353 assertSuccess("CurrencyUnit", ec); 2354 2355 const UChar * r = cu.getISOCurrency(); // who is the buffer owner ? 2356 assertEquals("getISOCurrency()", USD, r); 2357 2358 CurrencyUnit cu2(cu); 2359 if (!(cu2 == cu)){ 2360 errln("CurrencyUnit copy constructed object should be same"); 2361 } 2362 2363 CurrencyUnit * cu3 = (CurrencyUnit *)cu.clone(); 2364 if (!(*cu3 == cu)){ 2365 errln("CurrencyUnit cloned object should be same"); 2366 } 2367 CurrencyUnit bad(BAD, ec); 2368 assertSuccess("CurrencyUnit", ec); 2369 if (cu.getIndex() == bad.getIndex()) { 2370 errln("Indexes of different currencies should differ."); 2371 } 2372 CurrencyUnit bad2(BAD2, ec); 2373 assertSuccess("CurrencyUnit", ec); 2374 if (bad2.getIndex() != bad.getIndex()) { 2375 errln("Indexes of unrecognized currencies should be the same."); 2376 } 2377 if (bad == bad2) { 2378 errln("Different unrecognized currencies should not be equal."); 2379 } 2380 bad = bad2; 2381 if (bad != bad2) { 2382 errln("Currency unit assignment should be the same."); 2383 } 2384 delete cu3; 2385 } 2386 2387 void NumberFormatTest::TestCurrencyAmount(void){ 2388 UErrorCode ec = U_ZERO_ERROR; 2389 static const UChar USD[] = {85, 83, 68, 0}; /*USD*/ 2390 CurrencyAmount ca(9, USD, ec); 2391 assertSuccess("CurrencyAmount", ec); 2392 2393 CurrencyAmount ca2(ca); 2394 if (!(ca2 == ca)){ 2395 errln("CurrencyAmount copy constructed object should be same"); 2396 } 2397 2398 ca2=ca; 2399 if (!(ca2 == ca)){ 2400 errln("CurrencyAmount assigned object should be same"); 2401 } 2402 2403 CurrencyAmount *ca3 = (CurrencyAmount *)ca.clone(); 2404 if (!(*ca3 == ca)){ 2405 errln("CurrencyAmount cloned object should be same"); 2406 } 2407 delete ca3; 2408 } 2409 2410 void NumberFormatTest::TestSymbolsWithBadLocale(void) { 2411 Locale locDefault; 2412 static const char *badLocales[] = { 2413 // length < ULOC_FULLNAME_CAPACITY 2414 "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME", 2415 2416 // length > ULOC_FULLNAME_CAPACITY 2417 "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME" 2418 }; // expect U_USING_DEFAULT_WARNING for both 2419 2420 unsigned int i; 2421 for (i = 0; i < sizeof(badLocales) / sizeof(char*); i++) { 2422 const char *localeName = badLocales[i]; 2423 Locale locBad(localeName); 2424 UErrorCode status = U_ZERO_ERROR; 2425 UnicodeString intlCurrencySymbol((UChar)0xa4); 2426 2427 intlCurrencySymbol.append((UChar)0xa4); 2428 2429 logln("Current locale is %s", Locale::getDefault().getName()); 2430 Locale::setDefault(locBad, status); 2431 logln("Current locale is %s", Locale::getDefault().getName()); 2432 DecimalFormatSymbols mySymbols(status); 2433 if (status != U_USING_DEFAULT_WARNING) { 2434 errln("DecimalFormatSymbols should return U_USING_DEFAULT_WARNING."); 2435 } 2436 if (strcmp(mySymbols.getLocale().getName(), locBad.getName()) != 0) { 2437 errln("DecimalFormatSymbols does not have the right locale.", locBad.getName()); 2438 } 2439 int symbolEnum = (int)DecimalFormatSymbols::kDecimalSeparatorSymbol; 2440 for (; symbolEnum < (int)DecimalFormatSymbols::kFormatSymbolCount; symbolEnum++) { 2441 UnicodeString symbolString = mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum); 2442 logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum + UnicodeString("] = ") + prettify(symbolString)); 2443 if (symbolString.length() == 0 2444 && symbolEnum != (int)DecimalFormatSymbols::kGroupingSeparatorSymbol 2445 && symbolEnum != (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol) 2446 { 2447 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum); 2448 } 2449 } 2450 2451 status = U_ZERO_ERROR; 2452 Locale::setDefault(locDefault, status); 2453 logln("Current locale is %s", Locale::getDefault().getName()); 2454 } 2455 } 2456 2457 /** 2458 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols 2459 * behave the same, except for memory ownership semantics. (No 2460 * version of this test on Java, since Java has only one method.) 2461 */ 2462 void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) { 2463 UErrorCode ec = U_ZERO_ERROR; 2464 DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), ec); 2465 if (U_FAILURE(ec)) { 2466 errcheckln(ec, "Fail: DecimalFormatSymbols constructor - %s", u_errorName(ec)); 2467 delete sym; 2468 return; 2469 } 2470 UnicodeString pat(" #,##0.00"); 2471 pat.insert(0, (UChar)0x00A4); 2472 DecimalFormat fmt(pat, sym, ec); 2473 if (U_FAILURE(ec)) { 2474 errln("Fail: DecimalFormat constructor"); 2475 return; 2476 } 2477 2478 UnicodeString str; 2479 fmt.format(2350.75, str); 2480 if (str == "$ 2,350.75") { 2481 logln(str); 2482 } else { 2483 dataerrln("Fail: " + str + ", expected $ 2,350.75"); 2484 } 2485 2486 sym = new DecimalFormatSymbols(Locale::getUS(), ec); 2487 if (U_FAILURE(ec)) { 2488 errln("Fail: DecimalFormatSymbols constructor"); 2489 delete sym; 2490 return; 2491 } 2492 sym->setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q"); 2493 fmt.adoptDecimalFormatSymbols(sym); 2494 2495 str.truncate(0); 2496 fmt.format(2350.75, str); 2497 if (str == "Q 2,350.75") { 2498 logln(str); 2499 } else { 2500 dataerrln("Fail: adoptDecimalFormatSymbols -> " + str + ", expected Q 2,350.75"); 2501 } 2502 2503 sym = new DecimalFormatSymbols(Locale::getUS(), ec); 2504 if (U_FAILURE(ec)) { 2505 errln("Fail: DecimalFormatSymbols constructor"); 2506 delete sym; 2507 return; 2508 } 2509 DecimalFormat fmt2(pat, sym, ec); 2510 if (U_FAILURE(ec)) { 2511 errln("Fail: DecimalFormat constructor"); 2512 return; 2513 } 2514 2515 DecimalFormatSymbols sym2(Locale::getUS(), ec); 2516 if (U_FAILURE(ec)) { 2517 errln("Fail: DecimalFormatSymbols constructor"); 2518 return; 2519 } 2520 sym2.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q"); 2521 fmt2.setDecimalFormatSymbols(sym2); 2522 2523 str.truncate(0); 2524 fmt2.format(2350.75, str); 2525 if (str == "Q 2,350.75") { 2526 logln(str); 2527 } else { 2528 dataerrln("Fail: setDecimalFormatSymbols -> " + str + ", expected Q 2,350.75"); 2529 } 2530 } 2531 2532 void NumberFormatTest::TestPerMill() { 2533 UErrorCode ec = U_ZERO_ERROR; 2534 UnicodeString str; 2535 DecimalFormat fmt(ctou("###.###\\u2030"), ec); 2536 if (!assertSuccess("DecimalFormat ct", ec)) return; 2537 assertEquals("0.4857 x ###.###\\u2030", 2538 ctou("485.7\\u2030"), fmt.format(0.4857, str)); 2539 2540 DecimalFormatSymbols sym(Locale::getUS(), ec); 2541 sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, ctou("m")); 2542 DecimalFormat fmt2("", sym, ec); 2543 fmt2.applyLocalizedPattern("###.###m", ec); 2544 if (!assertSuccess("setup", ec)) return; 2545 str.truncate(0); 2546 assertEquals("0.4857 x ###.###m", 2547 "485.7m", fmt2.format(0.4857, str)); 2548 } 2549 2550 /** 2551 * Generic test for patterns that should be legal/illegal. 2552 */ 2553 void NumberFormatTest::TestIllegalPatterns() { 2554 // Test cases: 2555 // Prefix with "-:" for illegal patterns 2556 // Prefix with "+:" for legal patterns 2557 const char* DATA[] = { 2558 // Unquoted special characters in the suffix are illegal 2559 "-:000.000|###", 2560 "+:000.000'|###'", 2561 0 2562 }; 2563 for (int32_t i=0; DATA[i]; ++i) { 2564 const char* pat=DATA[i]; 2565 UBool valid = (*pat) == '+'; 2566 pat += 2; 2567 UErrorCode ec = U_ZERO_ERROR; 2568 DecimalFormat fmt(pat, ec); // locale doesn't matter here 2569 if (U_SUCCESS(ec) == valid) { 2570 logln("Ok: pattern \"%s\": %s", 2571 pat, u_errorName(ec)); 2572 } else { 2573 errcheckln(ec, "FAIL: pattern \"%s\" should have %s; got %s", 2574 pat, (valid?"succeeded":"failed"), 2575 u_errorName(ec)); 2576 } 2577 } 2578 } 2579 2580 //---------------------------------------------------------------------- 2581 2582 static const char* KEYWORDS[] = { 2583 /*0*/ "ref=", // <reference pattern to parse numbers> 2584 /*1*/ "loc=", // <locale for formats> 2585 /*2*/ "f:", // <pattern or '-'> <number> <exp. string> 2586 /*3*/ "fp:", // <pattern or '-'> <number> <exp. string> <exp. number> 2587 /*4*/ "rt:", // <pattern or '-'> <(exp.) number> <(exp.) string> 2588 /*5*/ "p:", // <pattern or '-'> <string> <exp. number> 2589 /*6*/ "perr:", // <pattern or '-'> <invalid string> 2590 /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'> 2591 /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt> 2592 0 2593 }; 2594 2595 /** 2596 * Return an integer representing the next token from this 2597 * iterator. The integer will be an index into the given list, or 2598 * -1 if there are no more tokens, or -2 if the token is not on 2599 * the list. 2600 */ 2601 static int32_t keywordIndex(const UnicodeString& tok) { 2602 for (int32_t i=0; KEYWORDS[i]!=0; ++i) { 2603 if (tok==KEYWORDS[i]) { 2604 return i; 2605 } 2606 } 2607 return -1; 2608 } 2609 2610 /** 2611 * Parse a CurrencyAmount using the given NumberFormat, with 2612 * the 'delim' character separating the number and the currency. 2613 */ 2614 static void parseCurrencyAmount(const UnicodeString& str, 2615 const NumberFormat& fmt, 2616 UChar delim, 2617 Formattable& result, 2618 UErrorCode& ec) { 2619 UnicodeString num, cur; 2620 int32_t i = str.indexOf(delim); 2621 str.extractBetween(0, i, num); 2622 str.extractBetween(i+1, INT32_MAX, cur); 2623 Formattable n; 2624 fmt.parse(num, n, ec); 2625 result.adoptObject(new CurrencyAmount(n, cur.getTerminatedBuffer(), ec)); 2626 } 2627 2628 void NumberFormatTest::TestCases() { 2629 UErrorCode ec = U_ZERO_ERROR; 2630 TextFile reader("NumberFormatTestCases.txt", "UTF8", ec); 2631 if (U_FAILURE(ec)) { 2632 dataerrln("Couldn't open NumberFormatTestCases.txt"); 2633 return; 2634 } 2635 TokenIterator tokens(&reader); 2636 2637 Locale loc("en", "US", ""); 2638 DecimalFormat *ref = 0, *fmt = 0; 2639 MeasureFormat *mfmt = 0; 2640 UnicodeString pat, tok, mloc, str, out, where, currAmt; 2641 Formattable n; 2642 2643 for (;;) { 2644 ec = U_ZERO_ERROR; 2645 if (!tokens.next(tok, ec)) { 2646 break; 2647 } 2648 where = UnicodeString("(") + tokens.getLineNumber() + ") "; 2649 int32_t cmd = keywordIndex(tok); 2650 switch (cmd) { 2651 case 0: 2652 // ref= <reference pattern> 2653 if (!tokens.next(tok, ec)) goto error; 2654 delete ref; 2655 ref = new DecimalFormat(tok, 2656 new DecimalFormatSymbols(Locale::getUS(), ec), ec); 2657 if (U_FAILURE(ec)) { 2658 dataerrln("Error constructing DecimalFormat"); 2659 goto error; 2660 } 2661 break; 2662 case 1: 2663 // loc= <locale> 2664 if (!tokens.next(tok, ec)) goto error; 2665 loc = Locale::createFromName(CharString().appendInvariantChars(tok, ec).data()); 2666 break; 2667 case 2: // f: 2668 case 3: // fp: 2669 case 4: // rt: 2670 case 5: // p: 2671 if (!tokens.next(tok, ec)) goto error; 2672 if (tok != "-") { 2673 pat = tok; 2674 delete fmt; 2675 fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc, ec), ec); 2676 if (U_FAILURE(ec)) { 2677 errln("FAIL: " + where + "Pattern \"" + pat + "\": " + u_errorName(ec)); 2678 ec = U_ZERO_ERROR; 2679 if (!tokens.next(tok, ec)) goto error; 2680 if (!tokens.next(tok, ec)) goto error; 2681 if (cmd == 3) { 2682 if (!tokens.next(tok, ec)) goto error; 2683 } 2684 continue; 2685 } 2686 } 2687 if (cmd == 2 || cmd == 3 || cmd == 4) { 2688 // f: <pattern or '-'> <number> <exp. string> 2689 // fp: <pattern or '-'> <number> <exp. string> <exp. number> 2690 // rt: <pattern or '-'> <number> <string> 2691 UnicodeString num; 2692 if (!tokens.next(num, ec)) goto error; 2693 if (!tokens.next(str, ec)) goto error; 2694 ref->parse(num, n, ec); 2695 assertSuccess("parse", ec); 2696 assertEquals(where + "\"" + pat + "\".format(" + num + ")", 2697 str, fmt->format(n, out.remove(), ec)); 2698 assertSuccess("format", ec); 2699 if (cmd == 3) { // fp: 2700 if (!tokens.next(num, ec)) goto error; 2701 ref->parse(num, n, ec); 2702 assertSuccess("parse", ec); 2703 } 2704 if (cmd != 2) { // != f: 2705 Formattable m; 2706 fmt->parse(str, m, ec); 2707 assertSuccess("parse", ec); 2708 assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")", 2709 n, m); 2710 } 2711 } 2712 // p: <pattern or '-'> <string to parse> <exp. number> 2713 else { 2714 UnicodeString expstr; 2715 if (!tokens.next(str, ec)) goto error; 2716 if (!tokens.next(expstr, ec)) goto error; 2717 Formattable exp, n; 2718 ref->parse(expstr, exp, ec); 2719 assertSuccess("parse", ec); 2720 fmt->parse(str, n, ec); 2721 assertSuccess("parse", ec); 2722 assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")", 2723 exp, n); 2724 } 2725 break; 2726 case 8: // fpc: 2727 if (!tokens.next(tok, ec)) goto error; 2728 if (tok != "-") { 2729 mloc = tok; 2730 delete mfmt; 2731 mfmt = MeasureFormat::createCurrencyFormat( 2732 Locale::createFromName( 2733 CharString().appendInvariantChars(mloc, ec).data()), ec); 2734 if (U_FAILURE(ec)) { 2735 errln("FAIL: " + where + "Loc \"" + mloc + "\": " + u_errorName(ec)); 2736 ec = U_ZERO_ERROR; 2737 if (!tokens.next(tok, ec)) goto error; 2738 if (!tokens.next(tok, ec)) goto error; 2739 if (!tokens.next(tok, ec)) goto error; 2740 continue; 2741 } 2742 } else if (mfmt == NULL) { 2743 errln("FAIL: " + where + "Loc \"" + mloc + "\": skip case using previous locale, no valid MeasureFormat"); 2744 if (!tokens.next(tok, ec)) goto error; 2745 if (!tokens.next(tok, ec)) goto error; 2746 if (!tokens.next(tok, ec)) goto error; 2747 continue; 2748 } 2749 // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt> 2750 if (!tokens.next(currAmt, ec)) goto error; 2751 if (!tokens.next(str, ec)) goto error; 2752 parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec); 2753 if (assertSuccess("parseCurrencyAmount", ec)) { 2754 assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")", 2755 str, mfmt->format(n, out.remove(), ec)); 2756 assertSuccess("format", ec); 2757 } 2758 if (!tokens.next(currAmt, ec)) goto error; 2759 parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec); 2760 if (assertSuccess("parseCurrencyAmount", ec)) { 2761 Formattable m; 2762 2763 mfmt->parseObject(str, m, ec); 2764 if (assertSuccess("parseCurrency", ec)) { 2765 assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")", 2766 n, m); 2767 } else { 2768 errln("FAIL: source " + str); 2769 } 2770 } 2771 break; 2772 case 6: 2773 // perr: <pattern or '-'> <invalid string> 2774 errln("FAIL: Under construction"); 2775 goto done; 2776 case 7: { 2777 // pat: <pattern> <exp. toPattern, or '-' or 'err'> 2778 UnicodeString testpat; 2779 UnicodeString exppat; 2780 if (!tokens.next(testpat, ec)) goto error; 2781 if (!tokens.next(exppat, ec)) goto error; 2782 UBool err = exppat == "err"; 2783 UBool existingPat = FALSE; 2784 if (testpat == "-") { 2785 if (err) { 2786 errln("FAIL: " + where + "Invalid command \"pat: - err\""); 2787 continue; 2788 } 2789 existingPat = TRUE; 2790 testpat = pat; 2791 } 2792 if (exppat == "-") exppat = testpat; 2793 DecimalFormat* f = 0; 2794 UErrorCode ec2 = U_ZERO_ERROR; 2795 if (existingPat) { 2796 f = fmt; 2797 } else { 2798 f = new DecimalFormat(testpat, ec2); 2799 } 2800 if (U_SUCCESS(ec2)) { 2801 if (err) { 2802 errln("FAIL: " + where + "Invalid pattern \"" + testpat + 2803 "\" was accepted"); 2804 } else { 2805 UnicodeString pat2; 2806 assertEquals(where + "\"" + testpat + "\".toPattern()", 2807 exppat, f->toPattern(pat2)); 2808 } 2809 } else { 2810 if (err) { 2811 logln("Ok: " + where + "Invalid pattern \"" + testpat + 2812 "\" failed: " + u_errorName(ec2)); 2813 } else { 2814 errln("FAIL: " + where + "Valid pattern \"" + testpat + 2815 "\" failed: " + u_errorName(ec2)); 2816 } 2817 } 2818 if (!existingPat) delete f; 2819 } break; 2820 case -1: 2821 errln("FAIL: " + where + "Unknown command \"" + tok + "\""); 2822 goto done; 2823 } 2824 } 2825 goto done; 2826 2827 error: 2828 if (U_SUCCESS(ec)) { 2829 errln("FAIL: Unexpected EOF"); 2830 } else { 2831 errcheckln(ec, "FAIL: " + where + "Unexpected " + u_errorName(ec)); 2832 } 2833 2834 done: 2835 delete mfmt; 2836 delete fmt; 2837 delete ref; 2838 } 2839 2840 2841 //---------------------------------------------------------------------- 2842 // Support methods 2843 //---------------------------------------------------------------------- 2844 2845 UBool NumberFormatTest::equalValue(const Formattable& a, const Formattable& b) { 2846 if (a.getType() == b.getType()) { 2847 return a == b; 2848 } 2849 2850 if (a.getType() == Formattable::kLong) { 2851 if (b.getType() == Formattable::kInt64) { 2852 return a.getLong() == b.getLong(); 2853 } else if (b.getType() == Formattable::kDouble) { 2854 return (double) a.getLong() == b.getDouble(); // TODO check use of double instead of long 2855 } 2856 } else if (a.getType() == Formattable::kDouble) { 2857 if (b.getType() == Formattable::kLong) { 2858 return a.getDouble() == (double) b.getLong(); 2859 } else if (b.getType() == Formattable::kInt64) { 2860 return a.getDouble() == (double)b.getInt64(); 2861 } 2862 } else if (a.getType() == Formattable::kInt64) { 2863 if (b.getType() == Formattable::kLong) { 2864 return a.getInt64() == (int64_t)b.getLong(); 2865 } else if (b.getType() == Formattable::kDouble) { 2866 return a.getInt64() == (int64_t)b.getDouble(); 2867 } 2868 } 2869 return FALSE; 2870 } 2871 2872 void NumberFormatTest::expect3(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) { 2873 // Don't round-trip format test, since we explicitly do it 2874 expect_rbnf(fmt, n, str, FALSE); 2875 expect_rbnf(fmt, str, n); 2876 } 2877 2878 void NumberFormatTest::expect2(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) { 2879 // Don't round-trip format test, since we explicitly do it 2880 expect(fmt, n, str, FALSE); 2881 expect(fmt, str, n); 2882 } 2883 2884 void NumberFormatTest::expect2(NumberFormat* fmt, const Formattable& n, 2885 const UnicodeString& exp, 2886 UErrorCode status) { 2887 if (fmt == NULL || U_FAILURE(status)) { 2888 dataerrln("FAIL: NumberFormat constructor"); 2889 } else { 2890 expect2(*fmt, n, exp); 2891 } 2892 delete fmt; 2893 } 2894 2895 void NumberFormatTest::expect(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) { 2896 UErrorCode status = U_ZERO_ERROR; 2897 Formattable num; 2898 fmt.parse(str, num, status); 2899 if (U_FAILURE(status)) { 2900 dataerrln(UnicodeString("FAIL: Parse failed for \"") + str + "\" - " + u_errorName(status)); 2901 return; 2902 } 2903 UnicodeString pat; 2904 ((DecimalFormat*) &fmt)->toPattern(pat); 2905 if (equalValue(num, n)) { 2906 logln(UnicodeString("Ok \"") + str + "\" x " + 2907 pat + " = " + 2908 toString(num)); 2909 } else { 2910 dataerrln(UnicodeString("FAIL \"") + str + "\" x " + 2911 pat + " = " + 2912 toString(num) + ", expected " + toString(n)); 2913 } 2914 } 2915 2916 void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) { 2917 UErrorCode status = U_ZERO_ERROR; 2918 Formattable num; 2919 fmt.parse(str, num, status); 2920 if (U_FAILURE(status)) { 2921 errln(UnicodeString("FAIL: Parse failed for \"") + str + "\""); 2922 return; 2923 } 2924 if (equalValue(num, n)) { 2925 logln(UnicodeString("Ok \"") + str + " = " + 2926 toString(num)); 2927 } else { 2928 errln(UnicodeString("FAIL \"") + str + " = " + 2929 toString(num) + ", expected " + toString(n)); 2930 } 2931 } 2932 2933 void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const Formattable& n, 2934 const UnicodeString& exp, UBool rt) { 2935 UnicodeString saw; 2936 FieldPosition pos; 2937 UErrorCode status = U_ZERO_ERROR; 2938 fmt.format(n, saw, pos, status); 2939 CHECK(status, "NumberFormat::format"); 2940 if (saw == exp) { 2941 logln(UnicodeString("Ok ") + toString(n) + 2942 " = \"" + 2943 escape(saw) + "\""); 2944 // We should be able to round-trip the formatted string => 2945 // number => string (but not the other way around: number 2946 // => string => number2, might have number2 != number): 2947 if (rt) { 2948 Formattable n2; 2949 fmt.parse(exp, n2, status); 2950 if (U_FAILURE(status)) { 2951 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\""); 2952 return; 2953 } 2954 UnicodeString saw2; 2955 fmt.format(n2, saw2, pos, status); 2956 CHECK(status, "NumberFormat::format"); 2957 if (saw2 != exp) { 2958 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) + 2959 " => \"" + saw2 + "\""); 2960 } 2961 } 2962 } else { 2963 errln(UnicodeString("FAIL ") + toString(n) + 2964 " = \"" + 2965 escape(saw) + "\", expected \"" + exp + "\""); 2966 } 2967 } 2968 2969 void NumberFormatTest::expect(NumberFormat& fmt, const Formattable& n, 2970 const UnicodeString& exp, UBool rt) { 2971 UnicodeString saw; 2972 FieldPosition pos; 2973 UErrorCode status = U_ZERO_ERROR; 2974 fmt.format(n, saw, pos, status); 2975 CHECK(status, "NumberFormat::format"); 2976 UnicodeString pat; 2977 ((DecimalFormat*) &fmt)->toPattern(pat); 2978 if (saw == exp) { 2979 logln(UnicodeString("Ok ") + toString(n) + " x " + 2980 escape(pat) + " = \"" + 2981 escape(saw) + "\""); 2982 // We should be able to round-trip the formatted string => 2983 // number => string (but not the other way around: number 2984 // => string => number2, might have number2 != number): 2985 if (rt) { 2986 Formattable n2; 2987 fmt.parse(exp, n2, status); 2988 if (U_FAILURE(status)) { 2989 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\" - " + u_errorName(status)); 2990 return; 2991 } 2992 UnicodeString saw2; 2993 fmt.format(n2, saw2, pos, status); 2994 CHECK(status, "NumberFormat::format"); 2995 if (saw2 != exp) { 2996 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) + 2997 " => \"" + saw2 + "\""); 2998 } 2999 } 3000 } else { 3001 dataerrln(UnicodeString("FAIL ") + toString(n) + " x " + 3002 escape(pat) + " = \"" + 3003 escape(saw) + "\", expected \"" + exp + "\""); 3004 } 3005 } 3006 3007 void NumberFormatTest::expect(NumberFormat* fmt, const Formattable& n, 3008 const UnicodeString& exp, UBool rt, 3009 UErrorCode status) { 3010 if (fmt == NULL || U_FAILURE(status)) { 3011 dataerrln("FAIL: NumberFormat constructor"); 3012 } else { 3013 expect(*fmt, n, exp, rt); 3014 } 3015 delete fmt; 3016 } 3017 3018 void NumberFormatTest::expectCurrency(NumberFormat& nf, const Locale& locale, 3019 double value, const UnicodeString& string) { 3020 UErrorCode ec = U_ZERO_ERROR; 3021 DecimalFormat& fmt = * (DecimalFormat*) &nf; 3022 const UChar DEFAULT_CURR[] = {45/*-*/,0}; 3023 UChar curr[4]; 3024 u_strcpy(curr, DEFAULT_CURR); 3025 if (*locale.getLanguage() != 0) { 3026 ucurr_forLocale(locale.getName(), curr, 4, &ec); 3027 assertSuccess("ucurr_forLocale", ec); 3028 fmt.setCurrency(curr, ec); 3029 assertSuccess("DecimalFormat::setCurrency", ec); 3030 fmt.setCurrency(curr); //Deprecated variant, for coverage only 3031 } 3032 UnicodeString s; 3033 fmt.format(value, s); 3034 s.findAndReplace((UChar32)0x00A0, (UChar32)0x0020); 3035 3036 // Default display of the number yields "1234.5599999999999" 3037 // instead of "1234.56". Use a formatter to fix this. 3038 NumberFormat* f = 3039 NumberFormat::createInstance(Locale::getUS(), ec); 3040 UnicodeString v; 3041 if (U_FAILURE(ec)) { 3042 // Oops; bad formatter. Use default op+= display. 3043 v = (UnicodeString)"" + value; 3044 } else { 3045 f->setMaximumFractionDigits(4); 3046 f->setGroupingUsed(FALSE); 3047 f->format(value, v); 3048 } 3049 delete f; 3050 3051 if (s == string) { 3052 logln((UnicodeString)"Ok: " + v + " x " + curr + " => " + prettify(s)); 3053 } else { 3054 errln((UnicodeString)"FAIL: " + v + " x " + curr + " => " + prettify(s) + 3055 ", expected " + prettify(string)); 3056 } 3057 } 3058 3059 void NumberFormatTest::expectPat(DecimalFormat& fmt, const UnicodeString& exp) { 3060 UnicodeString pat; 3061 fmt.toPattern(pat); 3062 if (pat == exp) { 3063 logln(UnicodeString("Ok \"") + pat + "\""); 3064 } else { 3065 errln(UnicodeString("FAIL \"") + pat + "\", expected \"" + exp + "\""); 3066 } 3067 } 3068 3069 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat, 3070 int32_t pos) { 3071 expectPad(fmt, pat, pos, 0, (UnicodeString)""); 3072 } 3073 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat, 3074 int32_t pos, int32_t width, UChar pad) { 3075 expectPad(fmt, pat, pos, width, UnicodeString(pad)); 3076 } 3077 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat, 3078 int32_t pos, int32_t width, const UnicodeString& pad) { 3079 int32_t apos = 0, awidth = 0; 3080 UnicodeString apadStr; 3081 UErrorCode status = U_ZERO_ERROR; 3082 fmt.applyPattern(pat, status); 3083 if (U_SUCCESS(status)) { 3084 apos = fmt.getPadPosition(); 3085 awidth = fmt.getFormatWidth(); 3086 apadStr=fmt.getPadCharacterString(); 3087 } else { 3088 apos = -1; 3089 awidth = width; 3090 apadStr = pad; 3091 } 3092 if (apos == pos && awidth == width && apadStr == pad) { 3093 UnicodeString infoStr; 3094 if (pos == ILLEGAL) { 3095 infoStr = UnicodeString(" width=", "") + awidth + UnicodeString(" pad=", "") + apadStr; 3096 } 3097 logln(UnicodeString("Ok \"") + pat + "\" pos=" + apos + infoStr); 3098 } else { 3099 errln(UnicodeString("FAIL \"") + pat + "\" pos=" + apos + 3100 " width=" + awidth + " pad=" + apadStr + 3101 ", expected " + pos + " " + width + " " + pad); 3102 } 3103 } 3104 3105 // This test is flaky b/c the symbols for CNY and JPY are equivalent in this locale - FIXME 3106 void NumberFormatTest::TestCompatibleCurrencies() { 3107 /* 3108 static const UChar JPY[] = {0x4A, 0x50, 0x59, 0}; 3109 static const UChar CNY[] = {0x43, 0x4E, 0x59, 0}; 3110 UErrorCode status = U_ZERO_ERROR; 3111 LocalPointer<NumberFormat> fmt( 3112 NumberFormat::createCurrencyInstance(Locale::getUS(), status)); 3113 if (U_FAILURE(status)) { 3114 errln("Could not create number format instance."); 3115 return; 3116 } 3117 logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__); 3118 expectParseCurrency(*fmt, JPY, 1235, "\\u00A51,235"); 3119 logln("%s:%d - testing parse of fullwidth yen sign\n", __FILE__, __LINE__); 3120 expectParseCurrency(*fmt, JPY, 1235, "\\uFFE51,235"); 3121 logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__); 3122 expectParseCurrency(*fmt, CNY, 1235, "CN\\u00A51,235"); 3123 3124 LocalPointer<NumberFormat> fmtTW( 3125 NumberFormat::createCurrencyInstance(Locale::getTaiwan(), status)); 3126 3127 logln("%s:%d - testing parse of halfwidth yen sign in TW\n", __FILE__, __LINE__); 3128 expectParseCurrency(*fmtTW, CNY, 1235, "\\u00A51,235"); 3129 logln("%s:%d - testing parse of fullwidth yen sign in TW\n", __FILE__, __LINE__); 3130 expectParseCurrency(*fmtTW, CNY, 1235, "\\uFFE51,235"); 3131 3132 LocalPointer<NumberFormat> fmtJP( 3133 NumberFormat::createCurrencyInstance(Locale::getJapan(), status)); 3134 3135 logln("%s:%d - testing parse of halfwidth yen sign in JP\n", __FILE__, __LINE__); 3136 expectParseCurrency(*fmtJP, JPY, 1235, "\\u00A51,235"); 3137 logln("%s:%d - testing parse of fullwidth yen sign in JP\n", __FILE__, __LINE__); 3138 expectParseCurrency(*fmtJP, JPY, 1235, "\\uFFE51,235"); 3139 3140 // more.. 3141 */ 3142 } 3143 3144 void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar* currency, double amount, const char *text) { 3145 ParsePosition ppos; 3146 UnicodeString utext = ctou(text); 3147 LocalPointer<CurrencyAmount> currencyAmount(fmt.parseCurrency(utext, ppos)); 3148 if (!ppos.getIndex()) { 3149 errln(UnicodeString("Parse of ") + utext + " should have succeeded."); 3150 return; 3151 } 3152 UErrorCode status = U_ZERO_ERROR; 3153 3154 char theInfo[100]; 3155 sprintf(theInfo, "For locale %s, string \"%s\", currency ", 3156 fmt.getLocale(ULOC_ACTUAL_LOCALE, status).getBaseName(), 3157 text); 3158 u_austrcpy(theInfo+uprv_strlen(theInfo), currency); 3159 3160 char theOperation[100]; 3161 3162 uprv_strcpy(theOperation, theInfo); 3163 uprv_strcat(theOperation, ", check amount:"); 3164 assertTrue(theOperation, amount == currencyAmount->getNumber().getDouble(status)); 3165 3166 uprv_strcpy(theOperation, theInfo); 3167 uprv_strcat(theOperation, ", check currency:"); 3168 assertEquals(theOperation, currency, currencyAmount->getISOCurrency()); 3169 } 3170 3171 3172 void NumberFormatTest::TestJB3832(){ 3173 const char* localeID = "pt_PT@currency=PTE"; 3174 Locale loc(localeID); 3175 UErrorCode status = U_ZERO_ERROR; 3176 UnicodeString expected(CharsToUnicodeString("1,150$50\\u00A0\\u200B")); // per cldrbug 7670 3177 UnicodeString s; 3178 NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(loc, status); 3179 if(U_FAILURE(status)){ 3180 dataerrln("Could not create currency formatter for locale %s - %s", localeID, u_errorName(status)); 3181 return; 3182 } 3183 currencyFmt->format(1150.50, s); 3184 if(s!=expected){ 3185 errln(UnicodeString("FAIL: Expected: ")+expected 3186 + UnicodeString(" Got: ") + s 3187 + UnicodeString( " for locale: ")+ UnicodeString(localeID) ); 3188 } 3189 if (U_FAILURE(status)){ 3190 errln("FAIL: Status %s", u_errorName(status)); 3191 } 3192 delete currencyFmt; 3193 } 3194 3195 void NumberFormatTest::TestHost() 3196 { 3197 #if U_PLATFORM_USES_ONLY_WIN32_API 3198 Win32NumberTest::testLocales(this); 3199 #endif 3200 Locale loc("en_US@compat=host"); 3201 for (UNumberFormatStyle k = UNUM_DECIMAL; 3202 k < UNUM_FORMAT_STYLE_COUNT; k = (UNumberFormatStyle)(k+1)) { 3203 UErrorCode status = U_ZERO_ERROR; 3204 LocalPointer<NumberFormat> full(NumberFormat::createInstance(loc, k, status)); 3205 if (!NumberFormat::isStyleSupported(k)) { 3206 if (status != U_UNSUPPORTED_ERROR) { 3207 errln("FAIL: expected style %d to be unsupported - %s", 3208 k, u_errorName(status)); 3209 } 3210 continue; 3211 } 3212 if (full.isNull() || U_FAILURE(status)) { 3213 dataerrln("FAIL: Can't create number instance of style %d for host - %s", 3214 k, u_errorName(status)); 3215 return; 3216 } 3217 UnicodeString result1; 3218 Formattable number(10.00); 3219 full->format(number, result1, status); 3220 if (U_FAILURE(status)) { 3221 errln("FAIL: Can't format for host"); 3222 return; 3223 } 3224 Formattable formattable; 3225 full->parse(result1, formattable, status); 3226 if (U_FAILURE(status)) { 3227 errln("FAIL: Can't parse for host"); 3228 return; 3229 } 3230 } 3231 } 3232 3233 void NumberFormatTest::TestHostClone() 3234 { 3235 /* 3236 Verify that a cloned formatter gives the same results 3237 and is useable after the original has been deleted. 3238 */ 3239 // This is mainly important on Windows. 3240 UErrorCode status = U_ZERO_ERROR; 3241 Locale loc("en_US@compat=host"); 3242 UDate now = Calendar::getNow(); 3243 NumberFormat *full = NumberFormat::createInstance(loc, status); 3244 if (full == NULL || U_FAILURE(status)) { 3245 dataerrln("FAIL: Can't create Relative date instance - %s", u_errorName(status)); 3246 return; 3247 } 3248 UnicodeString result1; 3249 full->format(now, result1, status); 3250 Format *fullClone = full->clone(); 3251 delete full; 3252 full = NULL; 3253 3254 UnicodeString result2; 3255 fullClone->format(now, result2, status); 3256 if (U_FAILURE(status)) { 3257 errln("FAIL: format failure."); 3258 } 3259 if (result1 != result2) { 3260 errln("FAIL: Clone returned different result from non-clone."); 3261 } 3262 delete fullClone; 3263 } 3264 3265 void NumberFormatTest::TestCurrencyFormat() 3266 { 3267 // This test is here to increase code coverage. 3268 UErrorCode status = U_ZERO_ERROR; 3269 MeasureFormat *cloneObj; 3270 UnicodeString str; 3271 Formattable toFormat, result; 3272 static const UChar ISO_CODE[4] = {0x0047, 0x0042, 0x0050, 0}; 3273 3274 Locale saveDefaultLocale = Locale::getDefault(); 3275 Locale::setDefault( Locale::getUK(), status ); 3276 if (U_FAILURE(status)) { 3277 errln("couldn't set default Locale!"); 3278 return; 3279 } 3280 3281 MeasureFormat *measureObj = MeasureFormat::createCurrencyFormat(status); 3282 Locale::setDefault( saveDefaultLocale, status ); 3283 if (U_FAILURE(status)){ 3284 dataerrln("FAIL: Status %s", u_errorName(status)); 3285 return; 3286 } 3287 cloneObj = (MeasureFormat *)measureObj->clone(); 3288 if (cloneObj == NULL) { 3289 errln("Clone doesn't work"); 3290 return; 3291 } 3292 toFormat.adoptObject(new CurrencyAmount(1234.56, ISO_CODE, status)); 3293 measureObj->format(toFormat, str, status); 3294 measureObj->parseObject(str, result, status); 3295 if (U_FAILURE(status)){ 3296 errln("FAIL: Status %s", u_errorName(status)); 3297 } 3298 if (result != toFormat) { 3299 errln("measureObj does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat)); 3300 } 3301 status = U_ZERO_ERROR; 3302 str.truncate(0); 3303 cloneObj->format(toFormat, str, status); 3304 cloneObj->parseObject(str, result, status); 3305 if (U_FAILURE(status)){ 3306 errln("FAIL: Status %s", u_errorName(status)); 3307 } 3308 if (result != toFormat) { 3309 errln("Clone does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat)); 3310 } 3311 if (*measureObj != *cloneObj) { 3312 errln("Cloned object is not equal to the original object"); 3313 } 3314 delete measureObj; 3315 delete cloneObj; 3316 3317 status = U_USELESS_COLLATOR_ERROR; 3318 if (MeasureFormat::createCurrencyFormat(status) != NULL) { 3319 errln("createCurrencyFormat should have returned NULL."); 3320 } 3321 } 3322 3323 /* Port of ICU4J rounding test. */ 3324 void NumberFormatTest::TestRounding() { 3325 UErrorCode status = U_ZERO_ERROR; 3326 DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status); 3327 3328 if (U_FAILURE(status)) { 3329 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status)); 3330 return; 3331 } 3332 3333 int roundingIncrements[]={1, 2, 5, 20, 50, 100}; 3334 int testValues[]={0, 300}; 3335 3336 for (int j=0; j<2; j++) { 3337 for (int mode=DecimalFormat::kRoundUp;mode<DecimalFormat::kRoundHalfEven;mode++) { 3338 df->setRoundingMode((DecimalFormat::ERoundingMode)mode); 3339 for (int increment=0; increment<6; increment++) { 3340 double base=testValues[j]; 3341 double rInc=roundingIncrements[increment]; 3342 checkRounding(df, base, 20, rInc); 3343 rInc=1.000000000/rInc; 3344 checkRounding(df, base, 20, rInc); 3345 } 3346 } 3347 } 3348 delete df; 3349 } 3350 3351 void NumberFormatTest::TestRoundingPattern() { 3352 UErrorCode status = U_ZERO_ERROR; 3353 struct { 3354 UnicodeString pattern; 3355 double testCase; 3356 UnicodeString expected; 3357 } tests[] = { 3358 { (UnicodeString)"##0.65", 1.234, (UnicodeString)"1.30" }, 3359 { (UnicodeString)"#50", 1230, (UnicodeString)"1250" } 3360 }; 3361 int32_t numOfTests = (sizeof(tests)/sizeof(tests[0])); 3362 UnicodeString result; 3363 3364 DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status); 3365 if (U_FAILURE(status)) { 3366 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status)); 3367 return; 3368 } 3369 3370 for (int32_t i = 0; i < numOfTests; i++) { 3371 result.remove(); 3372 3373 df->applyPattern(tests[i].pattern, status); 3374 if (U_FAILURE(status)) { 3375 errln("Unable to apply pattern to decimal formatter. - %s", u_errorName(status)); 3376 } 3377 3378 df->format(tests[i].testCase, result); 3379 3380 if (result != tests[i].expected) { 3381 errln("String Pattern Rounding Test Failed: Pattern: \"" + tests[i].pattern + "\" Number: " + tests[i].testCase + " - Got: " + result + " Expected: " + tests[i].expected); 3382 } 3383 } 3384 3385 delete df; 3386 } 3387 3388 void NumberFormatTest::checkRounding(DecimalFormat* df, double base, int iterations, double increment) { 3389 df->setRoundingIncrement(increment); 3390 double lastParsed=INT32_MIN; //Intger.MIN_VALUE 3391 for (int i=-iterations; i<=iterations;i++) { 3392 double iValue=base+(increment*(i*0.1)); 3393 double smallIncrement=0.00000001; 3394 if (iValue!=0) { 3395 smallIncrement*=iValue; 3396 } 3397 //we not only test the value, but some values in a small range around it 3398 lastParsed=checkRound(df, iValue-smallIncrement, lastParsed); 3399 lastParsed=checkRound(df, iValue, lastParsed); 3400 lastParsed=checkRound(df, iValue+smallIncrement, lastParsed); 3401 } 3402 } 3403 3404 double NumberFormatTest::checkRound(DecimalFormat* df, double iValue, double lastParsed) { 3405 UErrorCode status=U_ZERO_ERROR; 3406 UnicodeString formattedDecimal; 3407 double parsed; 3408 Formattable result; 3409 df->format(iValue, formattedDecimal, status); 3410 3411 if (U_FAILURE(status)) { 3412 errln("Error formatting number."); 3413 } 3414 3415 df->parse(formattedDecimal, result, status); 3416 3417 if (U_FAILURE(status)) { 3418 errln("Error parsing number."); 3419 } 3420 3421 parsed=result.getDouble(); 3422 3423 if (lastParsed>parsed) { 3424 errln("Rounding wrong direction! %d > %d", lastParsed, parsed); 3425 } 3426 3427 return lastParsed; 3428 } 3429 3430 void NumberFormatTest::TestNonpositiveMultiplier() { 3431 UErrorCode status = U_ZERO_ERROR; 3432 DecimalFormatSymbols US(Locale::getUS(), status); 3433 CHECK(status, "DecimalFormatSymbols constructor"); 3434 DecimalFormat df(UnicodeString("0"), US, status); 3435 CHECK(status, "DecimalFormat(0)"); 3436 3437 // test zero multiplier 3438 3439 int32_t mult = df.getMultiplier(); 3440 df.setMultiplier(0); 3441 if (df.getMultiplier() != mult) { 3442 errln("DecimalFormat.setMultiplier(0) did not ignore its zero input"); 3443 } 3444 3445 // test negative multiplier 3446 3447 df.setMultiplier(-1); 3448 if (df.getMultiplier() != -1) { 3449 errln("DecimalFormat.setMultiplier(-1) ignored its negative input"); 3450 return; 3451 } 3452 3453 expect(df, "1122.123", -1122.123); 3454 expect(df, "-1122.123", 1122.123); 3455 expect(df, "1.2", -1.2); 3456 expect(df, "-1.2", 1.2); 3457 3458 // Note: the tests with the final parameter of FALSE will not round trip. 3459 // The initial numeric value will format correctly, after the multiplier. 3460 // Parsing the formatted text will be out-of-range for an int64, however. 3461 // The expect() function could be modified to detect this and fall back 3462 // to looking at the decimal parsed value, but it doesn't. 3463 expect(df, U_INT64_MIN, "9223372036854775808", FALSE); 3464 expect(df, U_INT64_MIN+1, "9223372036854775807"); 3465 expect(df, (int64_t)-123, "123"); 3466 expect(df, (int64_t)123, "-123"); 3467 expect(df, U_INT64_MAX-1, "-9223372036854775806"); 3468 expect(df, U_INT64_MAX, "-9223372036854775807"); 3469 3470 df.setMultiplier(-2); 3471 expect(df, -(U_INT64_MIN/2)-1, "-9223372036854775806"); 3472 expect(df, -(U_INT64_MIN/2), "-9223372036854775808"); 3473 expect(df, -(U_INT64_MIN/2)+1, "-9223372036854775810", FALSE); 3474 3475 df.setMultiplier(-7); 3476 expect(df, -(U_INT64_MAX/7)-1, "9223372036854775814", FALSE); 3477 expect(df, -(U_INT64_MAX/7), "9223372036854775807"); 3478 expect(df, -(U_INT64_MAX/7)+1, "9223372036854775800"); 3479 3480 // TODO: uncomment (and fix up) all the following int64_t tests once BigInteger is ported 3481 // (right now the big numbers get turned into doubles and lose tons of accuracy) 3482 //expect2(df, U_INT64_MAX, Int64ToUnicodeString(-U_INT64_MAX)); 3483 //expect2(df, U_INT64_MIN, UnicodeString(Int64ToUnicodeString(U_INT64_MIN), 1)); 3484 //expect2(df, U_INT64_MAX / 2, Int64ToUnicodeString(-(U_INT64_MAX / 2))); 3485 //expect2(df, U_INT64_MIN / 2, Int64ToUnicodeString(-(U_INT64_MIN / 2))); 3486 3487 // TODO: uncomment (and fix up) once BigDecimal is ported and DecimalFormat can handle it 3488 //expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString()); 3489 //expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString()); 3490 //expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString()); 3491 //expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString()); 3492 } 3493 3494 typedef struct { 3495 const char * stringToParse; 3496 int parsedPos; 3497 int errorIndex; 3498 UBool lenient; 3499 } TestSpaceParsingItem; 3500 3501 void 3502 NumberFormatTest::TestSpaceParsing() { 3503 // the data are: 3504 // the string to be parsed, parsed position, parsed error index 3505 const TestSpaceParsingItem DATA[] = { 3506 // TOTO: Update the following TODOs, some may be handled now 3507 {"$124", 4, -1, FALSE}, 3508 {"$124 $124", 4, -1, FALSE}, 3509 {"$124 ", 4, -1, FALSE}, 3510 //{"$ 124 ", 5, -1, FALSE}, // TODO: need to handle space correctly 3511 //{"$\\u00A0124 ", 5, -1, FALSE}, // TODO: need to handle space correctly 3512 {"$ 124 ", 0, 1, FALSE}, // errorIndex used to be 0, now 1 (better) 3513 {"$\\u00A0124 ", 0, 1, FALSE}, // errorIndex used to be 0, now 1 (better) 3514 {" $ 124 ", 0, 0, FALSE}, // TODO: need to handle space correctly 3515 {"124$", 0, 3, FALSE}, // TODO: need to handle space correctly 3516 // {"124 $", 5, -1, FALSE}, // TODO: OK or not, need currency spacing rule 3517 {"124 $", 0, 3, FALSE}, 3518 {"$124", 4, -1, TRUE}, 3519 {"$124 $124", 4, -1, TRUE}, 3520 {"$124 ", 4, -1, TRUE}, 3521 {"$ 124 ", 5, -1, TRUE}, 3522 {"$\\u00A0124 ", 5, -1, TRUE}, 3523 {" $ 124 ", 6, -1, TRUE}, 3524 //{"124$", 4, -1, TRUE}, // TODO: need to handle trailing currency correctly 3525 {"124$", 3, -1, TRUE}, 3526 //{"124 $", 5, -1, TRUE}, // TODO: OK or not, need currency spacing rule 3527 {"124 $", 4, -1, TRUE}, 3528 }; 3529 UErrorCode status = U_ZERO_ERROR; 3530 Locale locale("en_US"); 3531 NumberFormat* foo = NumberFormat::createCurrencyInstance(locale, status); 3532 3533 if (U_FAILURE(status)) { 3534 delete foo; 3535 return; 3536 } 3537 for (uint32_t i = 0; i < sizeof(DATA)/sizeof(DATA[0]); ++i) { 3538 ParsePosition parsePosition(0); 3539 UnicodeString stringToBeParsed = ctou(DATA[i].stringToParse); 3540 int parsedPosition = DATA[i].parsedPos; 3541 int errorIndex = DATA[i].errorIndex; 3542 foo->setLenient(DATA[i].lenient); 3543 Formattable result; 3544 foo->parse(stringToBeParsed, result, parsePosition); 3545 if (parsePosition.getIndex() != parsedPosition || 3546 parsePosition.getErrorIndex() != errorIndex) { 3547 errln("FAILED parse " + stringToBeParsed + "; lenient: " + DATA[i].lenient + "; wrong position, expected: (" + parsedPosition + ", " + errorIndex + "); got (" + parsePosition.getIndex() + ", " + parsePosition.getErrorIndex() + ")"); 3548 } 3549 if (parsePosition.getErrorIndex() == -1 && 3550 result.getType() == Formattable::kLong && 3551 result.getLong() != 124) { 3552 errln("FAILED parse " + stringToBeParsed + "; wrong number, expect: 124, got " + result.getLong()); 3553 } 3554 } 3555 delete foo; 3556 } 3557 3558 /** 3559 * Test using various numbering systems and numbering system keyword. 3560 */ 3561 typedef struct { 3562 const char *localeName; 3563 double value; 3564 UBool isRBNF; 3565 const char *expectedResult; 3566 } TestNumberingSystemItem; 3567 3568 void NumberFormatTest::TestNumberingSystems() { 3569 3570 const TestNumberingSystemItem DATA[] = { 3571 { "en_US@numbers=thai", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" }, 3572 { "en_US@numbers=hebr", 5678.0, TRUE, "\\u05D4\\u05F3\\u05EA\\u05E8\\u05E2\\u05F4\\u05D7" }, 3573 { "en_US@numbers=arabext", 1234.567, FALSE, "\\u06F1\\u066c\\u06F2\\u06F3\\u06F4\\u066b\\u06F5\\u06F6\\u06F7" }, 3574 { "ar_EG", 1234.567, FALSE, "\\u0661\\u066C\\u0662\\u0663\\u0664\\u066b\\u0665\\u0666\\u0667" }, 3575 { "th_TH@numbers=traditional", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" }, // fall back to native per TR35 3576 { "ar_MA", 1234.567, FALSE, "1.234,567" }, 3577 { "en_US@numbers=hanidec", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" }, 3578 { "ta_IN@numbers=native", 1234.567, FALSE, "\\u0BE7,\\u0BE8\\u0BE9\\u0BEA.\\u0BEB\\u0BEC\\u0BED" }, 3579 { "ta_IN@numbers=traditional", 1235.0, TRUE, "\\u0BF2\\u0BE8\\u0BF1\\u0BE9\\u0BF0\\u0BEB" }, 3580 { "ta_IN@numbers=finance", 1234.567, FALSE, "1,234.567" }, // fall back to default per TR35 3581 { "zh_TW@numbers=native", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" }, 3582 { "zh_TW@numbers=traditional", 1234.567, TRUE, "\\u4E00\\u5343\\u4E8C\\u767E\\u4E09\\u5341\\u56DB\\u9EDE\\u4E94\\u516D\\u4E03" }, 3583 { "zh_TW@numbers=finance", 1234.567, TRUE, "\\u58F9\\u4EDF\\u8CB3\\u4F70\\u53C3\\u62FE\\u8086\\u9EDE\\u4F0D\\u9678\\u67D2" }, 3584 { NULL, 0, FALSE, NULL } 3585 }; 3586 3587 UErrorCode ec; 3588 3589 const TestNumberingSystemItem *item; 3590 for (item = DATA; item->localeName != NULL; item++) { 3591 ec = U_ZERO_ERROR; 3592 Locale loc = Locale::createFromName(item->localeName); 3593 3594 NumberFormat *origFmt = NumberFormat::createInstance(loc,ec); 3595 if (U_FAILURE(ec)) { 3596 dataerrln("FAIL: getInstance(%s) - %s", item->localeName, u_errorName(ec)); 3597 continue; 3598 } 3599 // Clone to test ticket #10682 3600 NumberFormat *fmt = (NumberFormat *) origFmt->clone(); 3601 delete origFmt; 3602 3603 3604 if (item->isRBNF) { 3605 expect3(*fmt,item->value,CharsToUnicodeString(item->expectedResult)); 3606 } else { 3607 expect2(*fmt,item->value,CharsToUnicodeString(item->expectedResult)); 3608 } 3609 delete fmt; 3610 } 3611 3612 3613 // Test bogus keyword value 3614 ec = U_ZERO_ERROR; 3615 Locale loc4 = Locale::createFromName("en_US@numbers=foobar"); 3616 NumberFormat* fmt4= NumberFormat::createInstance(loc4, ec); 3617 if ( ec != U_UNSUPPORTED_ERROR ) { 3618 errln("FAIL: getInstance(en_US@numbers=foobar) should have returned U_UNSUPPORTED_ERROR"); 3619 delete fmt4; 3620 } 3621 3622 ec = U_ZERO_ERROR; 3623 NumberingSystem *ns = NumberingSystem::createInstance(ec); 3624 if (U_FAILURE(ec)) { 3625 dataerrln("FAIL: NumberingSystem::createInstance(ec); - %s", u_errorName(ec)); 3626 } 3627 3628 if ( ns != NULL ) { 3629 ns->getDynamicClassID(); 3630 ns->getStaticClassID(); 3631 } else { 3632 errln("FAIL: getInstance() returned NULL."); 3633 } 3634 3635 NumberingSystem *ns1 = new NumberingSystem(*ns); 3636 if (ns1 == NULL) { 3637 errln("FAIL: NumberSystem copy constructor returned NULL."); 3638 } 3639 3640 delete ns1; 3641 delete ns; 3642 3643 } 3644 3645 3646 void 3647 NumberFormatTest::TestMultiCurrencySign() { 3648 const char* DATA[][6] = { 3649 // the fields in the following test are: 3650 // locale, 3651 // currency pattern (with negative pattern), 3652 // currency number to be formatted, 3653 // currency format using currency symbol name, such as "$" for USD, 3654 // currency format using currency ISO name, such as "USD", 3655 // currency format using plural name, such as "US dollars". 3656 // for US locale 3657 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1234.56", "$1,234.56", "USD1,234.56", "US dollars1,234.56"}, 3658 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD1,234.56", "-US dollars1,234.56"}, 3659 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1", "$1.00", "USD1.00", "US dollars1.00"}, 3660 // for CHINA locale 3661 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1234.56", "\\uFFE51,234.56", "CNY1,234.56", "\\u4EBA\\u6C11\\u5E011,234.56"}, 3662 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "-1234.56", "(\\uFFE51,234.56)", "(CNY1,234.56)", "(\\u4EBA\\u6C11\\u5E011,234.56)"}, 3663 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1", "\\uFFE51.00", "CNY1.00", "\\u4EBA\\u6C11\\u5E011.00"} 3664 }; 3665 3666 const UChar doubleCurrencySign[] = {0xA4, 0xA4, 0}; 3667 UnicodeString doubleCurrencyStr(doubleCurrencySign); 3668 const UChar tripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0}; 3669 UnicodeString tripleCurrencyStr(tripleCurrencySign); 3670 3671 for (uint32_t i=0; i<sizeof(DATA)/sizeof(DATA[0]); ++i) { 3672 const char* locale = DATA[i][0]; 3673 UnicodeString pat = ctou(DATA[i][1]); 3674 double numberToBeFormat = atof(DATA[i][2]); 3675 UErrorCode status = U_ZERO_ERROR; 3676 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale(locale), status); 3677 if (U_FAILURE(status)) { 3678 delete sym; 3679 continue; 3680 } 3681 for (int j=1; j<=3; ++j) { 3682 // j represents the number of currency sign in the pattern. 3683 if (j == 2) { 3684 pat = pat.findAndReplace(ctou("\\u00A4"), doubleCurrencyStr); 3685 } else if (j == 3) { 3686 pat = pat.findAndReplace(ctou("\\u00A4\\u00A4"), tripleCurrencyStr); 3687 } 3688 3689 DecimalFormat* fmt = new DecimalFormat(pat, new DecimalFormatSymbols(*sym), status); 3690 if (U_FAILURE(status)) { 3691 errln("FAILED init DecimalFormat "); 3692 delete fmt; 3693 continue; 3694 } 3695 UnicodeString s; 3696 ((NumberFormat*) fmt)->format(numberToBeFormat, s); 3697 // DATA[i][3] is the currency format result using a 3698 // single currency sign. 3699 // DATA[i][4] is the currency format result using 3700 // double currency sign. 3701 // DATA[i][5] is the currency format result using 3702 // triple currency sign. 3703 // DATA[i][j+2] is the currency format result using 3704 // 'j' number of currency sign. 3705 UnicodeString currencyFormatResult = ctou(DATA[i][2+j]); 3706 if (s.compare(currencyFormatResult)) { 3707 errln("FAIL format: Expected " + currencyFormatResult + "; Got " + s); 3708 } 3709 // mix style parsing 3710 for (int k=3; k<=5; ++k) { 3711 // DATA[i][3] is the currency format result using a 3712 // single currency sign. 3713 // DATA[i][4] is the currency format result using 3714 // double currency sign. 3715 // DATA[i][5] is the currency format result using 3716 // triple currency sign. 3717 UnicodeString oneCurrencyFormat = ctou(DATA[i][k]); 3718 UErrorCode status = U_ZERO_ERROR; 3719 Formattable parseRes; 3720 fmt->parse(oneCurrencyFormat, parseRes, status); 3721 if (U_FAILURE(status) || 3722 (parseRes.getType() == Formattable::kDouble && 3723 parseRes.getDouble() != numberToBeFormat) || 3724 (parseRes.getType() == Formattable::kLong && 3725 parseRes.getLong() != numberToBeFormat)) { 3726 errln("FAILED parse " + oneCurrencyFormat + "; (i, j, k): " + 3727 i + ", " + j + ", " + k); 3728 } 3729 } 3730 delete fmt; 3731 } 3732 delete sym; 3733 } 3734 } 3735 3736 3737 void 3738 NumberFormatTest::TestCurrencyFormatForMixParsing() { 3739 UErrorCode status = U_ZERO_ERROR; 3740 MeasureFormat* curFmt = MeasureFormat::createCurrencyFormat(Locale("en_US"), status); 3741 if (U_FAILURE(status)) { 3742 delete curFmt; 3743 return; 3744 } 3745 const char* formats[] = { 3746 "$1,234.56", // string to be parsed 3747 "USD1,234.56", 3748 "US dollars1,234.56", 3749 "1,234.56 US dollars" 3750 }; 3751 const CurrencyAmount* curramt = NULL; 3752 for (uint32_t i = 0; i < sizeof(formats)/sizeof(formats[0]); ++i) { 3753 UnicodeString stringToBeParsed = ctou(formats[i]); 3754 logln(UnicodeString("stringToBeParsed: ") + stringToBeParsed); 3755 Formattable result; 3756 UErrorCode status = U_ZERO_ERROR; 3757 curFmt->parseObject(stringToBeParsed, result, status); 3758 if (U_FAILURE(status)) { 3759 errln("FAIL: measure format parsing: '%s' ec: %s", formats[i], u_errorName(status)); 3760 } else if (result.getType() != Formattable::kObject || 3761 (curramt = dynamic_cast<const CurrencyAmount*>(result.getObject())) == NULL || 3762 curramt->getNumber().getDouble() != 1234.56 || 3763 UnicodeString(curramt->getISOCurrency()).compare(ISO_CURRENCY_USD) 3764 ) { 3765 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number "); 3766 if (curramt->getNumber().getDouble() != 1234.56) { 3767 errln((UnicodeString)"wong number, expect: 1234.56" + ", got: " + curramt->getNumber().getDouble()); 3768 } 3769 if (curramt->getISOCurrency() != ISO_CURRENCY_USD) { 3770 errln((UnicodeString)"wong currency, expect: USD" + ", got: " + curramt->getISOCurrency()); 3771 } 3772 } 3773 } 3774 delete curFmt; 3775 } 3776 3777 3778 void 3779 NumberFormatTest::TestDecimalFormatCurrencyParse() { 3780 // Locale.US 3781 UErrorCode status = U_ZERO_ERROR; 3782 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale("en_US"), status); 3783 if (U_FAILURE(status)) { 3784 delete sym; 3785 return; 3786 } 3787 UnicodeString pat; 3788 UChar currency = 0x00A4; 3789 // "\xA4#,##0.00;-\xA4#,##0.00" 3790 pat.append(currency).append(currency).append(currency).append("#,##0.00;-").append(currency).append(currency).append(currency).append("#,##0.00"); 3791 DecimalFormat* fmt = new DecimalFormat(pat, sym, status); 3792 if (U_FAILURE(status)) { 3793 delete fmt; 3794 errln("failed to new DecimalFormat in TestDecimalFormatCurrencyParse"); 3795 return; 3796 } 3797 const char* DATA[][2] = { 3798 // the data are: 3799 // string to be parsed, the parsed result (number) 3800 {"$1.00", "1"}, 3801 {"USD1.00", "1"}, 3802 {"1.00 US dollar", "1"}, 3803 {"$1,234.56", "1234.56"}, 3804 {"USD1,234.56", "1234.56"}, 3805 {"1,234.56 US dollar", "1234.56"}, 3806 }; 3807 for (uint32_t i = 0; i < sizeof(DATA)/sizeof(DATA[0]); ++i) { 3808 UnicodeString stringToBeParsed = ctou(DATA[i][0]); 3809 double parsedResult = atof(DATA[i][1]); 3810 UErrorCode status = U_ZERO_ERROR; 3811 Formattable result; 3812 fmt->parse(stringToBeParsed, result, status); 3813 if (U_FAILURE(status) || 3814 (result.getType() == Formattable::kDouble && 3815 result.getDouble() != parsedResult) || 3816 (result.getType() == Formattable::kLong && 3817 result.getLong() != parsedResult)) { 3818 errln((UnicodeString)"FAIL parse: Expected " + parsedResult); 3819 } 3820 } 3821 delete fmt; 3822 } 3823 3824 3825 void 3826 NumberFormatTest::TestCurrencyIsoPluralFormat() { 3827 static const char* DATA[][6] = { 3828 // the data are: 3829 // locale, 3830 // currency amount to be formatted, 3831 // currency ISO code to be formatted, 3832 // format result using CURRENCYSTYLE, 3833 // format result using ISOCURRENCYSTYLE, 3834 // format result using PLURALCURRENCYSTYLE, 3835 3836 {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollars"}, 3837 {"en_US", "1234.56", "USD", "$1,234.56", "USD1,234.56", "1,234.56 US dollars"}, 3838 {"en_US", "-1234.56", "USD", "-$1,234.56", "-USD1,234.56", "-1,234.56 US dollars"}, 3839 {"zh_CN", "1", "USD", "US$1.00", "USD1.00", "1.00\\u7F8E\\u5143"}, 3840 {"zh_CN", "1234.56", "USD", "US$1,234.56", "USD1,234.56", "1,234.56\\u7F8E\\u5143"}, 3841 {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY1.00", "1.00\\u4EBA\\u6C11\\u5E01"}, 3842 {"zh_CN", "1234.56", "CNY", "\\uFFE51,234.56", "CNY1,234.56", "1,234.56\\u4EBA\\u6C11\\u5E01"}, 3843 {"ru_RU", "1", "RUB", "1,00\\u00A0\\u20BD", "1,00\\u00A0RUB", "1,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"}, 3844 {"ru_RU", "2", "RUB", "2,00\\u00A0\\u20BD", "2,00\\u00A0RUB", "2,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"}, 3845 {"ru_RU", "5", "RUB", "5,00\\u00A0\\u20BD", "5,00\\u00A0RUB", "5,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"}, 3846 // test locale without currency information 3847 {"root", "-1.23", "USD", "-US$\\u00A01.23", "-USD\\u00A01.23", "-1.23 USD"}, 3848 // test choice format 3849 {"es_AR", "1", "INR", "INR\\u00A01,00", "INR\\u00A01,00", "1,00 rupia india"}, 3850 }; 3851 static const UNumberFormatStyle currencyStyles[] = { 3852 UNUM_CURRENCY, 3853 UNUM_CURRENCY_ISO, 3854 UNUM_CURRENCY_PLURAL 3855 }; 3856 3857 for (int32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) { 3858 for (int32_t kIndex = 0; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) { 3859 UNumberFormatStyle k = currencyStyles[kIndex]; 3860 const char* localeString = DATA[i][0]; 3861 double numberToBeFormat = atof(DATA[i][1]); 3862 const char* currencyISOCode = DATA[i][2]; 3863 Locale locale(localeString); 3864 UErrorCode status = U_ZERO_ERROR; 3865 NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status); 3866 if (U_FAILURE(status)) { 3867 delete numFmt; 3868 dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status)); 3869 continue; 3870 } 3871 UChar currencyCode[4]; 3872 u_charsToUChars(currencyISOCode, currencyCode, 4); 3873 numFmt->setCurrency(currencyCode, status); 3874 if (U_FAILURE(status)) { 3875 delete numFmt; 3876 errln((UnicodeString)"can not set currency:" + currencyISOCode); 3877 continue; 3878 } 3879 3880 UnicodeString strBuf; 3881 numFmt->format(numberToBeFormat, strBuf); 3882 int resultDataIndex = 3 + kIndex; 3883 // DATA[i][resultDataIndex] is the currency format result 3884 // using 'k' currency style. 3885 UnicodeString formatResult = ctou(DATA[i][resultDataIndex]); 3886 if (strBuf.compare(formatResult)) { 3887 errln("FAIL: Expected " + formatResult + " actual: " + strBuf); 3888 } 3889 // test parsing, and test parsing for all currency formats. 3890 for (int j = 3; j < 6; ++j) { 3891 // DATA[i][3] is the currency format result using 3892 // CURRENCYSTYLE formatter. 3893 // DATA[i][4] is the currency format result using 3894 // ISOCURRENCYSTYLE formatter. 3895 // DATA[i][5] is the currency format result using 3896 // PLURALCURRENCYSTYLE formatter. 3897 UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]); 3898 UErrorCode status = U_ZERO_ERROR; 3899 Formattable parseResult; 3900 numFmt->parse(oneCurrencyFormatResult, parseResult, status); 3901 if (U_FAILURE(status) || 3902 (parseResult.getType() == Formattable::kDouble && 3903 parseResult.getDouble() != numberToBeFormat) || 3904 (parseResult.getType() == Formattable::kLong && 3905 parseResult.getLong() != numberToBeFormat)) { 3906 errln((UnicodeString)"FAIL: getCurrencyFormat of locale " + 3907 localeString + " failed roundtripping the number"); 3908 if (parseResult.getType() == Formattable::kDouble) { 3909 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getDouble()); 3910 } else { 3911 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getLong()); 3912 } 3913 } 3914 } 3915 delete numFmt; 3916 } 3917 } 3918 } 3919 3920 void 3921 NumberFormatTest::TestCurrencyParsing() { 3922 static const char* DATA[][6] = { 3923 // the data are: 3924 // locale, 3925 // currency amount to be formatted, 3926 // currency ISO code to be formatted, 3927 // format result using CURRENCYSTYLE, 3928 // format result using ISOCURRENCYSTYLE, 3929 // format result using PLURALCURRENCYSTYLE, 3930 {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar"}, 3931 {"pa_IN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\u0a2f\\u0a42.\\u0a10\\u0a38. \\u0a21\\u0a3e\\u0a32\\u0a30"}, 3932 {"es_AR", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 d\\u00f3lar estadounidense"}, 3933 {"ar_EG", "1", "USD", "US$\\u00a0\\u0661\\u066b\\u0660\\u0660", "USD\\u00a0\\u0661\\u066b\\u0660\\u0660", "\\u0661\\u066b\\u0660\\u0660 \\u062f\\u0648\\u0644\\u0627\\u0631 \\u0623\\u0645\\u0631\\u064a\\u0643\\u064a"}, 3934 {"fa_CA", "1", "USD", "\\u200e$\\u06f1\\u066b\\u06f0\\u06f0", "\\u200eUSD\\u06f1\\u066b\\u06f0\\u06f0", "\\u200e\\u062f\\u0644\\u0627\\u0631 \\u0627\\u0645\\u0631\\u06cc\\u06a9\\u0627\\u06f1\\u066b\\u06f0\\u06f0"}, 3935 {"he_IL", "1", "USD", "1.00\\u00a0$", "1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"}, 3936 {"hr_HR", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 Ameri\\u010dki dolar"}, 3937 {"id_ID", "1", "USD", "US$1,00", "USD1,00", "1,00 Dolar Amerika Serikat"}, 3938 {"it_IT", "1", "USD", "1,00\\u00a0US$", "1,00\\u00a0USD", "1,00 Dollaro Statunitense"}, 3939 {"ko_KR", "1", "USD", "US$1.00", "USD1.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"}, 3940 {"ja_JP", "1", "USD", "$1.00", "USD1.00", "1.00\\u7c73\\u30c9\\u30eb"}, 3941 {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY01.00", "1.00\\u4EBA\\u6C11\\u5E01"}, 3942 {"zh_TW", "1", "CNY", "CN\\u00A51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"}, 3943 {"zh_Hant", "1", "CNY", "CN\\u00A51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"}, 3944 {"zh_Hant", "1", "JPY", "\\u00A51.00", "JPY1.00", "1.00 \\u65e5\\u5713"}, 3945 {"ja_JP", "1", "JPY", "\\uFFE51.00", "JPY1.00", "1.00\\u65e5\\u672c\\u5186"}, 3946 {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY1.00", "1.00\\u65e5\\u672c\\u5186"}, 3947 {"ru_RU", "1", "RUB", "1,00\\u00A0\\u20BD", "1,00\\u00A0RUB", "1,00 \\u0420\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u0438\\u0439 \\u0440\\u0443\\u0431\\u043B\\u044C"} 3948 }; 3949 static const UNumberFormatStyle currencyStyles[] = { 3950 UNUM_CURRENCY, 3951 UNUM_CURRENCY_ISO, 3952 UNUM_CURRENCY_PLURAL 3953 }; 3954 static const char* currencyStyleNames[] = { 3955 "UNUM_CURRENCY", 3956 "UNUM_CURRENCY_ISO", 3957 "UNUM_CURRENCY_PLURAL" 3958 }; 3959 3960 #ifdef NUMFMTST_CACHE_DEBUG 3961 int deadloop = 0; 3962 for (;;) { 3963 printf("loop: %d\n", deadloop++); 3964 #endif 3965 for (uint32_t i=0; i< sizeof(DATA)/sizeof(DATA[0]); ++i) { /* i = test case # - should be i=0*/ 3966 for (int32_t kIndex = 2; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) { 3967 UNumberFormatStyle k = currencyStyles[kIndex]; /* k = style */ 3968 const char* localeString = DATA[i][0]; 3969 double numberToBeFormat = atof(DATA[i][1]); 3970 const char* currencyISOCode = DATA[i][2]; 3971 Locale locale(localeString); 3972 UErrorCode status = U_ZERO_ERROR; 3973 NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status); 3974 logln("#%d NumberFormat(%s, %s) Currency=%s\n", 3975 i, localeString, currencyStyleNames[kIndex], 3976 currencyISOCode); 3977 3978 if (U_FAILURE(status)) { 3979 delete numFmt; 3980 dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status)); 3981 continue; 3982 } 3983 UChar currencyCode[4]; 3984 u_charsToUChars(currencyISOCode, currencyCode, 4); 3985 numFmt->setCurrency(currencyCode, status); 3986 if (U_FAILURE(status)) { 3987 delete numFmt; 3988 errln((UnicodeString)"can not set currency:" + currencyISOCode); 3989 continue; 3990 } 3991 3992 UnicodeString strBuf; 3993 numFmt->format(numberToBeFormat, strBuf); 3994 /* 3995 int resultDataIndex = 3 + kIndex; 3996 // DATA[i][resultDataIndex] is the currency format result 3997 // using 'k' currency style. 3998 UnicodeString formatResult = ctou(DATA[i][resultDataIndex]); 3999 if (strBuf.compare(formatResult)) { 4000 errln("FAIL: Expected " + formatResult + " actual: " + strBuf); 4001 } 4002 */ 4003 // test parsing, and test parsing for all currency formats. 4004 for (int j = 3; j < 6; ++j) { 4005 // DATA[i][3] is the currency format result using 4006 // CURRENCYSTYLE formatter. 4007 // DATA[i][4] is the currency format result using 4008 // ISOCURRENCYSTYLE formatter. 4009 // DATA[i][5] is the currency format result using 4010 // PLURALCURRENCYSTYLE formatter. 4011 UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]); 4012 UErrorCode status = U_ZERO_ERROR; 4013 Formattable parseResult; 4014 logln("parse(%s)", DATA[i][j]); 4015 numFmt->parse(oneCurrencyFormatResult, parseResult, status); 4016 if (U_FAILURE(status) || 4017 (parseResult.getType() == Formattable::kDouble && 4018 parseResult.getDouble() != numberToBeFormat) || 4019 (parseResult.getType() == Formattable::kLong && 4020 parseResult.getLong() != numberToBeFormat)) { 4021 errln((UnicodeString)"FAIL: NumberFormat(" + localeString +", " + currencyStyleNames[kIndex] + 4022 "), Currency="+currencyISOCode+", parse("+DATA[i][j]+") returned error " + (UnicodeString)u_errorName(status)+". Testcase: data[" + i + "][" + currencyStyleNames[j-3] +"="+j+"]"); 4023 if (parseResult.getType() == Formattable::kDouble) { 4024 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (double): " +parseResult.getDouble()); 4025 } else { 4026 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (long): " +parseResult.getLong()); 4027 } 4028 errln((UnicodeString)" round-trip would be: " + strBuf); 4029 } 4030 } 4031 delete numFmt; 4032 } 4033 } 4034 #ifdef NUMFMTST_CACHE_DEBUG 4035 } 4036 #endif 4037 } 4038 4039 4040 void 4041 NumberFormatTest::TestParseCurrencyInUCurr() { 4042 const char* DATA[] = { 4043 "1.00 US DOLLAR", // case in-sensitive 4044 "$1.00", 4045 "USD1.00", 4046 "US dollar1.00", 4047 "US dollars1.00", 4048 "$1.00", 4049 "A$1.00", 4050 "ADP1.00", 4051 "ADP1.00", 4052 "AED1.00", 4053 "AED1.00", 4054 "AFA1.00", 4055 "AFA1.00", 4056 "AFN1.00", 4057 "ALL1.00", 4058 "AMD1.00", 4059 "ANG1.00", 4060 "AOA1.00", 4061 "AOK1.00", 4062 "AOK1.00", 4063 "AON1.00", 4064 "AON1.00", 4065 "AOR1.00", 4066 "AOR1.00", 4067 "ARS1.00", 4068 "ARA1.00", 4069 "ARA1.00", 4070 "ARP1.00", 4071 "ARP1.00", 4072 "ARS1.00", 4073 "ATS1.00", 4074 "ATS1.00", 4075 "AUD1.00", 4076 "AWG1.00", 4077 "AZM1.00", 4078 "AZM1.00", 4079 "AZN1.00", 4080 "Afghan Afghani (1927\\u20132002)1.00", 4081 "Afghan afghani (1927\\u20132002)1.00", 4082 "Afghan Afghani1.00", 4083 "Afghan Afghanis1.00", 4084 "Albanian Lek1.00", 4085 "Albanian lek1.00", 4086 "Albanian lek\\u00eb1.00", 4087 "Algerian Dinar1.00", 4088 "Algerian dinar1.00", 4089 "Algerian dinars1.00", 4090 "Andorran Peseta1.00", 4091 "Andorran peseta1.00", 4092 "Andorran pesetas1.00", 4093 "Angolan Kwanza (1977\\u20131991)1.00", 4094 "Angolan Readjusted Kwanza (1995\\u20131999)1.00", 4095 "Angolan Kwanza1.00", 4096 "Angolan New Kwanza (1990\\u20132000)1.00", 4097 "Angolan kwanza (1977\\u20131991)1.00", 4098 "Angolan readjusted kwanza (1995\\u20131999)1.00", 4099 "Angolan kwanza1.00", 4100 "Angolan kwanzas (1977\\u20131991)1.00", 4101 "Angolan readjusted kwanzas (1995\\u20131999)1.00", 4102 "Angolan kwanzas1.00", 4103 "Angolan new kwanza (1990\\u20132000)1.00", 4104 "Angolan new kwanzas (1990\\u20132000)1.00", 4105 "Argentine Austral1.00", 4106 "Argentine Peso (1983\\u20131985)1.00", 4107 "Argentine Peso1.00", 4108 "Argentine austral1.00", 4109 "Argentine australs1.00", 4110 "Argentine peso (1983\\u20131985)1.00", 4111 "Argentine peso1.00", 4112 "Argentine pesos (1983\\u20131985)1.00", 4113 "Argentine pesos1.00", 4114 "Armenian Dram1.00", 4115 "Armenian dram1.00", 4116 "Armenian drams1.00", 4117 "Aruban Florin1.00", 4118 "Aruban florin1.00", 4119 "Australian Dollar1.00", 4120 "Australian dollar1.00", 4121 "Australian dollars1.00", 4122 "Austrian Schilling1.00", 4123 "Austrian schilling1.00", 4124 "Austrian schillings1.00", 4125 "Azerbaijani Manat (1993\\u20132006)1.00", 4126 "Azerbaijani Manat1.00", 4127 "Azerbaijani manat (1993\\u20132006)1.00", 4128 "Azerbaijani manat1.00", 4129 "Azerbaijani manats (1993\\u20132006)1.00", 4130 "Azerbaijani manats1.00", 4131 "BAD1.00", 4132 "BAD1.00", 4133 "BAM1.00", 4134 "BBD1.00", 4135 "BDT1.00", 4136 "BEC1.00", 4137 "BEC1.00", 4138 "BEF1.00", 4139 "BEL1.00", 4140 "BEL1.00", 4141 "BGL1.00", 4142 "BGN1.00", 4143 "BGN1.00", 4144 "BHD1.00", 4145 "BIF1.00", 4146 "BMD1.00", 4147 "BND1.00", 4148 "BOB1.00", 4149 "BOP1.00", 4150 "BOP1.00", 4151 "BOV1.00", 4152 "BOV1.00", 4153 "BRB1.00", 4154 "BRB1.00", 4155 "BRC1.00", 4156 "BRC1.00", 4157 "BRE1.00", 4158 "BRE1.00", 4159 "BRL1.00", 4160 "BRN1.00", 4161 "BRN1.00", 4162 "BRR1.00", 4163 "BRR1.00", 4164 "BSD1.00", 4165 "BSD1.00", 4166 "BTN1.00", 4167 "BUK1.00", 4168 "BUK1.00", 4169 "BWP1.00", 4170 "BYB1.00", 4171 "BYB1.00", 4172 "BYR1.00", 4173 "BZD1.00", 4174 "Bahamian Dollar1.00", 4175 "Bahamian dollar1.00", 4176 "Bahamian dollars1.00", 4177 "Bahraini Dinar1.00", 4178 "Bahraini dinar1.00", 4179 "Bahraini dinars1.00", 4180 "Bangladeshi Taka1.00", 4181 "Bangladeshi taka1.00", 4182 "Bangladeshi takas1.00", 4183 "Barbadian Dollar1.00", 4184 "Barbadian dollar1.00", 4185 "Barbadian dollars1.00", 4186 "Belarusian New Ruble (1994\\u20131999)1.00", 4187 "Belarusian Ruble1.00", 4188 "Belarusian new ruble (1994\\u20131999)1.00", 4189 "Belarusian new rubles (1994\\u20131999)1.00", 4190 "Belarusian ruble1.00", 4191 "Belarusian rubles1.00", 4192 "Belgian Franc (convertible)1.00", 4193 "Belgian Franc (financial)1.00", 4194 "Belgian Franc1.00", 4195 "Belgian franc (convertible)1.00", 4196 "Belgian franc (financial)1.00", 4197 "Belgian franc1.00", 4198 "Belgian francs (convertible)1.00", 4199 "Belgian francs (financial)1.00", 4200 "Belgian francs1.00", 4201 "Belize Dollar1.00", 4202 "Belize dollar1.00", 4203 "Belize dollars1.00", 4204 "Bermudan Dollar1.00", 4205 "Bermudan dollar1.00", 4206 "Bermudan dollars1.00", 4207 "Bhutanese Ngultrum1.00", 4208 "Bhutanese ngultrum1.00", 4209 "Bhutanese ngultrums1.00", 4210 "Bolivian Mvdol1.00", 4211 "Bolivian Peso1.00", 4212 "Bolivian mvdol1.00", 4213 "Bolivian mvdols1.00", 4214 "Bolivian peso1.00", 4215 "Bolivian pesos1.00", 4216 "Bolivian Boliviano1.00", 4217 "Bolivian Boliviano1.00", 4218 "Bolivian Bolivianos1.00", 4219 "Bosnia-Herzegovina Convertible Mark1.00", 4220 "Bosnia-Herzegovina Dinar (1992\\u20131994)1.00", 4221 "Bosnia-Herzegovina convertible mark1.00", 4222 "Bosnia-Herzegovina convertible marks1.00", 4223 "Bosnia-Herzegovina dinar (1992\\u20131994)1.00", 4224 "Bosnia-Herzegovina dinars (1992\\u20131994)1.00", 4225 "Botswanan Pula1.00", 4226 "Botswanan pula1.00", 4227 "Botswanan pulas1.00", 4228 "Brazilian New Cruzado (1989\\u20131990)1.00", 4229 "Brazilian Cruzado (1986\\u20131989)1.00", 4230 "Brazilian Cruzeiro (1990\\u20131993)1.00", 4231 "Brazilian New Cruzeiro (1967\\u20131986)1.00", 4232 "Brazilian Cruzeiro (1993\\u20131994)1.00", 4233 "Brazilian Real1.00", 4234 "Brazilian new cruzado (1989\\u20131990)1.00", 4235 "Brazilian new cruzados (1989\\u20131990)1.00", 4236 "Brazilian cruzado (1986\\u20131989)1.00", 4237 "Brazilian cruzados (1986\\u20131989)1.00", 4238 "Brazilian cruzeiro (1990\\u20131993)1.00", 4239 "Brazilian new cruzeiro (1967\\u20131986)1.00", 4240 "Brazilian cruzeiro (1993\\u20131994)1.00", 4241 "Brazilian cruzeiros (1990\\u20131993)1.00", 4242 "Brazilian new cruzeiros (1967\\u20131986)1.00", 4243 "Brazilian cruzeiros (1993\\u20131994)1.00", 4244 "Brazilian real1.00", 4245 "Brazilian reals1.00", 4246 "British Pound1.00", 4247 "British pound1.00", 4248 "British pounds1.00", 4249 "Brunei Dollar1.00", 4250 "Brunei dollar1.00", 4251 "Brunei dollars1.00", 4252 "Bulgarian Hard Lev1.00", 4253 "Bulgarian Lev1.00", 4254 "Bulgarian Leva1.00", 4255 "Bulgarian hard lev1.00", 4256 "Bulgarian hard leva1.00", 4257 "Bulgarian lev1.00", 4258 "Burmese Kyat1.00", 4259 "Burmese kyat1.00", 4260 "Burmese kyats1.00", 4261 "Burundian Franc1.00", 4262 "Burundian franc1.00", 4263 "Burundian francs1.00", 4264 "CA$1.00", 4265 "CAD1.00", 4266 "CDF1.00", 4267 "CDF1.00", 4268 "West African CFA Franc1.00", 4269 "Central African CFA Franc1.00", 4270 "West African CFA franc1.00", 4271 "Central African CFA franc1.00", 4272 "West African CFA francs1.00", 4273 "Central African CFA francs1.00", 4274 "CFP Franc1.00", 4275 "CFP franc1.00", 4276 "CFP francs1.00", 4277 "CFPF1.00", 4278 "CHE1.00", 4279 "CHE1.00", 4280 "CHF1.00", 4281 "CHW1.00", 4282 "CHW1.00", 4283 "CLF1.00", 4284 "CLF1.00", 4285 "CLP1.00", 4286 "CNY1.00", 4287 "COP1.00", 4288 "COU1.00", 4289 "COU1.00", 4290 "CRC1.00", 4291 "CSD1.00", 4292 "CSD1.00", 4293 "CSK1.00", 4294 "CSK1.00", 4295 "CUP1.00", 4296 "CUP1.00", 4297 "CVE1.00", 4298 "CYP1.00", 4299 "CZK1.00", 4300 "Cambodian Riel1.00", 4301 "Cambodian riel1.00", 4302 "Cambodian riels1.00", 4303 "Canadian Dollar1.00", 4304 "Canadian dollar1.00", 4305 "Canadian dollars1.00", 4306 "Cape Verdean Escudo1.00", 4307 "Cape Verdean escudo1.00", 4308 "Cape Verdean escudos1.00", 4309 "Cayman Islands Dollar1.00", 4310 "Cayman Islands dollar1.00", 4311 "Cayman Islands dollars1.00", 4312 "Chilean Peso1.00", 4313 "Chilean Unit of Account (UF)1.00", 4314 "Chilean peso1.00", 4315 "Chilean pesos1.00", 4316 "Chilean unit of account (UF)1.00", 4317 "Chilean units of account (UF)1.00", 4318 "Chinese Yuan1.00", 4319 "Chinese yuan1.00", 4320 "Colombian Peso1.00", 4321 "Colombian peso1.00", 4322 "Colombian pesos1.00", 4323 "Comorian Franc1.00", 4324 "Comorian franc1.00", 4325 "Comorian francs1.00", 4326 "Congolese Franc1.00", 4327 "Congolese franc1.00", 4328 "Congolese francs1.00", 4329 "Costa Rican Col\\u00f3n1.00", 4330 "Costa Rican col\\u00f3n1.00", 4331 "Costa Rican col\\u00f3ns1.00", 4332 "Croatian Dinar1.00", 4333 "Croatian Kuna1.00", 4334 "Croatian dinar1.00", 4335 "Croatian dinars1.00", 4336 "Croatian kuna1.00", 4337 "Croatian kunas1.00", 4338 "Cuban Peso1.00", 4339 "Cuban peso1.00", 4340 "Cuban pesos1.00", 4341 "Cypriot Pound1.00", 4342 "Cypriot pound1.00", 4343 "Cypriot pounds1.00", 4344 "Czech Republic Koruna1.00", 4345 "Czech Republic koruna1.00", 4346 "Czech Republic korunas1.00", 4347 "Czechoslovak Hard Koruna1.00", 4348 "Czechoslovak hard koruna1.00", 4349 "Czechoslovak hard korunas1.00", 4350 "DDM1.00", 4351 "DDM1.00", 4352 "DEM1.00", 4353 "DEM1.00", 4354 "DJF1.00", 4355 "DKK1.00", 4356 "DOP1.00", 4357 "DZD1.00", 4358 "Danish Krone1.00", 4359 "Danish krone1.00", 4360 "Danish kroner1.00", 4361 "German Mark1.00", 4362 "German mark1.00", 4363 "German marks1.00", 4364 "Djiboutian Franc1.00", 4365 "Djiboutian franc1.00", 4366 "Djiboutian francs1.00", 4367 "Dominican Peso1.00", 4368 "Dominican peso1.00", 4369 "Dominican pesos1.00", 4370 "EC$1.00", 4371 "ECS1.00", 4372 "ECS1.00", 4373 "ECV1.00", 4374 "ECV1.00", 4375 "EEK1.00", 4376 "EEK1.00", 4377 "EGP1.00", 4378 "EGP1.00", 4379 "ERN1.00", 4380 "ERN1.00", 4381 "ESA1.00", 4382 "ESA1.00", 4383 "ESB1.00", 4384 "ESB1.00", 4385 "ESP1.00", 4386 "ETB1.00", 4387 "EUR1.00", 4388 "East Caribbean Dollar1.00", 4389 "East Caribbean dollar1.00", 4390 "East Caribbean dollars1.00", 4391 "East German Mark1.00", 4392 "East German mark1.00", 4393 "East German marks1.00", 4394 "Ecuadorian Sucre1.00", 4395 "Ecuadorian Unit of Constant Value1.00", 4396 "Ecuadorian sucre1.00", 4397 "Ecuadorian sucres1.00", 4398 "Ecuadorian unit of constant value1.00", 4399 "Ecuadorian units of constant value1.00", 4400 "Egyptian Pound1.00", 4401 "Egyptian pound1.00", 4402 "Egyptian pounds1.00", 4403 "Salvadoran Col\\u00f3n1.00", 4404 "Salvadoran col\\u00f3n1.00", 4405 "Salvadoran colones1.00", 4406 "Equatorial Guinean Ekwele1.00", 4407 "Equatorial Guinean ekwele1.00", 4408 "Eritrean Nakfa1.00", 4409 "Eritrean nakfa1.00", 4410 "Eritrean nakfas1.00", 4411 "Estonian Kroon1.00", 4412 "Estonian kroon1.00", 4413 "Estonian kroons1.00", 4414 "Ethiopian Birr1.00", 4415 "Ethiopian birr1.00", 4416 "Ethiopian birrs1.00", 4417 "Euro1.00", 4418 "European Composite Unit1.00", 4419 "European Currency Unit1.00", 4420 "European Monetary Unit1.00", 4421 "European Unit of Account (XBC)1.00", 4422 "European Unit of Account (XBD)1.00", 4423 "European composite unit1.00", 4424 "European composite units1.00", 4425 "European currency unit1.00", 4426 "European currency units1.00", 4427 "European monetary unit1.00", 4428 "European monetary units1.00", 4429 "European unit of account (XBC)1.00", 4430 "European unit of account (XBD)1.00", 4431 "European units of account (XBC)1.00", 4432 "European units of account (XBD)1.00", 4433 "FIM1.00", 4434 "FIM1.00", 4435 "FJD1.00", 4436 "FKP1.00", 4437 "FKP1.00", 4438 "FRF1.00", 4439 "FRF1.00", 4440 "Falkland Islands Pound1.00", 4441 "Falkland Islands pound1.00", 4442 "Falkland Islands pounds1.00", 4443 "Fijian Dollar1.00", 4444 "Fijian dollar1.00", 4445 "Fijian dollars1.00", 4446 "Finnish Markka1.00", 4447 "Finnish markka1.00", 4448 "Finnish markkas1.00", 4449 "CHF1.00", 4450 "French Franc1.00", 4451 "French Gold Franc1.00", 4452 "French UIC-Franc1.00", 4453 "French UIC-franc1.00", 4454 "French UIC-francs1.00", 4455 "French franc1.00", 4456 "French francs1.00", 4457 "French gold franc1.00", 4458 "French gold francs1.00", 4459 "GBP1.00", 4460 "GEK1.00", 4461 "GEK1.00", 4462 "GEL1.00", 4463 "GHC1.00", 4464 "GHC1.00", 4465 "GHS1.00", 4466 "GIP1.00", 4467 "GIP1.00", 4468 "GMD1.00", 4469 "GMD1.00", 4470 "GNF1.00", 4471 "GNS1.00", 4472 "GNS1.00", 4473 "GQE1.00", 4474 "GQE1.00", 4475 "GRD1.00", 4476 "GRD1.00", 4477 "GTQ1.00", 4478 "GWE1.00", 4479 "GWE1.00", 4480 "GWP1.00", 4481 "GWP1.00", 4482 "GYD1.00", 4483 "Gambian Dalasi1.00", 4484 "Gambian dalasi1.00", 4485 "Gambian dalasis1.00", 4486 "Georgian Kupon Larit1.00", 4487 "Georgian Lari1.00", 4488 "Georgian kupon larit1.00", 4489 "Georgian kupon larits1.00", 4490 "Georgian lari1.00", 4491 "Georgian laris1.00", 4492 "Ghanaian Cedi (1979\\u20132007)1.00", 4493 "Ghanaian Cedi1.00", 4494 "Ghanaian cedi (1979\\u20132007)1.00", 4495 "Ghanaian cedi1.00", 4496 "Ghanaian cedis (1979\\u20132007)1.00", 4497 "Ghanaian cedis1.00", 4498 "Gibraltar Pound1.00", 4499 "Gibraltar pound1.00", 4500 "Gibraltar pounds1.00", 4501 "Gold1.00", 4502 "Gold1.00", 4503 "Greek Drachma1.00", 4504 "Greek drachma1.00", 4505 "Greek drachmas1.00", 4506 "Guatemalan Quetzal1.00", 4507 "Guatemalan quetzal1.00", 4508 "Guatemalan quetzals1.00", 4509 "Guinean Franc1.00", 4510 "Guinean Syli1.00", 4511 "Guinean franc1.00", 4512 "Guinean francs1.00", 4513 "Guinean syli1.00", 4514 "Guinean sylis1.00", 4515 "Guinea-Bissau Peso1.00", 4516 "Guinea-Bissau peso1.00", 4517 "Guinea-Bissau pesos1.00", 4518 "Guyanaese Dollar1.00", 4519 "Guyanaese dollar1.00", 4520 "Guyanaese dollars1.00", 4521 "HK$1.00", 4522 "HKD1.00", 4523 "HNL1.00", 4524 "HRD1.00", 4525 "HRD1.00", 4526 "HRK1.00", 4527 "HRK1.00", 4528 "HTG1.00", 4529 "HTG1.00", 4530 "HUF1.00", 4531 "Haitian Gourde1.00", 4532 "Haitian gourde1.00", 4533 "Haitian gourdes1.00", 4534 "Honduran Lempira1.00", 4535 "Honduran lempira1.00", 4536 "Honduran lempiras1.00", 4537 "Hong Kong Dollar1.00", 4538 "Hong Kong dollar1.00", 4539 "Hong Kong dollars1.00", 4540 "Hungarian Forint1.00", 4541 "Hungarian forint1.00", 4542 "Hungarian forints1.00", 4543 "IDR1.00", 4544 "IEP1.00", 4545 "ILP1.00", 4546 "ILP1.00", 4547 "ILS1.00", 4548 "INR1.00", 4549 "IQD1.00", 4550 "IRR1.00", 4551 "ISK1.00", 4552 "ISK1.00", 4553 "ITL1.00", 4554 "Icelandic Kr\\u00f3na1.00", 4555 "Icelandic kr\\u00f3na1.00", 4556 "Icelandic kr\\u00f3nur1.00", 4557 "Indian Rupee1.00", 4558 "Indian rupee1.00", 4559 "Indian rupees1.00", 4560 "Indonesian Rupiah1.00", 4561 "Indonesian rupiah1.00", 4562 "Indonesian rupiahs1.00", 4563 "Iranian Rial1.00", 4564 "Iranian rial1.00", 4565 "Iranian rials1.00", 4566 "Iraqi Dinar1.00", 4567 "Iraqi dinar1.00", 4568 "Iraqi dinars1.00", 4569 "Irish Pound1.00", 4570 "Irish pound1.00", 4571 "Irish pounds1.00", 4572 "Israeli Pound1.00", 4573 "Israeli new sheqel1.00", 4574 "Israeli pound1.00", 4575 "Israeli pounds1.00", 4576 "Italian Lira1.00", 4577 "Italian lira1.00", 4578 "Italian liras1.00", 4579 "JMD1.00", 4580 "JOD1.00", 4581 "JPY1.00", 4582 "Jamaican Dollar1.00", 4583 "Jamaican dollar1.00", 4584 "Jamaican dollars1.00", 4585 "Japanese Yen1.00", 4586 "Japanese yen1.00", 4587 "Jordanian Dinar1.00", 4588 "Jordanian dinar1.00", 4589 "Jordanian dinars1.00", 4590 "KES1.00", 4591 "KGS1.00", 4592 "KHR1.00", 4593 "KMF1.00", 4594 "KPW1.00", 4595 "KPW1.00", 4596 "KRW1.00", 4597 "KWD1.00", 4598 "KYD1.00", 4599 "KYD1.00", 4600 "KZT1.00", 4601 "Kazakhstani Tenge1.00", 4602 "Kazakhstani tenge1.00", 4603 "Kazakhstani tenges1.00", 4604 "Kenyan Shilling1.00", 4605 "Kenyan shilling1.00", 4606 "Kenyan shillings1.00", 4607 "Kuwaiti Dinar1.00", 4608 "Kuwaiti dinar1.00", 4609 "Kuwaiti dinars1.00", 4610 "Kyrgystani Som1.00", 4611 "Kyrgystani som1.00", 4612 "Kyrgystani soms1.00", 4613 "HNL1.00", 4614 "LAK1.00", 4615 "LAK1.00", 4616 "LBP1.00", 4617 "LKR1.00", 4618 "LRD1.00", 4619 "LRD1.00", 4620 "LSL1.00", 4621 "LTL1.00", 4622 "LTL1.00", 4623 "LTT1.00", 4624 "LTT1.00", 4625 "LUC1.00", 4626 "LUC1.00", 4627 "LUF1.00", 4628 "LUF1.00", 4629 "LUL1.00", 4630 "LUL1.00", 4631 "LVL1.00", 4632 "LVL1.00", 4633 "LVR1.00", 4634 "LVR1.00", 4635 "LYD1.00", 4636 "Laotian Kip1.00", 4637 "Laotian kip1.00", 4638 "Laotian kips1.00", 4639 "Latvian Lats1.00", 4640 "Latvian Ruble1.00", 4641 "Latvian lats1.00", 4642 "Latvian lati1.00", 4643 "Latvian ruble1.00", 4644 "Latvian rubles1.00", 4645 "Lebanese Pound1.00", 4646 "Lebanese pound1.00", 4647 "Lebanese pounds1.00", 4648 "Lesotho Loti1.00", 4649 "Lesotho loti1.00", 4650 "Lesotho lotis1.00", 4651 "Liberian Dollar1.00", 4652 "Liberian dollar1.00", 4653 "Liberian dollars1.00", 4654 "Libyan Dinar1.00", 4655 "Libyan dinar1.00", 4656 "Libyan dinars1.00", 4657 "Lithuanian Litas1.00", 4658 "Lithuanian Talonas1.00", 4659 "Lithuanian litas1.00", 4660 "Lithuanian litai1.00", 4661 "Lithuanian talonas1.00", 4662 "Lithuanian talonases1.00", 4663 "Luxembourgian Convertible Franc1.00", 4664 "Luxembourg Financial Franc1.00", 4665 "Luxembourgian Franc1.00", 4666 "Luxembourgian convertible franc1.00", 4667 "Luxembourgian convertible francs1.00", 4668 "Luxembourg financial franc1.00", 4669 "Luxembourg financial francs1.00", 4670 "Luxembourgian franc1.00", 4671 "Luxembourgian francs1.00", 4672 "MAD1.00", 4673 "MAD1.00", 4674 "MAF1.00", 4675 "MAF1.00", 4676 "MDL1.00", 4677 "MDL1.00", 4678 "MX$1.00", 4679 "MGA1.00", 4680 "MGA1.00", 4681 "MGF1.00", 4682 "MGF1.00", 4683 "MKD1.00", 4684 "MLF1.00", 4685 "MLF1.00", 4686 "MMK1.00", 4687 "MMK1.00", 4688 "MNT1.00", 4689 "MOP1.00", 4690 "MOP1.00", 4691 "MRO1.00", 4692 "MTL1.00", 4693 "MTP1.00", 4694 "MTP1.00", 4695 "MUR1.00", 4696 "MUR1.00", 4697 "MVR1.00", 4698 "MVR1.00", 4699 "MWK1.00", 4700 "MXN1.00", 4701 "MXP1.00", 4702 "MXP1.00", 4703 "MXV1.00", 4704 "MXV1.00", 4705 "MYR1.00", 4706 "MZE1.00", 4707 "MZE1.00", 4708 "MZM1.00", 4709 "MZN1.00", 4710 "Macanese Pataca1.00", 4711 "Macanese pataca1.00", 4712 "Macanese patacas1.00", 4713 "Macedonian Denar1.00", 4714 "Macedonian denar1.00", 4715 "Macedonian denari1.00", 4716 "Malagasy Ariaries1.00", 4717 "Malagasy Ariary1.00", 4718 "Malagasy Ariary1.00", 4719 "Malagasy Franc1.00", 4720 "Malagasy franc1.00", 4721 "Malagasy francs1.00", 4722 "Malawian Kwacha1.00", 4723 "Malawian Kwacha1.00", 4724 "Malawian Kwachas1.00", 4725 "Malaysian Ringgit1.00", 4726 "Malaysian ringgit1.00", 4727 "Malaysian ringgits1.00", 4728 "Maldivian Rufiyaa1.00", 4729 "Maldivian rufiyaa1.00", 4730 "Maldivian rufiyaas1.00", 4731 "Malian Franc1.00", 4732 "Malian franc1.00", 4733 "Malian francs1.00", 4734 "Maltese Lira1.00", 4735 "Maltese Pound1.00", 4736 "Maltese lira1.00", 4737 "Maltese lira1.00", 4738 "Maltese pound1.00", 4739 "Maltese pounds1.00", 4740 "Mauritanian Ouguiya1.00", 4741 "Mauritanian ouguiya1.00", 4742 "Mauritanian ouguiyas1.00", 4743 "Mauritian Rupee1.00", 4744 "Mauritian rupee1.00", 4745 "Mauritian rupees1.00", 4746 "Mexican Peso1.00", 4747 "Mexican Silver Peso (1861\\u20131992)1.00", 4748 "Mexican Investment Unit1.00", 4749 "Mexican peso1.00", 4750 "Mexican pesos1.00", 4751 "Mexican silver peso (1861\\u20131992)1.00", 4752 "Mexican silver pesos (1861\\u20131992)1.00", 4753 "Mexican investment unit1.00", 4754 "Mexican investment units1.00", 4755 "Moldovan Leu1.00", 4756 "Moldovan leu1.00", 4757 "Moldovan lei1.00", 4758 "Mongolian Tugrik1.00", 4759 "Mongolian tugrik1.00", 4760 "Mongolian tugriks1.00", 4761 "Moroccan Dirham1.00", 4762 "Moroccan Franc1.00", 4763 "Moroccan dirham1.00", 4764 "Moroccan dirhams1.00", 4765 "Moroccan franc1.00", 4766 "Moroccan francs1.00", 4767 "Mozambican Escudo1.00", 4768 "Mozambican Metical1.00", 4769 "Mozambican escudo1.00", 4770 "Mozambican escudos1.00", 4771 "Mozambican metical1.00", 4772 "Mozambican meticals1.00", 4773 "Myanmar Kyat1.00", 4774 "Myanmar kyat1.00", 4775 "Myanmar kyats1.00", 4776 "NAD1.00", 4777 "NGN1.00", 4778 "NIC1.00", 4779 "NIO1.00", 4780 "NIO1.00", 4781 "NLG1.00", 4782 "NLG1.00", 4783 "NOK1.00", 4784 "NPR1.00", 4785 "NT$1.00", 4786 "NZ$1.00", 4787 "NZD1.00", 4788 "Namibian Dollar1.00", 4789 "Namibian dollar1.00", 4790 "Namibian dollars1.00", 4791 "Nepalese Rupee1.00", 4792 "Nepalese rupee1.00", 4793 "Nepalese rupees1.00", 4794 "Netherlands Antillean Guilder1.00", 4795 "Netherlands Antillean guilder1.00", 4796 "Netherlands Antillean guilders1.00", 4797 "Dutch Guilder1.00", 4798 "Dutch guilder1.00", 4799 "Dutch guilders1.00", 4800 "Israeli New Sheqel1.00", 4801 "Israeli New Sheqels1.00", 4802 "New Zealand Dollar1.00", 4803 "New Zealand dollar1.00", 4804 "New Zealand dollars1.00", 4805 "Nicaraguan C\\u00f3rdoba1.00", 4806 "Nicaraguan C\\u00f3rdoba (1988\\u20131991)1.00", 4807 "Nicaraguan c\\u00f3rdoba1.00", 4808 "Nicaraguan c\\u00f3rdobas1.00", 4809 "Nicaraguan c\\u00f3rdoba (1988\\u20131991)1.00", 4810 "Nicaraguan c\\u00f3rdobas (1988\\u20131991)1.00", 4811 "Nigerian Naira1.00", 4812 "Nigerian naira1.00", 4813 "Nigerian nairas1.00", 4814 "North Korean Won1.00", 4815 "North Korean won1.00", 4816 "North Korean won1.00", 4817 "Norwegian Krone1.00", 4818 "Norwegian krone1.00", 4819 "Norwegian kroner1.00", 4820 "OMR1.00", 4821 "Mozambican Metical (1980\\u20132006)1.00", 4822 "Mozambican metical (1980\\u20132006)1.00", 4823 "Mozambican meticals (1980\\u20132006)1.00", 4824 "Romanian Lei (1952\\u20132006)1.00", 4825 "Romanian Leu (1952\\u20132006)1.00", 4826 "Romanian leu (1952\\u20132006)1.00", 4827 "Serbian Dinar (2002\\u20132006)1.00", 4828 "Serbian dinar (2002\\u20132006)1.00", 4829 "Serbian dinars (2002\\u20132006)1.00", 4830 "Sudanese Dinar (1992\\u20132007)1.00", 4831 "Sudanese Pound (1957\\u20131998)1.00", 4832 "Sudanese dinar (1992\\u20132007)1.00", 4833 "Sudanese dinars (1992\\u20132007)1.00", 4834 "Sudanese pound (1957\\u20131998)1.00", 4835 "Sudanese pounds (1957\\u20131998)1.00", 4836 "Turkish Lira (1922\\u20132005)1.00", 4837 "Turkish Lira (1922\\u20132005)1.00", 4838 "Omani Rial1.00", 4839 "Omani rial1.00", 4840 "Omani rials1.00", 4841 "PAB1.00", 4842 "PAB1.00", 4843 "PEI1.00", 4844 "PEI1.00", 4845 "PEN1.00", 4846 "PEN1.00", 4847 "PES1.00", 4848 "PES1.00", 4849 "PGK1.00", 4850 "PGK1.00", 4851 "PHP1.00", 4852 "PKR1.00", 4853 "PLN1.00", 4854 "PLZ1.00", 4855 "PLZ1.00", 4856 "PTE1.00", 4857 "PTE1.00", 4858 "PYG1.00", 4859 "Pakistani Rupee1.00", 4860 "Pakistani rupee1.00", 4861 "Pakistani rupees1.00", 4862 "Palladium1.00", 4863 "Palladium1.00", 4864 "Panamanian Balboa1.00", 4865 "Panamanian balboa1.00", 4866 "Panamanian balboas1.00", 4867 "Papua New Guinean Kina1.00", 4868 "Papua New Guinean kina1.00", 4869 "Papua New Guinean kina1.00", 4870 "Paraguayan Guarani1.00", 4871 "Paraguayan guarani1.00", 4872 "Paraguayan guaranis1.00", 4873 "Peruvian Inti1.00", 4874 "Peruvian Nuevo Sol1.00", 4875 "Peruvian Sol (1863\\u20131965)1.00", 4876 "Peruvian inti1.00", 4877 "Peruvian intis1.00", 4878 "Peruvian nuevo sol1.00", 4879 "Peruvian nuevos soles1.00", 4880 "Peruvian sol (1863\\u20131965)1.00", 4881 "Peruvian soles (1863\\u20131965)1.00", 4882 "Philippine Peso1.00", 4883 "Philippine peso1.00", 4884 "Philippine pesos1.00", 4885 "Platinum1.00", 4886 "Platinum1.00", 4887 "Polish Zloty (1950\\u20131995)1.00", 4888 "Polish Zloty1.00", 4889 "Polish zlotys1.00", 4890 "Polish zloty (PLZ)1.00", 4891 "Polish zloty1.00", 4892 "Polish zlotys (PLZ)1.00", 4893 "Portuguese Escudo1.00", 4894 "Portuguese Guinea Escudo1.00", 4895 "Portuguese Guinea escudo1.00", 4896 "Portuguese Guinea escudos1.00", 4897 "Portuguese escudo1.00", 4898 "Portuguese escudos1.00", 4899 "GTQ1.00", 4900 "QAR1.00", 4901 "Qatari Rial1.00", 4902 "Qatari rial1.00", 4903 "Qatari rials1.00", 4904 "RHD1.00", 4905 "RHD1.00", 4906 "RINET Funds1.00", 4907 "RINET Funds1.00", 4908 "CN\\u00a51.00", 4909 "ROL1.00", 4910 "ROL1.00", 4911 "RON1.00", 4912 "RON1.00", 4913 "RSD1.00", 4914 "RSD1.00", 4915 "RUB1.00", 4916 "RUR1.00", 4917 "RUR1.00", 4918 "RWF1.00", 4919 "RWF1.00", 4920 "Rhodesian Dollar1.00", 4921 "Rhodesian dollar1.00", 4922 "Rhodesian dollars1.00", 4923 "Romanian Leu1.00", 4924 "Romanian lei1.00", 4925 "Romanian leu1.00", 4926 "Russian Ruble (1991\\u20131998)1.00", 4927 "Russian Ruble1.00", 4928 "Russian ruble (1991\\u20131998)1.00", 4929 "Russian ruble1.00", 4930 "Russian rubles (1991\\u20131998)1.00", 4931 "Russian rubles1.00", 4932 "Rwandan Franc1.00", 4933 "Rwandan franc1.00", 4934 "Rwandan francs1.00", 4935 "SAR1.00", 4936 "SBD1.00", 4937 "SCR1.00", 4938 "SDD1.00", 4939 "SDD1.00", 4940 "SDG1.00", 4941 "SDG1.00", 4942 "SDP1.00", 4943 "SDP1.00", 4944 "SEK1.00", 4945 "SGD1.00", 4946 "SHP1.00", 4947 "SHP1.00", 4948 "SIT1.00", 4949 "SIT1.00", 4950 "SKK1.00", 4951 "SLL1.00", 4952 "SLL1.00", 4953 "SOS1.00", 4954 "SRD1.00", 4955 "SRD1.00", 4956 "SRG1.00", 4957 "STD1.00", 4958 "SUR1.00", 4959 "SUR1.00", 4960 "SVC1.00", 4961 "SVC1.00", 4962 "SYP1.00", 4963 "SZL1.00", 4964 "St. Helena Pound1.00", 4965 "St. Helena pound1.00", 4966 "St. Helena pounds1.00", 4967 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobra1.00", 4968 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobra1.00", 4969 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobras1.00", 4970 "Saudi Riyal1.00", 4971 "Saudi riyal1.00", 4972 "Saudi riyals1.00", 4973 "Serbian Dinar1.00", 4974 "Serbian dinar1.00", 4975 "Serbian dinars1.00", 4976 "Seychellois Rupee1.00", 4977 "Seychellois rupee1.00", 4978 "Seychellois rupees1.00", 4979 "Sierra Leonean Leone1.00", 4980 "Sierra Leonean leone1.00", 4981 "Sierra Leonean leones1.00", 4982 "Silver1.00", 4983 "Silver1.00", 4984 "Singapore Dollar1.00", 4985 "Singapore dollar1.00", 4986 "Singapore dollars1.00", 4987 "Slovak Koruna1.00", 4988 "Slovak koruna1.00", 4989 "Slovak korunas1.00", 4990 "Slovenian Tolar1.00", 4991 "Slovenian tolar1.00", 4992 "Slovenian tolars1.00", 4993 "Solomon Islands Dollar1.00", 4994 "Solomon Islands dollar1.00", 4995 "Solomon Islands dollars1.00", 4996 "Somali Shilling1.00", 4997 "Somali shilling1.00", 4998 "Somali shillings1.00", 4999 "South African Rand (financial)1.00", 5000 "South African Rand1.00", 5001 "South African rand (financial)1.00", 5002 "South African rand1.00", 5003 "South African rands (financial)1.00", 5004 "South African rand1.00", 5005 "South Korean Won1.00", 5006 "South Korean won1.00", 5007 "South Korean won1.00", 5008 "Soviet Rouble1.00", 5009 "Soviet rouble1.00", 5010 "Soviet roubles1.00", 5011 "Spanish Peseta (A account)1.00", 5012 "Spanish Peseta (convertible account)1.00", 5013 "Spanish Peseta1.00", 5014 "Spanish peseta (A account)1.00", 5015 "Spanish peseta (convertible account)1.00", 5016 "Spanish peseta1.00", 5017 "Spanish pesetas (A account)1.00", 5018 "Spanish pesetas (convertible account)1.00", 5019 "Spanish pesetas1.00", 5020 "Special Drawing Rights1.00", 5021 "Sri Lankan Rupee1.00", 5022 "Sri Lankan rupee1.00", 5023 "Sri Lankan rupees1.00", 5024 "Sudanese Pound1.00", 5025 "Sudanese pound1.00", 5026 "Sudanese pounds1.00", 5027 "Surinamese Dollar1.00", 5028 "Surinamese dollar1.00", 5029 "Surinamese dollars1.00", 5030 "Surinamese Guilder1.00", 5031 "Surinamese guilder1.00", 5032 "Surinamese guilders1.00", 5033 "Swazi Lilangeni1.00", 5034 "Swazi lilangeni1.00", 5035 "Swazi emalangeni1.00", 5036 "Swedish Krona1.00", 5037 "Swedish krona1.00", 5038 "Swedish kronor1.00", 5039 "Swiss Franc1.00", 5040 "Swiss franc1.00", 5041 "Swiss francs1.00", 5042 "Syrian Pound1.00", 5043 "Syrian pound1.00", 5044 "Syrian pounds1.00", 5045 "THB1.00", 5046 "TJR1.00", 5047 "TJR1.00", 5048 "TJS1.00", 5049 "TJS1.00", 5050 "TMM1.00", 5051 "TMM1.00", 5052 "TND1.00", 5053 "TND1.00", 5054 "TOP1.00", 5055 "TPE1.00", 5056 "TPE1.00", 5057 "TRL1.00", 5058 "TRY1.00", 5059 "TRY1.00", 5060 "TTD1.00", 5061 "TWD1.00", 5062 "TZS1.00", 5063 "New Taiwan Dollar1.00", 5064 "New Taiwan dollar1.00", 5065 "New Taiwan dollars1.00", 5066 "Tajikistani Ruble1.00", 5067 "Tajikistani Somoni1.00", 5068 "Tajikistani ruble1.00", 5069 "Tajikistani rubles1.00", 5070 "Tajikistani somoni1.00", 5071 "Tajikistani somonis1.00", 5072 "Tanzanian Shilling1.00", 5073 "Tanzanian shilling1.00", 5074 "Tanzanian shillings1.00", 5075 "Testing Currency Code1.00", 5076 "Testing Currency Code1.00", 5077 "Thai Baht1.00", 5078 "Thai baht1.00", 5079 "Thai baht1.00", 5080 "Timorese Escudo1.00", 5081 "Timorese escudo1.00", 5082 "Timorese escudos1.00", 5083 "Tongan Pa\\u02bbanga1.00", 5084 "Tongan pa\\u02bbanga1.00", 5085 "Tongan pa\\u02bbanga1.00", 5086 "Trinidad & Tobago Dollar1.00", 5087 "Trinidad & Tobago dollar1.00", 5088 "Trinidad & Tobago dollars1.00", 5089 "Tunisian Dinar1.00", 5090 "Tunisian dinar1.00", 5091 "Tunisian dinars1.00", 5092 "Turkish Lira1.00", 5093 "Turkish Lira1.00", 5094 "Turkish lira1.00", 5095 "Turkmenistani Manat1.00", 5096 "Turkmenistani manat1.00", 5097 "Turkmenistani manat1.00", 5098 "UAE dirham1.00", 5099 "UAE dirhams1.00", 5100 "UAH1.00", 5101 "UAK1.00", 5102 "UAK1.00", 5103 "UGS1.00", 5104 "UGS1.00", 5105 "UGX1.00", 5106 "US Dollar (Next day)1.00", 5107 "US Dollar (Same day)1.00", 5108 "US Dollar1.00", 5109 "US dollar (next day)1.00", 5110 "US dollar (same day)1.00", 5111 "US dollar1.00", 5112 "US dollars (next day)1.00", 5113 "US dollars (same day)1.00", 5114 "US dollars1.00", 5115 "USD1.00", 5116 "USN1.00", 5117 "USN1.00", 5118 "USS1.00", 5119 "USS1.00", 5120 "UYI1.00", 5121 "UYI1.00", 5122 "UYP1.00", 5123 "UYP1.00", 5124 "UYU1.00", 5125 "UZS1.00", 5126 "UZS1.00", 5127 "Ugandan Shilling (1966\\u20131987)1.00", 5128 "Ugandan Shilling1.00", 5129 "Ugandan shilling (1966\\u20131987)1.00", 5130 "Ugandan shilling1.00", 5131 "Ugandan shillings (1966\\u20131987)1.00", 5132 "Ugandan shillings1.00", 5133 "Ukrainian Hryvnia1.00", 5134 "Ukrainian Karbovanets1.00", 5135 "Ukrainian hryvnia1.00", 5136 "Ukrainian hryvnias1.00", 5137 "Ukrainian karbovanets1.00", 5138 "Ukrainian karbovantsiv1.00", 5139 "Colombian Real Value Unit1.00", 5140 "United Arab Emirates Dirham1.00", 5141 "Unknown Currency1.00", 5142 "Uruguayan Peso (1975\\u20131993)1.00", 5143 "Uruguayan Peso1.00", 5144 "Uruguayan Peso (Indexed Units)1.00", 5145 "Uruguayan peso (1975\\u20131993)1.00", 5146 "Uruguayan peso (indexed units)1.00", 5147 "Uruguayan peso1.00", 5148 "Uruguayan pesos (1975\\u20131993)1.00", 5149 "Uruguayan pesos (indexed units)1.00", 5150 "Uruguayan pesos1.00", 5151 "Uzbekistani Som1.00", 5152 "Uzbekistani som1.00", 5153 "Uzbekistani som1.00", 5154 "VEB1.00", 5155 "VEF1.00", 5156 "VND1.00", 5157 "VUV1.00", 5158 "Vanuatu Vatu1.00", 5159 "Vanuatu vatu1.00", 5160 "Vanuatu vatus1.00", 5161 "Venezuelan Bol\\u00edvar1.00", 5162 "Venezuelan Bol\\u00edvar (1871\\u20132008)1.00", 5163 "Venezuelan bol\\u00edvar1.00", 5164 "Venezuelan bol\\u00edvars1.00", 5165 "Venezuelan bol\\u00edvar (1871\\u20132008)1.00", 5166 "Venezuelan bol\\u00edvars (1871\\u20132008)1.00", 5167 "Vietnamese Dong1.00", 5168 "Vietnamese dong1.00", 5169 "Vietnamese dong1.00", 5170 "WIR Euro1.00", 5171 "WIR Franc1.00", 5172 "WIR euro1.00", 5173 "WIR euros1.00", 5174 "WIR franc1.00", 5175 "WIR francs1.00", 5176 "WST1.00", 5177 "WST1.00", 5178 "Samoan Tala1.00", 5179 "Samoan tala1.00", 5180 "Samoan tala1.00", 5181 "XAF1.00", 5182 "XAF1.00", 5183 "XAG1.00", 5184 "XAG1.00", 5185 "XAU1.00", 5186 "XAU1.00", 5187 "XBA1.00", 5188 "XBA1.00", 5189 "XBB1.00", 5190 "XBB1.00", 5191 "XBC1.00", 5192 "XBC1.00", 5193 "XBD1.00", 5194 "XBD1.00", 5195 "XCD1.00", 5196 "XDR1.00", 5197 "XDR1.00", 5198 "XEU1.00", 5199 "XEU1.00", 5200 "XFO1.00", 5201 "XFO1.00", 5202 "XFU1.00", 5203 "XFU1.00", 5204 "XOF1.00", 5205 "XOF1.00", 5206 "XPD1.00", 5207 "XPD1.00", 5208 "XPF1.00", 5209 "XPT1.00", 5210 "XPT1.00", 5211 "XRE1.00", 5212 "XRE1.00", 5213 "XTS1.00", 5214 "XTS1.00", 5215 "XXX1.00", 5216 "XXX1.00", 5217 "YDD1.00", 5218 "YDD1.00", 5219 "YER1.00", 5220 "YUD1.00", 5221 "YUD1.00", 5222 "YUM1.00", 5223 "YUM1.00", 5224 "YUN1.00", 5225 "YUN1.00", 5226 "Yemeni Dinar1.00", 5227 "Yemeni Rial1.00", 5228 "Yemeni dinar1.00", 5229 "Yemeni dinars1.00", 5230 "Yemeni rial1.00", 5231 "Yemeni rials1.00", 5232 "Yugoslavian Convertible Dinar (1990\\u20131992)1.00", 5233 "Yugoslavian Hard Dinar (1966\\u20131990)1.00", 5234 "Yugoslavian New Dinar (1994\\u20132002)1.00", 5235 "Yugoslavian convertible dinar (1990\\u20131992)1.00", 5236 "Yugoslavian convertible dinars (1990\\u20131992)1.00", 5237 "Yugoslavian hard dinar (1966\\u20131990)1.00", 5238 "Yugoslavian hard dinars (1966\\u20131990)1.00", 5239 "Yugoslavian new dinar (1994\\u20132002)1.00", 5240 "Yugoslavian new dinars (1994\\u20132002)1.00", 5241 "ZAL1.00", 5242 "ZAL1.00", 5243 "ZAR1.00", 5244 "ZMK1.00", 5245 "ZMK1.00", 5246 "ZRN1.00", 5247 "ZRN1.00", 5248 "ZRZ1.00", 5249 "ZRZ1.00", 5250 "ZWD1.00", 5251 "Zairean New Zaire (1993\\u20131998)1.00", 5252 "Zairean Zaire (1971\\u20131993)1.00", 5253 "Zairean new zaire (1993\\u20131998)1.00", 5254 "Zairean new zaires (1993\\u20131998)1.00", 5255 "Zairean zaire (1971\\u20131993)1.00", 5256 "Zairean zaires (1971\\u20131993)1.00", 5257 "Zambian Kwacha1.00", 5258 "Zambian kwacha1.00", 5259 "Zambian kwachas1.00", 5260 "Zimbabwean Dollar (1980\\u20132008)1.00", 5261 "Zimbabwean dollar (1980\\u20132008)1.00", 5262 "Zimbabwean dollars (1980\\u20132008)1.00", 5263 "euro1.00", 5264 "euros1.00", 5265 "Turkish lira (1922\\u20132005)1.00", 5266 "special drawing rights1.00", 5267 "Colombian real value unit1.00", 5268 "Colombian real value units1.00", 5269 "unknown currency1.00", 5270 "\\u00a31.00", 5271 "\\u00a51.00", 5272 "\\u20ab1.00", 5273 "\\u20aa1.00", 5274 "\\u20ac1.00", 5275 "\\u20b91.00", 5276 // 5277 // Following has extra text, should be parsed correctly too 5278 "$1.00 random", 5279 "USD1.00 random", 5280 "1.00 US dollar random", 5281 "1.00 US dollars random", 5282 "1.00 Afghan Afghani random", 5283 "1.00 Afghan Afghani random", 5284 "1.00 Afghan Afghanis (1927\\u20131992) random", 5285 "1.00 Afghan Afghanis random", 5286 "1.00 Albanian Lek random", 5287 "1.00 Albanian lek random", 5288 "1.00 Albanian lek\\u00eb random", 5289 "1.00 Algerian Dinar random", 5290 "1.00 Algerian dinar random", 5291 "1.00 Algerian dinars random", 5292 "1.00 Andorran Peseta random", 5293 "1.00 Andorran peseta random", 5294 "1.00 Andorran pesetas random", 5295 "1.00 Angolan Kwanza (1977\\u20131990) random", 5296 "1.00 Angolan Readjusted Kwanza (1995\\u20131999) random", 5297 "1.00 Angolan Kwanza random", 5298 "1.00 Angolan New Kwanza (1990\\u20132000) random", 5299 "1.00 Angolan kwanza (1977\\u20131991) random", 5300 "1.00 Angolan readjusted kwanza (1995\\u20131999) random", 5301 "1.00 Angolan kwanza random", 5302 "1.00 Angolan kwanzas (1977\\u20131991) random", 5303 "1.00 Angolan readjusted kwanzas (1995\\u20131999) random", 5304 "1.00 Angolan kwanzas random", 5305 "1.00 Angolan new kwanza (1990\\u20132000) random", 5306 "1.00 Angolan new kwanzas (1990\\u20132000) random", 5307 "1.00 Argentine Austral random", 5308 "1.00 Argentine Peso (1983\\u20131985) random", 5309 "1.00 Argentine Peso random", 5310 "1.00 Argentine austral random", 5311 "1.00 Argentine australs random", 5312 "1.00 Argentine peso (1983\\u20131985) random", 5313 "1.00 Argentine peso random", 5314 "1.00 Argentine pesos (1983\\u20131985) random", 5315 "1.00 Argentine pesos random", 5316 "1.00 Armenian Dram random", 5317 "1.00 Armenian dram random", 5318 "1.00 Armenian drams random", 5319 "1.00 Aruban Florin random", 5320 "1.00 Aruban florin random", 5321 "1.00 Australian Dollar random", 5322 "1.00 Australian dollar random", 5323 "1.00 Australian dollars random", 5324 "1.00 Austrian Schilling random", 5325 "1.00 Austrian schilling random", 5326 "1.00 Austrian schillings random", 5327 "1.00 Azerbaijani Manat (1993\\u20132006) random", 5328 "1.00 Azerbaijani Manat random", 5329 "1.00 Azerbaijani manat (1993\\u20132006) random", 5330 "1.00 Azerbaijani manat random", 5331 "1.00 Azerbaijani manats (1993\\u20132006) random", 5332 "1.00 Azerbaijani manats random", 5333 "1.00 Bahamian Dollar random", 5334 "1.00 Bahamian dollar random", 5335 "1.00 Bahamian dollars random", 5336 "1.00 Bahraini Dinar random", 5337 "1.00 Bahraini dinar random", 5338 "1.00 Bahraini dinars random", 5339 "1.00 Bangladeshi Taka random", 5340 "1.00 Bangladeshi taka random", 5341 "1.00 Bangladeshi takas random", 5342 "1.00 Barbadian Dollar random", 5343 "1.00 Barbadian dollar random", 5344 "1.00 Barbadian dollars random", 5345 "1.00 Belarusian New Ruble (1994\\u20131999) random", 5346 "1.00 Belarusian Ruble random", 5347 "1.00 Belarusian new ruble (1994\\u20131999) random", 5348 "1.00 Belarusian new rubles (1994\\u20131999) random", 5349 "1.00 Belarusian ruble random", 5350 "1.00 Belarusian rubles random", 5351 "1.00 Belgian Franc (convertible) random", 5352 "1.00 Belgian Franc (financial) random", 5353 "1.00 Belgian Franc random", 5354 "1.00 Belgian franc (convertible) random", 5355 "1.00 Belgian franc (financial) random", 5356 "1.00 Belgian franc random", 5357 "1.00 Belgian francs (convertible) random", 5358 "1.00 Belgian francs (financial) random", 5359 "1.00 Belgian francs random", 5360 "1.00 Belize Dollar random", 5361 "1.00 Belize dollar random", 5362 "1.00 Belize dollars random", 5363 "1.00 Bermudan Dollar random", 5364 "1.00 Bermudan dollar random", 5365 "1.00 Bermudan dollars random", 5366 "1.00 Bhutanese Ngultrum random", 5367 "1.00 Bhutanese ngultrum random", 5368 "1.00 Bhutanese ngultrums random", 5369 "1.00 Bolivian Mvdol random", 5370 "1.00 Bolivian Peso random", 5371 "1.00 Bolivian mvdol random", 5372 "1.00 Bolivian mvdols random", 5373 "1.00 Bolivian peso random", 5374 "1.00 Bolivian pesos random", 5375 "1.00 Bolivian Boliviano random", 5376 "1.00 Bolivian Boliviano random", 5377 "1.00 Bolivian Bolivianos random", 5378 "1.00 Bosnia-Herzegovina Convertible Mark random", 5379 "1.00 Bosnia-Herzegovina Dinar (1992\\u20131994) random", 5380 "1.00 Bosnia-Herzegovina convertible mark random", 5381 "1.00 Bosnia-Herzegovina convertible marks random", 5382 "1.00 Bosnia-Herzegovina dinar (1992\\u20131994) random", 5383 "1.00 Bosnia-Herzegovina dinars (1992\\u20131994) random", 5384 "1.00 Botswanan Pula random", 5385 "1.00 Botswanan pula random", 5386 "1.00 Botswanan pulas random", 5387 "1.00 Brazilian New Cruzado (1989\\u20131990) random", 5388 "1.00 Brazilian Cruzado (1986\\u20131989) random", 5389 "1.00 Brazilian Cruzeiro (1990\\u20131993) random", 5390 "1.00 Brazilian New Cruzeiro (1967\\u20131986) random", 5391 "1.00 Brazilian Cruzeiro (1993\\u20131994) random", 5392 "1.00 Brazilian Real random", 5393 "1.00 Brazilian new cruzado (1989\\u20131990) random", 5394 "1.00 Brazilian new cruzados (1989\\u20131990) random", 5395 "1.00 Brazilian cruzado (1986\\u20131989) random", 5396 "1.00 Brazilian cruzados (1986\\u20131989) random", 5397 "1.00 Brazilian cruzeiro (1990\\u20131993) random", 5398 "1.00 Brazilian new cruzeiro (1967\\u20131986) random", 5399 "1.00 Brazilian cruzeiro (1993\\u20131994) random", 5400 "1.00 Brazilian cruzeiros (1990\\u20131993) random", 5401 "1.00 Brazilian new cruzeiros (1967\\u20131986) random", 5402 "1.00 Brazilian cruzeiros (1993\\u20131994) random", 5403 "1.00 Brazilian real random", 5404 "1.00 Brazilian reals random", 5405 "1.00 British Pound random", 5406 "1.00 British pound random", 5407 "1.00 British pounds random", 5408 "1.00 Brunei Dollar random", 5409 "1.00 Brunei dollar random", 5410 "1.00 Brunei dollars random", 5411 "1.00 Bulgarian Hard Lev random", 5412 "1.00 Bulgarian Lev random", 5413 "1.00 Bulgarian Leva random", 5414 "1.00 Bulgarian hard lev random", 5415 "1.00 Bulgarian hard leva random", 5416 "1.00 Bulgarian lev random", 5417 "1.00 Burmese Kyat random", 5418 "1.00 Burmese kyat random", 5419 "1.00 Burmese kyats random", 5420 "1.00 Burundian Franc random", 5421 "1.00 Burundian franc random", 5422 "1.00 Burundian francs random", 5423 "1.00 Cambodian Riel random", 5424 "1.00 Cambodian riel random", 5425 "1.00 Cambodian riels random", 5426 "1.00 Canadian Dollar random", 5427 "1.00 Canadian dollar random", 5428 "1.00 Canadian dollars random", 5429 "1.00 Cape Verdean Escudo random", 5430 "1.00 Cape Verdean escudo random", 5431 "1.00 Cape Verdean escudos random", 5432 "1.00 Cayman Islands Dollar random", 5433 "1.00 Cayman Islands dollar random", 5434 "1.00 Cayman Islands dollars random", 5435 "1.00 Chilean Peso random", 5436 "1.00 Chilean Unit of Account (UF) random", 5437 "1.00 Chilean peso random", 5438 "1.00 Chilean pesos random", 5439 "1.00 Chilean unit of account (UF) random", 5440 "1.00 Chilean units of account (UF) random", 5441 "1.00 Chinese Yuan random", 5442 "1.00 Chinese yuan random", 5443 "1.00 Colombian Peso random", 5444 "1.00 Colombian peso random", 5445 "1.00 Colombian pesos random", 5446 "1.00 Comorian Franc random", 5447 "1.00 Comorian franc random", 5448 "1.00 Comorian francs random", 5449 "1.00 Congolese Franc Congolais random", 5450 "1.00 Congolese franc Congolais random", 5451 "1.00 Congolese francs Congolais random", 5452 "1.00 Costa Rican Col\\u00f3n random", 5453 "1.00 Costa Rican col\\u00f3n random", 5454 "1.00 Costa Rican col\\u00f3ns random", 5455 "1.00 Croatian Dinar random", 5456 "1.00 Croatian Kuna random", 5457 "1.00 Croatian dinar random", 5458 "1.00 Croatian dinars random", 5459 "1.00 Croatian kuna random", 5460 "1.00 Croatian kunas random", 5461 "1.00 Cuban Peso random", 5462 "1.00 Cuban peso random", 5463 "1.00 Cuban pesos random", 5464 "1.00 Cypriot Pound random", 5465 "1.00 Cypriot pound random", 5466 "1.00 Cypriot pounds random", 5467 "1.00 Czech Republic Koruna random", 5468 "1.00 Czech Republic koruna random", 5469 "1.00 Czech Republic korunas random", 5470 "1.00 Czechoslovak Hard Koruna random", 5471 "1.00 Czechoslovak hard koruna random", 5472 "1.00 Czechoslovak hard korunas random", 5473 "1.00 Danish Krone random", 5474 "1.00 Danish krone random", 5475 "1.00 Danish kroner random", 5476 "1.00 German Mark random", 5477 "1.00 German mark random", 5478 "1.00 German marks random", 5479 "1.00 Djiboutian Franc random", 5480 "1.00 Djiboutian franc random", 5481 "1.00 Djiboutian francs random", 5482 "1.00 Dominican Peso random", 5483 "1.00 Dominican peso random", 5484 "1.00 Dominican pesos random", 5485 "1.00 East Caribbean Dollar random", 5486 "1.00 East Caribbean dollar random", 5487 "1.00 East Caribbean dollars random", 5488 "1.00 East German Mark random", 5489 "1.00 East German mark random", 5490 "1.00 East German marks random", 5491 "1.00 Ecuadorian Sucre random", 5492 "1.00 Ecuadorian Unit of Constant Value random", 5493 "1.00 Ecuadorian sucre random", 5494 "1.00 Ecuadorian sucres random", 5495 "1.00 Ecuadorian unit of constant value random", 5496 "1.00 Ecuadorian units of constant value random", 5497 "1.00 Egyptian Pound random", 5498 "1.00 Egyptian pound random", 5499 "1.00 Egyptian pounds random", 5500 "1.00 Salvadoran Col\\u00f3n random", 5501 "1.00 Salvadoran col\\u00f3n random", 5502 "1.00 Salvadoran colones random", 5503 "1.00 Equatorial Guinean Ekwele random", 5504 "1.00 Equatorial Guinean ekwele random", 5505 "1.00 Eritrean Nakfa random", 5506 "1.00 Eritrean nakfa random", 5507 "1.00 Eritrean nakfas random", 5508 "1.00 Estonian Kroon random", 5509 "1.00 Estonian kroon random", 5510 "1.00 Estonian kroons random", 5511 "1.00 Ethiopian Birr random", 5512 "1.00 Ethiopian birr random", 5513 "1.00 Ethiopian birrs random", 5514 "1.00 European Composite Unit random", 5515 "1.00 European Currency Unit random", 5516 "1.00 European Monetary Unit random", 5517 "1.00 European Unit of Account (XBC) random", 5518 "1.00 European Unit of Account (XBD) random", 5519 "1.00 European composite unit random", 5520 "1.00 European composite units random", 5521 "1.00 European currency unit random", 5522 "1.00 European currency units random", 5523 "1.00 European monetary unit random", 5524 "1.00 European monetary units random", 5525 "1.00 European unit of account (XBC) random", 5526 "1.00 European unit of account (XBD) random", 5527 "1.00 European units of account (XBC) random", 5528 "1.00 European units of account (XBD) random", 5529 "1.00 Falkland Islands Pound random", 5530 "1.00 Falkland Islands pound random", 5531 "1.00 Falkland Islands pounds random", 5532 "1.00 Fijian Dollar random", 5533 "1.00 Fijian dollar random", 5534 "1.00 Fijian dollars random", 5535 "1.00 Finnish Markka random", 5536 "1.00 Finnish markka random", 5537 "1.00 Finnish markkas random", 5538 "1.00 French Franc random", 5539 "1.00 French Gold Franc random", 5540 "1.00 French UIC-Franc random", 5541 "1.00 French UIC-franc random", 5542 "1.00 French UIC-francs random", 5543 "1.00 French franc random", 5544 "1.00 French francs random", 5545 "1.00 French gold franc random", 5546 "1.00 French gold francs random", 5547 "1.00 Gambian Dalasi random", 5548 "1.00 Gambian dalasi random", 5549 "1.00 Gambian dalasis random", 5550 "1.00 Georgian Kupon Larit random", 5551 "1.00 Georgian Lari random", 5552 "1.00 Georgian kupon larit random", 5553 "1.00 Georgian kupon larits random", 5554 "1.00 Georgian lari random", 5555 "1.00 Georgian laris random", 5556 "1.00 Ghanaian Cedi (1979\\u20132007) random", 5557 "1.00 Ghanaian Cedi random", 5558 "1.00 Ghanaian cedi (1979\\u20132007) random", 5559 "1.00 Ghanaian cedi random", 5560 "1.00 Ghanaian cedis (1979\\u20132007) random", 5561 "1.00 Ghanaian cedis random", 5562 "1.00 Gibraltar Pound random", 5563 "1.00 Gibraltar pound random", 5564 "1.00 Gibraltar pounds random", 5565 "1.00 Gold random", 5566 "1.00 Gold random", 5567 "1.00 Greek Drachma random", 5568 "1.00 Greek drachma random", 5569 "1.00 Greek drachmas random", 5570 "1.00 Guatemalan Quetzal random", 5571 "1.00 Guatemalan quetzal random", 5572 "1.00 Guatemalan quetzals random", 5573 "1.00 Guinean Franc random", 5574 "1.00 Guinean Syli random", 5575 "1.00 Guinean franc random", 5576 "1.00 Guinean francs random", 5577 "1.00 Guinean syli random", 5578 "1.00 Guinean sylis random", 5579 "1.00 Guinea-Bissau Peso random", 5580 "1.00 Guinea-Bissau peso random", 5581 "1.00 Guinea-Bissau pesos random", 5582 "1.00 Guyanaese Dollar random", 5583 "1.00 Guyanaese dollar random", 5584 "1.00 Guyanaese dollars random", 5585 "1.00 Haitian Gourde random", 5586 "1.00 Haitian gourde random", 5587 "1.00 Haitian gourdes random", 5588 "1.00 Honduran Lempira random", 5589 "1.00 Honduran lempira random", 5590 "1.00 Honduran lempiras random", 5591 "1.00 Hong Kong Dollar random", 5592 "1.00 Hong Kong dollar random", 5593 "1.00 Hong Kong dollars random", 5594 "1.00 Hungarian Forint random", 5595 "1.00 Hungarian forint random", 5596 "1.00 Hungarian forints random", 5597 "1.00 Icelandic Kr\\u00f3na random", 5598 "1.00 Icelandic kr\\u00f3na random", 5599 "1.00 Icelandic kr\\u00f3nur random", 5600 "1.00 Indian Rupee random", 5601 "1.00 Indian rupee random", 5602 "1.00 Indian rupees random", 5603 "1.00 Indonesian Rupiah random", 5604 "1.00 Indonesian rupiah random", 5605 "1.00 Indonesian rupiahs random", 5606 "1.00 Iranian Rial random", 5607 "1.00 Iranian rial random", 5608 "1.00 Iranian rials random", 5609 "1.00 Iraqi Dinar random", 5610 "1.00 Iraqi dinar random", 5611 "1.00 Iraqi dinars random", 5612 "1.00 Irish Pound random", 5613 "1.00 Irish pound random", 5614 "1.00 Irish pounds random", 5615 "1.00 Israeli Pound random", 5616 "1.00 Israeli new sheqel random", 5617 "1.00 Israeli pound random", 5618 "1.00 Israeli pounds random", 5619 "1.00 Italian Lira random", 5620 "1.00 Italian lira random", 5621 "1.00 Italian liras random", 5622 "1.00 Jamaican Dollar random", 5623 "1.00 Jamaican dollar random", 5624 "1.00 Jamaican dollars random", 5625 "1.00 Japanese Yen random", 5626 "1.00 Japanese yen random", 5627 "1.00 Jordanian Dinar random", 5628 "1.00 Jordanian dinar random", 5629 "1.00 Jordanian dinars random", 5630 "1.00 Kazakhstani Tenge random", 5631 "1.00 Kazakhstani tenge random", 5632 "1.00 Kazakhstani tenges random", 5633 "1.00 Kenyan Shilling random", 5634 "1.00 Kenyan shilling random", 5635 "1.00 Kenyan shillings random", 5636 "1.00 Kuwaiti Dinar random", 5637 "1.00 Kuwaiti dinar random", 5638 "1.00 Kuwaiti dinars random", 5639 "1.00 Kyrgystani Som random", 5640 "1.00 Kyrgystani som random", 5641 "1.00 Kyrgystani soms random", 5642 "1.00 Laotian Kip random", 5643 "1.00 Laotian kip random", 5644 "1.00 Laotian kips random", 5645 "1.00 Latvian Lats random", 5646 "1.00 Latvian Ruble random", 5647 "1.00 Latvian lats random", 5648 "1.00 Latvian lati random", 5649 "1.00 Latvian ruble random", 5650 "1.00 Latvian rubles random", 5651 "1.00 Lebanese Pound random", 5652 "1.00 Lebanese pound random", 5653 "1.00 Lebanese pounds random", 5654 "1.00 Lesotho Loti random", 5655 "1.00 Lesotho loti random", 5656 "1.00 Lesotho lotis random", 5657 "1.00 Liberian Dollar random", 5658 "1.00 Liberian dollar random", 5659 "1.00 Liberian dollars random", 5660 "1.00 Libyan Dinar random", 5661 "1.00 Libyan dinar random", 5662 "1.00 Libyan dinars random", 5663 "1.00 Lithuanian Litas random", 5664 "1.00 Lithuanian Talonas random", 5665 "1.00 Lithuanian litas random", 5666 "1.00 Lithuanian litai random", 5667 "1.00 Lithuanian talonas random", 5668 "1.00 Lithuanian talonases random", 5669 "1.00 Luxembourgian Convertible Franc random", 5670 "1.00 Luxembourg Financial Franc random", 5671 "1.00 Luxembourgian Franc random", 5672 "1.00 Luxembourgian convertible franc random", 5673 "1.00 Luxembourgian convertible francs random", 5674 "1.00 Luxembourg financial franc random", 5675 "1.00 Luxembourg financial francs random", 5676 "1.00 Luxembourgian franc random", 5677 "1.00 Luxembourgian francs random", 5678 "1.00 Macanese Pataca random", 5679 "1.00 Macanese pataca random", 5680 "1.00 Macanese patacas random", 5681 "1.00 Macedonian Denar random", 5682 "1.00 Macedonian denar random", 5683 "1.00 Macedonian denari random", 5684 "1.00 Malagasy Ariaries random", 5685 "1.00 Malagasy Ariary random", 5686 "1.00 Malagasy Ariary random", 5687 "1.00 Malagasy Franc random", 5688 "1.00 Malagasy franc random", 5689 "1.00 Malagasy francs random", 5690 "1.00 Malawian Kwacha random", 5691 "1.00 Malawian Kwacha random", 5692 "1.00 Malawian Kwachas random", 5693 "1.00 Malaysian Ringgit random", 5694 "1.00 Malaysian ringgit random", 5695 "1.00 Malaysian ringgits random", 5696 "1.00 Maldivian Rufiyaa random", 5697 "1.00 Maldivian rufiyaa random", 5698 "1.00 Maldivian rufiyaas random", 5699 "1.00 Malian Franc random", 5700 "1.00 Malian franc random", 5701 "1.00 Malian francs random", 5702 "1.00 Maltese Lira random", 5703 "1.00 Maltese Pound random", 5704 "1.00 Maltese lira random", 5705 "1.00 Maltese liras random", 5706 "1.00 Maltese pound random", 5707 "1.00 Maltese pounds random", 5708 "1.00 Mauritanian Ouguiya random", 5709 "1.00 Mauritanian ouguiya random", 5710 "1.00 Mauritanian ouguiyas random", 5711 "1.00 Mauritian Rupee random", 5712 "1.00 Mauritian rupee random", 5713 "1.00 Mauritian rupees random", 5714 "1.00 Mexican Peso random", 5715 "1.00 Mexican Silver Peso (1861\\u20131992) random", 5716 "1.00 Mexican Investment Unit random", 5717 "1.00 Mexican peso random", 5718 "1.00 Mexican pesos random", 5719 "1.00 Mexican silver peso (1861\\u20131992) random", 5720 "1.00 Mexican silver pesos (1861\\u20131992) random", 5721 "1.00 Mexican investment unit random", 5722 "1.00 Mexican investment units random", 5723 "1.00 Moldovan Leu random", 5724 "1.00 Moldovan leu random", 5725 "1.00 Moldovan lei random", 5726 "1.00 Mongolian Tugrik random", 5727 "1.00 Mongolian tugrik random", 5728 "1.00 Mongolian tugriks random", 5729 "1.00 Moroccan Dirham random", 5730 "1.00 Moroccan Franc random", 5731 "1.00 Moroccan dirham random", 5732 "1.00 Moroccan dirhams random", 5733 "1.00 Moroccan franc random", 5734 "1.00 Moroccan francs random", 5735 "1.00 Mozambican Escudo random", 5736 "1.00 Mozambican Metical random", 5737 "1.00 Mozambican escudo random", 5738 "1.00 Mozambican escudos random", 5739 "1.00 Mozambican metical random", 5740 "1.00 Mozambican meticals random", 5741 "1.00 Myanmar Kyat random", 5742 "1.00 Myanmar kyat random", 5743 "1.00 Myanmar kyats random", 5744 "1.00 Namibian Dollar random", 5745 "1.00 Namibian dollar random", 5746 "1.00 Namibian dollars random", 5747 "1.00 Nepalese Rupee random", 5748 "1.00 Nepalese rupee random", 5749 "1.00 Nepalese rupees random", 5750 "1.00 Netherlands Antillean Guilder random", 5751 "1.00 Netherlands Antillean guilder random", 5752 "1.00 Netherlands Antillean guilders random", 5753 "1.00 Dutch Guilder random", 5754 "1.00 Dutch guilder random", 5755 "1.00 Dutch guilders random", 5756 "1.00 Israeli New Sheqel random", 5757 "1.00 Israeli new sheqels random", 5758 "1.00 New Zealand Dollar random", 5759 "1.00 New Zealand dollar random", 5760 "1.00 New Zealand dollars random", 5761 "1.00 Nicaraguan C\\u00f3rdoba random", 5762 "1.00 Nicaraguan C\\u00f3rdoba (1988\\u20131991) random", 5763 "1.00 Nicaraguan c\\u00f3rdoba random", 5764 "1.00 Nicaraguan c\\u00f3rdoba random", 5765 "1.00 Nicaraguan c\\u00f3rdoba (1988\\u20131991) random", 5766 "1.00 Nicaraguan c\\u00f3rdobas (1988\\u20131991) random", 5767 "1.00 Nigerian Naira random", 5768 "1.00 Nigerian naira random", 5769 "1.00 Nigerian nairas random", 5770 "1.00 North Korean Won random", 5771 "1.00 North Korean won random", 5772 "1.00 North Korean won random", 5773 "1.00 Norwegian Krone random", 5774 "1.00 Norwegian krone random", 5775 "1.00 Norwegian kroner random", 5776 "1.00 Mozambican Metical (1980\\u20132006) random", 5777 "1.00 Mozambican metical (1980\\u20132006) random", 5778 "1.00 Mozambican meticals (1980\\u20132006) random", 5779 "1.00 Romanian Lei (1952\\u20132006) random", 5780 "1.00 Romanian Leu (1952\\u20132006) random", 5781 "1.00 Romanian leu (1952\\u20132006) random", 5782 "1.00 Serbian Dinar (2002\\u20132006) random", 5783 "1.00 Serbian dinar (2002\\u20132006) random", 5784 "1.00 Serbian dinars (2002\\u20132006) random", 5785 "1.00 Sudanese Dinar (1992\\u20132007) random", 5786 "1.00 Sudanese Pound (1957\\u20131998) random", 5787 "1.00 Sudanese dinar (1992\\u20132007) random", 5788 "1.00 Sudanese dinars (1992\\u20132007) random", 5789 "1.00 Sudanese pound (1957\\u20131998) random", 5790 "1.00 Sudanese pounds (1957\\u20131998) random", 5791 "1.00 Turkish Lira (1922\\u20132005) random", 5792 "1.00 Turkish Lira (1922\\u20132005) random", 5793 "1.00 Omani Rial random", 5794 "1.00 Omani rial random", 5795 "1.00 Omani rials random", 5796 "1.00 Pakistani Rupee random", 5797 "1.00 Pakistani rupee random", 5798 "1.00 Pakistani rupees random", 5799 "1.00 Palladium random", 5800 "1.00 Palladium random", 5801 "1.00 Panamanian Balboa random", 5802 "1.00 Panamanian balboa random", 5803 "1.00 Panamanian balboas random", 5804 "1.00 Papua New Guinean Kina random", 5805 "1.00 Papua New Guinean kina random", 5806 "1.00 Papua New Guinean kina random", 5807 "1.00 Paraguayan Guarani random", 5808 "1.00 Paraguayan guarani random", 5809 "1.00 Paraguayan guaranis random", 5810 "1.00 Peruvian Inti random", 5811 "1.00 Peruvian Nuevo Sol random", 5812 "1.00 Peruvian Sol (1863\\u20131965) random", 5813 "1.00 Peruvian inti random", 5814 "1.00 Peruvian intis random", 5815 "1.00 Peruvian nuevo sol random", 5816 "1.00 Peruvian nuevos soles random", 5817 "1.00 Peruvian sol (1863\\u20131965) random", 5818 "1.00 Peruvian soles (1863\\u20131965) random", 5819 "1.00 Philippine Peso random", 5820 "1.00 Philippine peso random", 5821 "1.00 Philippine pesos random", 5822 "1.00 Platinum random", 5823 "1.00 Platinum random", 5824 "1.00 Polish Zloty (1950\\u20131995) random", 5825 "1.00 Polish Zloty random", 5826 "1.00 Polish zlotys random", 5827 "1.00 Polish zloty (PLZ) random", 5828 "1.00 Polish zloty random", 5829 "1.00 Polish zlotys (PLZ) random", 5830 "1.00 Portuguese Escudo random", 5831 "1.00 Portuguese Guinea Escudo random", 5832 "1.00 Portuguese Guinea escudo random", 5833 "1.00 Portuguese Guinea escudos random", 5834 "1.00 Portuguese escudo random", 5835 "1.00 Portuguese escudos random", 5836 "1.00 Qatari Rial random", 5837 "1.00 Qatari rial random", 5838 "1.00 Qatari rials random", 5839 "1.00 RINET Funds random", 5840 "1.00 RINET Funds random", 5841 "1.00 Rhodesian Dollar random", 5842 "1.00 Rhodesian dollar random", 5843 "1.00 Rhodesian dollars random", 5844 "1.00 Romanian Leu random", 5845 "1.00 Romanian lei random", 5846 "1.00 Romanian leu random", 5847 "1.00 Russian Ruble (1991\\u20131998) random", 5848 "1.00 Russian Ruble random", 5849 "1.00 Russian ruble (1991\\u20131998) random", 5850 "1.00 Russian ruble random", 5851 "1.00 Russian rubles (1991\\u20131998) random", 5852 "1.00 Russian rubles random", 5853 "1.00 Rwandan Franc random", 5854 "1.00 Rwandan franc random", 5855 "1.00 Rwandan francs random", 5856 "1.00 St. Helena Pound random", 5857 "1.00 St. Helena pound random", 5858 "1.00 St. Helena pounds random", 5859 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobra random", 5860 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobra random", 5861 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobras random", 5862 "1.00 Saudi Riyal random", 5863 "1.00 Saudi riyal random", 5864 "1.00 Saudi riyals random", 5865 "1.00 Serbian Dinar random", 5866 "1.00 Serbian dinar random", 5867 "1.00 Serbian dinars random", 5868 "1.00 Seychellois Rupee random", 5869 "1.00 Seychellois rupee random", 5870 "1.00 Seychellois rupees random", 5871 "1.00 Sierra Leonean Leone random", 5872 "1.00 Sierra Leonean leone random", 5873 "1.00 Sierra Leonean leones random", 5874 "1.00 Singapore Dollar random", 5875 "1.00 Singapore dollar random", 5876 "1.00 Singapore dollars random", 5877 "1.00 Slovak Koruna random", 5878 "1.00 Slovak koruna random", 5879 "1.00 Slovak korunas random", 5880 "1.00 Slovenian Tolar random", 5881 "1.00 Slovenian tolar random", 5882 "1.00 Slovenian tolars random", 5883 "1.00 Solomon Islands Dollar random", 5884 "1.00 Solomon Islands dollar random", 5885 "1.00 Solomon Islands dollars random", 5886 "1.00 Somali Shilling random", 5887 "1.00 Somali shilling random", 5888 "1.00 Somali shillings random", 5889 "1.00 South African Rand (financial) random", 5890 "1.00 South African Rand random", 5891 "1.00 South African rand (financial) random", 5892 "1.00 South African rand random", 5893 "1.00 South African rands (financial) random", 5894 "1.00 South African rand random", 5895 "1.00 South Korean Won random", 5896 "1.00 South Korean won random", 5897 "1.00 South Korean won random", 5898 "1.00 Soviet Rouble random", 5899 "1.00 Soviet rouble random", 5900 "1.00 Soviet roubles random", 5901 "1.00 Spanish Peseta (A account) random", 5902 "1.00 Spanish Peseta (convertible account) random", 5903 "1.00 Spanish Peseta random", 5904 "1.00 Spanish peseta (A account) random", 5905 "1.00 Spanish peseta (convertible account) random", 5906 "1.00 Spanish peseta random", 5907 "1.00 Spanish pesetas (A account) random", 5908 "1.00 Spanish pesetas (convertible account) random", 5909 "1.00 Spanish pesetas random", 5910 "1.00 Special Drawing Rights random", 5911 "1.00 Sri Lankan Rupee random", 5912 "1.00 Sri Lankan rupee random", 5913 "1.00 Sri Lankan rupees random", 5914 "1.00 Sudanese Pound random", 5915 "1.00 Sudanese pound random", 5916 "1.00 Sudanese pounds random", 5917 "1.00 Surinamese Dollar random", 5918 "1.00 Surinamese dollar random", 5919 "1.00 Surinamese dollars random", 5920 "1.00 Surinamese Guilder random", 5921 "1.00 Surinamese guilder random", 5922 "1.00 Surinamese guilders random", 5923 "1.00 Swazi Lilangeni random", 5924 "1.00 Swazi lilangeni random", 5925 "1.00 Swazi emalangeni random", 5926 "1.00 Swedish Krona random", 5927 "1.00 Swedish krona random", 5928 "1.00 Swedish kronor random", 5929 "1.00 Swiss Franc random", 5930 "1.00 Swiss franc random", 5931 "1.00 Swiss francs random", 5932 "1.00 Syrian Pound random", 5933 "1.00 Syrian pound random", 5934 "1.00 Syrian pounds random", 5935 "1.00 New Taiwan Dollar random", 5936 "1.00 New Taiwan dollar random", 5937 "1.00 New Taiwan dollars random", 5938 "1.00 Tajikistani Ruble random", 5939 "1.00 Tajikistani Somoni random", 5940 "1.00 Tajikistani ruble random", 5941 "1.00 Tajikistani rubles random", 5942 "1.00 Tajikistani somoni random", 5943 "1.00 Tajikistani somonis random", 5944 "1.00 Tanzanian Shilling random", 5945 "1.00 Tanzanian shilling random", 5946 "1.00 Tanzanian shillings random", 5947 "1.00 Testing Currency Code random", 5948 "1.00 Testing Currency Code random", 5949 "1.00 Thai Baht random", 5950 "1.00 Thai baht random", 5951 "1.00 Thai baht random", 5952 "1.00 Timorese Escudo random", 5953 "1.00 Timorese escudo random", 5954 "1.00 Timorese escudos random", 5955 "1.00 Trinidad & Tobago Dollar random", 5956 "1.00 Trinidad & Tobago dollar random", 5957 "1.00 Trinidad & Tobago dollars random", 5958 "1.00 Tunisian Dinar random", 5959 "1.00 Tunisian dinar random", 5960 "1.00 Tunisian dinars random", 5961 "1.00 Turkish Lira random", 5962 "1.00 Turkish Lira random", 5963 "1.00 Turkish lira random", 5964 "1.00 Turkmenistani Manat random", 5965 "1.00 Turkmenistani manat random", 5966 "1.00 Turkmenistani manat random", 5967 "1.00 US Dollar (Next day) random", 5968 "1.00 US Dollar (Same day) random", 5969 "1.00 US Dollar random", 5970 "1.00 US dollar (next day) random", 5971 "1.00 US dollar (same day) random", 5972 "1.00 US dollar random", 5973 "1.00 US dollars (next day) random", 5974 "1.00 US dollars (same day) random", 5975 "1.00 US dollars random", 5976 "1.00 Ugandan Shilling (1966\\u20131987) random", 5977 "1.00 Ugandan Shilling random", 5978 "1.00 Ugandan shilling (1966\\u20131987) random", 5979 "1.00 Ugandan shilling random", 5980 "1.00 Ugandan shillings (1966\\u20131987) random", 5981 "1.00 Ugandan shillings random", 5982 "1.00 Ukrainian Hryvnia random", 5983 "1.00 Ukrainian Karbovanets random", 5984 "1.00 Ukrainian hryvnia random", 5985 "1.00 Ukrainian hryvnias random", 5986 "1.00 Ukrainian karbovanets random", 5987 "1.00 Ukrainian karbovantsiv random", 5988 "1.00 Colombian Real Value Unit random", 5989 "1.00 United Arab Emirates Dirham random", 5990 "1.00 Unknown Currency random", 5991 "1.00 Uruguayan Peso (1975\\u20131993) random", 5992 "1.00 Uruguayan Peso random", 5993 "1.00 Uruguayan Peso (Indexed Units) random", 5994 "1.00 Uruguayan peso (1975\\u20131993) random", 5995 "1.00 Uruguayan peso (indexed units) random", 5996 "1.00 Uruguayan peso random", 5997 "1.00 Uruguayan pesos (1975\\u20131993) random", 5998 "1.00 Uruguayan pesos (indexed units) random", 5999 "1.00 Uzbekistani Som random", 6000 "1.00 Uzbekistani som random", 6001 "1.00 Uzbekistani som random", 6002 "1.00 Vanuatu Vatu random", 6003 "1.00 Vanuatu vatu random", 6004 "1.00 Vanuatu vatus random", 6005 "1.00 Venezuelan Bol\\u00edvar random", 6006 "1.00 Venezuelan Bol\\u00edvar (1871\\u20132008) random", 6007 "1.00 Venezuelan bol\\u00edvar random", 6008 "1.00 Venezuelan bol\\u00edvars random", 6009 "1.00 Venezuelan bol\\u00edvar (1871\\u20132008) random", 6010 "1.00 Venezuelan bol\\u00edvars (1871\\u20132008) random", 6011 "1.00 Vietnamese Dong random", 6012 "1.00 Vietnamese dong random", 6013 "1.00 Vietnamese dong random", 6014 "1.00 WIR Euro random", 6015 "1.00 WIR Franc random", 6016 "1.00 WIR euro random", 6017 "1.00 WIR euros random", 6018 "1.00 WIR franc random", 6019 "1.00 WIR francs random", 6020 "1.00 Samoan Tala random", 6021 "1.00 Samoan tala random", 6022 "1.00 Samoan tala random", 6023 "1.00 Yemeni Dinar random", 6024 "1.00 Yemeni Rial random", 6025 "1.00 Yemeni dinar random", 6026 "1.00 Yemeni dinars random", 6027 "1.00 Yemeni rial random", 6028 "1.00 Yemeni rials random", 6029 "1.00 Yugoslavian Convertible Dinar (1990\\u20131992) random", 6030 "1.00 Yugoslavian Hard Dinar (1966\\u20131990) random", 6031 "1.00 Yugoslavian New Dinar (1994\\u20132002) random", 6032 "1.00 Yugoslavian convertible dinar (1990\\u20131992) random", 6033 "1.00 Yugoslavian convertible dinars (1990\\u20131992) random", 6034 "1.00 Yugoslavian hard dinar (1966\\u20131990) random", 6035 "1.00 Yugoslavian hard dinars (1966\\u20131990) random", 6036 "1.00 Yugoslavian new dinar (1994\\u20132002) random", 6037 "1.00 Yugoslavian new dinars (1994\\u20132002) random", 6038 "1.00 Zairean New Zaire (1993\\u20131998) random", 6039 "1.00 Zairean Zaire (1971\\u20131993) random", 6040 "1.00 Zairean new zaire (1993\\u20131998) random", 6041 "1.00 Zairean new zaires (1993\\u20131998) random", 6042 "1.00 Zairean zaire (1971\\u20131993) random", 6043 "1.00 Zairean zaires (1971\\u20131993) random", 6044 "1.00 Zambian Kwacha random", 6045 "1.00 Zambian kwacha random", 6046 "1.00 Zambian kwachas random", 6047 "1.00 Zimbabwean Dollar (1980\\u20132008) random", 6048 "1.00 Zimbabwean dollar (1980\\u20132008) random", 6049 "1.00 Zimbabwean dollars (1980\\u20132008) random", 6050 "1.00 euro random", 6051 "1.00 euros random", 6052 "1.00 Turkish lira (1922\\u20132005) random", 6053 "1.00 special drawing rights random", 6054 "1.00 Colombian real value unit random", 6055 "1.00 Colombian real value units random", 6056 "1.00 unknown currency random", 6057 }; 6058 6059 const char* WRONG_DATA[] = { 6060 // Following are missing one last char in the currency name 6061 "usd1.00", // case sensitive 6062 "1.00 Nicaraguan Cordob", 6063 "1.00 Namibian Dolla", 6064 "1.00 Namibian dolla", 6065 "1.00 Nepalese Rupe", 6066 "1.00 Nepalese rupe", 6067 "1.00 Netherlands Antillean Guilde", 6068 "1.00 Netherlands Antillean guilde", 6069 "1.00 Dutch Guilde", 6070 "1.00 Dutch guilde", 6071 "1.00 Israeli New Sheqe", 6072 "1.00 New Zealand Dolla", 6073 "1.00 New Zealand dolla", 6074 "1.00 Nicaraguan cordob", 6075 "1.00 Nigerian Nair", 6076 "1.00 Nigerian nair", 6077 "1.00 North Korean Wo", 6078 "1.00 North Korean wo", 6079 "1.00 Norwegian Kron", 6080 "1.00 Norwegian kron", 6081 "1.00 US dolla", 6082 "1.00", 6083 "A1.00", 6084 "AD1.00", 6085 "AE1.00", 6086 "AF1.00", 6087 "AL1.00", 6088 "AM1.00", 6089 "AN1.00", 6090 "AO1.00", 6091 "AR1.00", 6092 "AT1.00", 6093 "AU1.00", 6094 "AW1.00", 6095 "AZ1.00", 6096 "Afghan Afghan1.00", 6097 "Afghan Afghani (1927\\u201320021.00", 6098 "Afl1.00", 6099 "Albanian Le1.00", 6100 "Algerian Dina1.00", 6101 "Andorran Peset1.00", 6102 "Angolan Kwanz1.00", 6103 "Angolan Kwanza (1977\\u201319901.00", 6104 "Angolan Readjusted Kwanza (1995\\u201319991.00", 6105 "Angolan New Kwanza (1990\\u201320001.00", 6106 "Argentine Austra1.00", 6107 "Argentine Pes1.00", 6108 "Argentine Peso (1983\\u201319851.00", 6109 "Armenian Dra1.00", 6110 "Aruban Flori1.00", 6111 "Australian Dolla1.00", 6112 "Austrian Schillin1.00", 6113 "Azerbaijani Mana1.00", 6114 "Azerbaijani Manat (1993\\u201320061.00", 6115 "B1.00", 6116 "BA1.00", 6117 "BB1.00", 6118 "BE1.00", 6119 "BG1.00", 6120 "BH1.00", 6121 "BI1.00", 6122 "BM1.00", 6123 "BN1.00", 6124 "BO1.00", 6125 "BR1.00", 6126 "BS1.00", 6127 "BT1.00", 6128 "BU1.00", 6129 "BW1.00", 6130 "BY1.00", 6131 "BZ1.00", 6132 "Bahamian Dolla1.00", 6133 "Bahraini Dina1.00", 6134 "Bangladeshi Tak1.00", 6135 "Barbadian Dolla1.00", 6136 "Bds1.00", 6137 "Belarusian New Ruble (1994\\u201319991.00", 6138 "Belarusian Rubl1.00", 6139 "Belgian Fran1.00", 6140 "Belgian Franc (convertible1.00", 6141 "Belgian Franc (financial1.00", 6142 "Belize Dolla1.00", 6143 "Bermudan Dolla1.00", 6144 "Bhutanese Ngultru1.00", 6145 "Bolivian Mvdo1.00", 6146 "Bolivian Pes1.00", 6147 "Bolivian Bolivian1.00", 6148 "Bosnia-Herzegovina Convertible Mar1.00", 6149 "Bosnia-Herzegovina Dina1.00", 6150 "Botswanan Pul1.00", 6151 "Brazilian Cruzad1.00", 6152 "Brazilian Cruzado Nov1.00", 6153 "Brazilian Cruzeir1.00", 6154 "Brazilian Cruzeiro (1990\\u201319931.00", 6155 "Brazilian New Cruzeiro (1967\\u201319861.00", 6156 "Brazilian Rea1.00", 6157 "British Pound Sterlin1.00", 6158 "Brunei Dolla1.00", 6159 "Bulgarian Hard Le1.00", 6160 "Bulgarian Le1.00", 6161 "Burmese Kya1.00", 6162 "Burundian Fran1.00", 6163 "C1.00", 6164 "CA1.00", 6165 "CD1.00", 6166 "CFP Fran1.00", 6167 "CFP1.00", 6168 "CH1.00", 6169 "CL1.00", 6170 "CN1.00", 6171 "CO1.00", 6172 "CS1.00", 6173 "CU1.00", 6174 "CV1.00", 6175 "CY1.00", 6176 "CZ1.00", 6177 "Cambodian Rie1.00", 6178 "Canadian Dolla1.00", 6179 "Cape Verdean Escud1.00", 6180 "Cayman Islands Dolla1.00", 6181 "Chilean Pes1.00", 6182 "Chilean Unit of Accoun1.00", 6183 "Chinese Yua1.00", 6184 "Colombian Pes1.00", 6185 "Comoro Fran1.00", 6186 "Congolese Fran1.00", 6187 "Costa Rican Col\\u00f31.00", 6188 "Croatian Dina1.00", 6189 "Croatian Kun1.00", 6190 "Cuban Pes1.00", 6191 "Cypriot Poun1.00", 6192 "Czech Republic Korun1.00", 6193 "Czechoslovak Hard Korun1.00", 6194 "D1.00", 6195 "DD1.00", 6196 "DE1.00", 6197 "DJ1.00", 6198 "DK1.00", 6199 "DO1.00", 6200 "DZ1.00", 6201 "Danish Kron1.00", 6202 "German Mar1.00", 6203 "Djiboutian Fran1.00", 6204 "Dk1.00", 6205 "Dominican Pes1.00", 6206 "EC1.00", 6207 "EE1.00", 6208 "EG1.00", 6209 "EQ1.00", 6210 "ER1.00", 6211 "ES1.00", 6212 "ET1.00", 6213 "EU1.00", 6214 "East Caribbean Dolla1.00", 6215 "East German Ostmar1.00", 6216 "Ecuadorian Sucr1.00", 6217 "Ecuadorian Unit of Constant Valu1.00", 6218 "Egyptian Poun1.00", 6219 "Ekwel1.00", 6220 "Salvadoran Col\\u00f31.00", 6221 "Equatorial Guinean Ekwel1.00", 6222 "Eritrean Nakf1.00", 6223 "Es1.00", 6224 "Estonian Kroo1.00", 6225 "Ethiopian Bir1.00", 6226 "Eur1.00", 6227 "European Composite Uni1.00", 6228 "European Currency Uni1.00", 6229 "European Monetary Uni1.00", 6230 "European Unit of Account (XBC1.00", 6231 "European Unit of Account (XBD1.00", 6232 "F1.00", 6233 "FB1.00", 6234 "FI1.00", 6235 "FJ1.00", 6236 "FK1.00", 6237 "FR1.00", 6238 "Falkland Islands Poun1.00", 6239 "Fd1.00", 6240 "Fijian Dolla1.00", 6241 "Finnish Markk1.00", 6242 "Fr1.00", 6243 "French Fran1.00", 6244 "French Gold Fran1.00", 6245 "French UIC-Fran1.00", 6246 "G1.00", 6247 "GB1.00", 6248 "GE1.00", 6249 "GH1.00", 6250 "GI1.00", 6251 "GM1.00", 6252 "GN1.00", 6253 "GQ1.00", 6254 "GR1.00", 6255 "GT1.00", 6256 "GW1.00", 6257 "GY1.00", 6258 "Gambian Dalas1.00", 6259 "Georgian Kupon Lari1.00", 6260 "Georgian Lar1.00", 6261 "Ghanaian Ced1.00", 6262 "Ghanaian Cedi (1979\\u201320071.00", 6263 "Gibraltar Poun1.00", 6264 "Gol1.00", 6265 "Greek Drachm1.00", 6266 "Guatemalan Quetza1.00", 6267 "Guinean Fran1.00", 6268 "Guinean Syl1.00", 6269 "Guinea-Bissau Pes1.00", 6270 "Guyanaese Dolla1.00", 6271 "HK1.00", 6272 "HN1.00", 6273 "HR1.00", 6274 "HT1.00", 6275 "HU1.00", 6276 "Haitian Gourd1.00", 6277 "Honduran Lempir1.00", 6278 "Hong Kong Dolla1.00", 6279 "Hungarian Forin1.00", 6280 "I1.00", 6281 "IE1.00", 6282 "IL1.00", 6283 "IN1.00", 6284 "IQ1.00", 6285 "IR1.00", 6286 "IS1.00", 6287 "IT1.00", 6288 "Icelandic Kron1.00", 6289 "Indian Rupe1.00", 6290 "Indonesian Rupia1.00", 6291 "Iranian Ria1.00", 6292 "Iraqi Dina1.00", 6293 "Irish Poun1.00", 6294 "Israeli Poun1.00", 6295 "Italian Lir1.00", 6296 "J1.00", 6297 "JM1.00", 6298 "JO1.00", 6299 "JP1.00", 6300 "Jamaican Dolla1.00", 6301 "Japanese Ye1.00", 6302 "Jordanian Dina1.00", 6303 "K S1.00", 6304 "K1.00", 6305 "KE1.00", 6306 "KG1.00", 6307 "KH1.00", 6308 "KP1.00", 6309 "KR1.00", 6310 "KW1.00", 6311 "KY1.00", 6312 "KZ1.00", 6313 "Kazakhstani Teng1.00", 6314 "Kenyan Shillin1.00", 6315 "Kuwaiti Dina1.00", 6316 "Kyrgystani So1.00", 6317 "LA1.00", 6318 "LB1.00", 6319 "LK1.00", 6320 "LR1.00", 6321 "LT1.00", 6322 "LU1.00", 6323 "LV1.00", 6324 "LY1.00", 6325 "Laotian Ki1.00", 6326 "Latvian Lat1.00", 6327 "Latvian Rubl1.00", 6328 "Lebanese Poun1.00", 6329 "Lesotho Lot1.00", 6330 "Liberian Dolla1.00", 6331 "Libyan Dina1.00", 6332 "Lithuanian Lit1.00", 6333 "Lithuanian Talona1.00", 6334 "Luxembourgian Convertible Fran1.00", 6335 "Luxembourg Financial Fran1.00", 6336 "Luxembourgian Fran1.00", 6337 "MA1.00", 6338 "MD1.00", 6339 "MDe1.00", 6340 "MEX1.00", 6341 "MG1.00", 6342 "ML1.00", 6343 "MM1.00", 6344 "MN1.00", 6345 "MO1.00", 6346 "MR1.00", 6347 "MT1.00", 6348 "MU1.00", 6349 "MV1.00", 6350 "MW1.00", 6351 "MX1.00", 6352 "MY1.00", 6353 "MZ1.00", 6354 "Macanese Patac1.00", 6355 "Macedonian Dena1.00", 6356 "Malagasy Ariar1.00", 6357 "Malagasy Fran1.00", 6358 "Malawian Kwach1.00", 6359 "Malaysian Ringgi1.00", 6360 "Maldivian Rufiya1.00", 6361 "Malian Fran1.00", 6362 "Malot1.00", 6363 "Maltese Lir1.00", 6364 "Maltese Poun1.00", 6365 "Mauritanian Ouguiy1.00", 6366 "Mauritian Rupe1.00", 6367 "Mexican Pes1.00", 6368 "Mexican Silver Peso (1861\\u201319921.00", 6369 "Mexican Investment Uni1.00", 6370 "Moldovan Le1.00", 6371 "Mongolian Tugri1.00", 6372 "Moroccan Dirha1.00", 6373 "Moroccan Fran1.00", 6374 "Mozambican Escud1.00", 6375 "Mozambican Metica1.00", 6376 "Myanmar Kya1.00", 6377 "N1.00", 6378 "NA1.00", 6379 "NAf1.00", 6380 "NG1.00", 6381 "NI1.00", 6382 "NK1.00", 6383 "NL1.00", 6384 "NO1.00", 6385 "NP1.00", 6386 "NT1.00", 6387 "Namibian Dolla1.00", 6388 "Nepalese Rupe1.00", 6389 "Netherlands Antillean Guilde1.00", 6390 "Dutch Guilde1.00", 6391 "Israeli New Sheqe1.00", 6392 "New Zealand Dolla1.00", 6393 "Nicaraguan C\\u00f3rdoba (1988\\u201319911.00", 6394 "Nicaraguan C\\u00f3rdob1.00", 6395 "Nigerian Nair1.00", 6396 "North Korean Wo1.00", 6397 "Norwegian Kron1.00", 6398 "Nr1.00", 6399 "OM1.00", 6400 "Old Mozambican Metica1.00", 6401 "Romanian Leu (1952\\u201320061.00", 6402 "Serbian Dinar (2002\\u201320061.00", 6403 "Sudanese Dinar (1992\\u201320071.00", 6404 "Sudanese Pound (1957\\u201319981.00", 6405 "Turkish Lira (1922\\u201320051.00", 6406 "Omani Ria1.00", 6407 "PA1.00", 6408 "PE1.00", 6409 "PG1.00", 6410 "PH1.00", 6411 "PK1.00", 6412 "PL1.00", 6413 "PT1.00", 6414 "PY1.00", 6415 "Pakistani Rupe1.00", 6416 "Palladiu1.00", 6417 "Panamanian Balbo1.00", 6418 "Papua New Guinean Kin1.00", 6419 "Paraguayan Guaran1.00", 6420 "Peruvian Int1.00", 6421 "Peruvian Sol (1863\\u201319651.00", 6422 "Peruvian Sol Nuev1.00", 6423 "Philippine Pes1.00", 6424 "Platinu1.00", 6425 "Polish Zlot1.00", 6426 "Polish Zloty (1950\\u201319951.00", 6427 "Portuguese Escud1.00", 6428 "Portuguese Guinea Escud1.00", 6429 "Pr1.00", 6430 "QA1.00", 6431 "Qatari Ria1.00", 6432 "RD1.00", 6433 "RH1.00", 6434 "RINET Fund1.00", 6435 "RS1.00", 6436 "RU1.00", 6437 "RW1.00", 6438 "Rb1.00", 6439 "Rhodesian Dolla1.00", 6440 "Romanian Le1.00", 6441 "Russian Rubl1.00", 6442 "Russian Ruble (1991\\u201319981.00", 6443 "Rwandan Fran1.00", 6444 "S1.00", 6445 "SA1.00", 6446 "SB1.00", 6447 "SC1.00", 6448 "SD1.00", 6449 "SE1.00", 6450 "SG1.00", 6451 "SH1.00", 6452 "SI1.00", 6453 "SK1.00", 6454 "SL R1.00", 6455 "SL1.00", 6456 "SO1.00", 6457 "ST1.00", 6458 "SU1.00", 6459 "SV1.00", 6460 "SY1.00", 6461 "SZ1.00", 6462 "St. Helena Poun1.00", 6463 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobr1.00", 6464 "Saudi Riya1.00", 6465 "Serbian Dina1.00", 6466 "Seychellois Rupe1.00", 6467 "Sh1.00", 6468 "Sierra Leonean Leon1.00", 6469 "Silve1.00", 6470 "Singapore Dolla1.00", 6471 "Slovak Korun1.00", 6472 "Slovenian Tola1.00", 6473 "Solomon Islands Dolla1.00", 6474 "Somali Shillin1.00", 6475 "South African Ran1.00", 6476 "South African Rand (financial1.00", 6477 "South Korean Wo1.00", 6478 "Soviet Roubl1.00", 6479 "Spanish Peset1.00", 6480 "Spanish Peseta (A account1.00", 6481 "Spanish Peseta (convertible account1.00", 6482 "Special Drawing Right1.00", 6483 "Sri Lankan Rupe1.00", 6484 "Sudanese Poun1.00", 6485 "Surinamese Dolla1.00", 6486 "Surinamese Guilde1.00", 6487 "Swazi Lilangen1.00", 6488 "Swedish Kron1.00", 6489 "Swiss Fran1.00", 6490 "Syrian Poun1.00", 6491 "T S1.00", 6492 "TH1.00", 6493 "TJ1.00", 6494 "TM1.00", 6495 "TN1.00", 6496 "TO1.00", 6497 "TP1.00", 6498 "TR1.00", 6499 "TT1.00", 6500 "TW1.00", 6501 "TZ1.00", 6502 "New Taiwan Dolla1.00", 6503 "Tajikistani Rubl1.00", 6504 "Tajikistani Somon1.00", 6505 "Tanzanian Shillin1.00", 6506 "Testing Currency Cod1.00", 6507 "Thai Bah1.00", 6508 "Timorese Escud1.00", 6509 "Tongan Pa\\u20bbang1.00", 6510 "Trinidad & Tobago Dolla1.00", 6511 "Tunisian Dina1.00", 6512 "Turkish Lir1.00", 6513 "Turkmenistani Mana1.00", 6514 "U S1.00", 6515 "U1.00", 6516 "UA1.00", 6517 "UG1.00", 6518 "US Dolla1.00", 6519 "US Dollar (Next day1.00", 6520 "US Dollar (Same day1.00", 6521 "US1.00", 6522 "UY1.00", 6523 "UZ1.00", 6524 "Ugandan Shillin1.00", 6525 "Ugandan Shilling (1966\\u201319871.00", 6526 "Ukrainian Hryvni1.00", 6527 "Ukrainian Karbovanet1.00", 6528 "Colombian Real Value Uni1.00", 6529 "United Arab Emirates Dirha1.00", 6530 "Unknown Currenc1.00", 6531 "Ur1.00", 6532 "Uruguay Peso (1975\\u201319931.00", 6533 "Uruguay Peso Uruguay1.00", 6534 "Uruguay Peso (Indexed Units1.00", 6535 "Uzbekistani So1.00", 6536 "V1.00", 6537 "VE1.00", 6538 "VN1.00", 6539 "VU1.00", 6540 "Vanuatu Vat1.00", 6541 "Venezuelan Bol\\u00edva1.00", 6542 "Venezuelan Bol\\u00edvar Fuert1.00", 6543 "Vietnamese Don1.00", 6544 "West African CFA Fran1.00", 6545 "Central African CFA Fran1.00", 6546 "WIR Eur1.00", 6547 "WIR Fran1.00", 6548 "WS1.00", 6549 "Samoa Tal1.00", 6550 "XA1.00", 6551 "XB1.00", 6552 "XC1.00", 6553 "XD1.00", 6554 "XE1.00", 6555 "XF1.00", 6556 "XO1.00", 6557 "XP1.00", 6558 "XR1.00", 6559 "XT1.00", 6560 "XX1.00", 6561 "YD1.00", 6562 "YE1.00", 6563 "YU1.00", 6564 "Yemeni Dina1.00", 6565 "Yemeni Ria1.00", 6566 "Yugoslavian Convertible Dina1.00", 6567 "Yugoslavian Hard Dinar (1966\\u201319901.00", 6568 "Yugoslavian New Dina1.00", 6569 "Z1.00", 6570 "ZA1.00", 6571 "ZM1.00", 6572 "ZR1.00", 6573 "ZW1.00", 6574 "Zairean New Zaire (1993\\u201319981.00", 6575 "Zairean Zair1.00", 6576 "Zambian Kwach1.00", 6577 "Zimbabwean Dollar (1980\\u201320081.00", 6578 "dra1.00", 6579 "lar1.00", 6580 "le1.00", 6581 "man1.00", 6582 "so1.00", 6583 }; 6584 6585 Locale locale("en_US"); 6586 for (uint32_t i=0; i<sizeof(DATA)/sizeof(DATA[0]); ++i) { 6587 UnicodeString formatted = ctou(DATA[i]); 6588 UErrorCode status = U_ZERO_ERROR; 6589 NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status); 6590 if (numFmt != NULL && U_SUCCESS(status)) { 6591 ParsePosition parsePos; 6592 LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos)); 6593 if (parsePos.getIndex() > 0) { 6594 double doubleVal = currAmt->getNumber().getDouble(status); 6595 if ( doubleVal != 1.0 ) { 6596 errln("Parsed as currency value other than 1.0: " + formatted + " -> " + doubleVal); 6597 } 6598 } else { 6599 errln("Failed to parse as currency: " + formatted); 6600 } 6601 } else { 6602 dataerrln("Unable to create NumberFormat. - %s", u_errorName(status)); 6603 delete numFmt; 6604 break; 6605 } 6606 delete numFmt; 6607 } 6608 6609 for (uint32_t i=0; i<sizeof(WRONG_DATA)/sizeof(WRONG_DATA[0]); ++i) { 6610 UnicodeString formatted = ctou(WRONG_DATA[i]); 6611 UErrorCode status = U_ZERO_ERROR; 6612 NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status); 6613 if (numFmt != NULL && U_SUCCESS(status)) { 6614 ParsePosition parsePos; 6615 LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos)); 6616 if (parsePos.getIndex() > 0) { 6617 double doubleVal = currAmt->getNumber().getDouble(status); 6618 errln("Parsed as currency, should not have: " + formatted + " -> " + doubleVal); 6619 } 6620 } else { 6621 dataerrln("Unable to create NumberFormat. - %s", u_errorName(status)); 6622 delete numFmt; 6623 break; 6624 } 6625 delete numFmt; 6626 } 6627 } 6628 6629 const char* attrString(int32_t); 6630 6631 // UnicodeString s; 6632 // std::string ss; 6633 // std::cout << s.toUTF8String(ss) 6634 void NumberFormatTest::expectPositions(FieldPositionIterator& iter, int32_t *values, int32_t tupleCount, 6635 const UnicodeString& str) { 6636 UBool found[10]; 6637 FieldPosition fp; 6638 6639 if (tupleCount > 10) { 6640 assertTrue("internal error, tupleCount too large", FALSE); 6641 } else { 6642 for (int i = 0; i < tupleCount; ++i) { 6643 found[i] = FALSE; 6644 } 6645 } 6646 6647 logln(str); 6648 while (iter.next(fp)) { 6649 UBool ok = FALSE; 6650 int32_t id = fp.getField(); 6651 int32_t start = fp.getBeginIndex(); 6652 int32_t limit = fp.getEndIndex(); 6653 6654 // is there a logln using printf? 6655 char buf[128]; 6656 sprintf(buf, "%24s %3d %3d %3d", attrString(id), id, start, limit); 6657 logln(buf); 6658 6659 for (int i = 0; i < tupleCount; ++i) { 6660 if (found[i]) { 6661 continue; 6662 } 6663 if (values[i*3] == id && 6664 values[i*3+1] == start && 6665 values[i*3+2] == limit) { 6666 found[i] = ok = TRUE; 6667 break; 6668 } 6669 } 6670 6671 assertTrue((UnicodeString)"found [" + id + "," + start + "," + limit + "]", ok); 6672 } 6673 6674 // check that all were found 6675 UBool ok = TRUE; 6676 for (int i = 0; i < tupleCount; ++i) { 6677 if (!found[i]) { 6678 ok = FALSE; 6679 assertTrue((UnicodeString) "missing [" + values[i*3] + "," + values[i*3+1] + "," + values[i*3+2] + "]", found[i]); 6680 } 6681 } 6682 assertTrue("no expected values were missing", ok); 6683 } 6684 6685 void NumberFormatTest::expectPosition(FieldPosition& pos, int32_t id, int32_t start, int32_t limit, 6686 const UnicodeString& str) { 6687 logln(str); 6688 assertTrue((UnicodeString)"id " + id + " == " + pos.getField(), id == pos.getField()); 6689 assertTrue((UnicodeString)"begin " + start + " == " + pos.getBeginIndex(), start == pos.getBeginIndex()); 6690 assertTrue((UnicodeString)"end " + limit + " == " + pos.getEndIndex(), limit == pos.getEndIndex()); 6691 } 6692 6693 void NumberFormatTest::TestFieldPositionIterator() { 6694 // bug 7372 6695 UErrorCode status = U_ZERO_ERROR; 6696 FieldPositionIterator iter1; 6697 FieldPositionIterator iter2; 6698 FieldPosition pos; 6699 6700 DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(status); 6701 if (failure(status, "NumberFormat::createInstance", TRUE)) return; 6702 6703 double num = 1234.56; 6704 UnicodeString str1; 6705 UnicodeString str2; 6706 6707 assertTrue((UnicodeString)"self==", iter1 == iter1); 6708 assertTrue((UnicodeString)"iter1==iter2", iter1 == iter2); 6709 6710 decFmt->format(num, str1, &iter1, status); 6711 assertTrue((UnicodeString)"iter1 != iter2", iter1 != iter2); 6712 decFmt->format(num, str2, &iter2, status); 6713 assertTrue((UnicodeString)"iter1 == iter2 (2)", iter1 == iter2); 6714 iter1.next(pos); 6715 assertTrue((UnicodeString)"iter1 != iter2 (2)", iter1 != iter2); 6716 iter2.next(pos); 6717 assertTrue((UnicodeString)"iter1 == iter2 (3)", iter1 == iter2); 6718 6719 // should format ok with no iterator 6720 str2.remove(); 6721 decFmt->format(num, str2, NULL, status); 6722 assertEquals("null fpiter", str1, str2); 6723 6724 delete decFmt; 6725 } 6726 6727 void NumberFormatTest::TestFormatAttributes() { 6728 Locale locale("en_US"); 6729 UErrorCode status = U_ZERO_ERROR; 6730 DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_CURRENCY, status); 6731 if (failure(status, "NumberFormat::createInstance", TRUE)) return; 6732 double val = 12345.67; 6733 6734 { 6735 int32_t expected[] = { 6736 UNUM_CURRENCY_FIELD, 0, 1, 6737 UNUM_GROUPING_SEPARATOR_FIELD, 3, 4, 6738 UNUM_INTEGER_FIELD, 1, 7, 6739 UNUM_DECIMAL_SEPARATOR_FIELD, 7, 8, 6740 UNUM_FRACTION_FIELD, 8, 10, 6741 }; 6742 int32_t tupleCount = sizeof(expected)/(3 * sizeof(*expected)); 6743 6744 FieldPositionIterator posIter; 6745 UnicodeString result; 6746 decFmt->format(val, result, &posIter, status); 6747 expectPositions(posIter, expected, tupleCount, result); 6748 } 6749 { 6750 FieldPosition fp(UNUM_INTEGER_FIELD); 6751 UnicodeString result; 6752 decFmt->format(val, result, fp); 6753 expectPosition(fp, UNUM_INTEGER_FIELD, 1, 7, result); 6754 } 6755 { 6756 FieldPosition fp(UNUM_FRACTION_FIELD); 6757 UnicodeString result; 6758 decFmt->format(val, result, fp); 6759 expectPosition(fp, UNUM_FRACTION_FIELD, 8, 10, result); 6760 } 6761 delete decFmt; 6762 6763 decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_SCIENTIFIC, status); 6764 val = -0.0000123; 6765 { 6766 int32_t expected[] = { 6767 UNUM_SIGN_FIELD, 0, 1, 6768 UNUM_INTEGER_FIELD, 1, 2, 6769 UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3, 6770 UNUM_FRACTION_FIELD, 3, 5, 6771 UNUM_EXPONENT_SYMBOL_FIELD, 5, 6, 6772 UNUM_EXPONENT_SIGN_FIELD, 6, 7, 6773 UNUM_EXPONENT_FIELD, 7, 8 6774 }; 6775 int32_t tupleCount = sizeof(expected)/(3 * sizeof(*expected)); 6776 6777 FieldPositionIterator posIter; 6778 UnicodeString result; 6779 decFmt->format(val, result, &posIter, status); 6780 expectPositions(posIter, expected, tupleCount, result); 6781 } 6782 { 6783 FieldPosition fp(UNUM_INTEGER_FIELD); 6784 UnicodeString result; 6785 decFmt->format(val, result, fp); 6786 expectPosition(fp, UNUM_INTEGER_FIELD, 1, 2, result); 6787 } 6788 { 6789 FieldPosition fp(UNUM_FRACTION_FIELD); 6790 UnicodeString result; 6791 decFmt->format(val, result, fp); 6792 expectPosition(fp, UNUM_FRACTION_FIELD, 3, 5, result); 6793 } 6794 delete decFmt; 6795 6796 fflush(stderr); 6797 } 6798 6799 const char* attrString(int32_t attrId) { 6800 switch (attrId) { 6801 case UNUM_INTEGER_FIELD: return "integer"; 6802 case UNUM_FRACTION_FIELD: return "fraction"; 6803 case UNUM_DECIMAL_SEPARATOR_FIELD: return "decimal separator"; 6804 case UNUM_EXPONENT_SYMBOL_FIELD: return "exponent symbol"; 6805 case UNUM_EXPONENT_SIGN_FIELD: return "exponent sign"; 6806 case UNUM_EXPONENT_FIELD: return "exponent"; 6807 case UNUM_GROUPING_SEPARATOR_FIELD: return "grouping separator"; 6808 case UNUM_CURRENCY_FIELD: return "currency"; 6809 case UNUM_PERCENT_FIELD: return "percent"; 6810 case UNUM_PERMILL_FIELD: return "permille"; 6811 case UNUM_SIGN_FIELD: return "sign"; 6812 default: return ""; 6813 } 6814 } 6815 6816 // 6817 // Test formatting & parsing of big decimals. 6818 // API test, not a comprehensive test. 6819 // See DecimalFormatTest/DataDrivenTests 6820 // 6821 #define ASSERT_SUCCESS(status) {if (U_FAILURE(status)) errln("file %s, line %d: status: %s", \ 6822 __FILE__, __LINE__, u_errorName(status));} 6823 #define ASSERT_EQUALS(expected, actual) {if ((expected) != (actual)) \ 6824 errln("file %s, line %d: %s != %s", __FILE__, __LINE__, #expected, #actual);} 6825 6826 static UBool operator != (const char *s1, UnicodeString &s2) { 6827 // This function lets ASSERT_EQUALS("literal", UnicodeString) work. 6828 UnicodeString us1(s1); 6829 return us1 != s2; 6830 } 6831 6832 void NumberFormatTest::TestDecimal() { 6833 { 6834 UErrorCode status = U_ZERO_ERROR; 6835 Formattable f("12.345678999987654321E666", status); 6836 ASSERT_SUCCESS(status); 6837 StringPiece s = f.getDecimalNumber(status); 6838 ASSERT_SUCCESS(status); 6839 ASSERT_EQUALS("1.2345678999987654321E+667", s); 6840 //printf("%s\n", s.data()); 6841 } 6842 6843 { 6844 UErrorCode status = U_ZERO_ERROR; 6845 Formattable f1("this is not a number", status); 6846 ASSERT_EQUALS(U_DECIMAL_NUMBER_SYNTAX_ERROR, status); 6847 } 6848 6849 { 6850 UErrorCode status = U_ZERO_ERROR; 6851 Formattable f; 6852 f.setDecimalNumber("123.45", status); 6853 ASSERT_SUCCESS(status); 6854 ASSERT_EQUALS( Formattable::kDouble, f.getType()); 6855 ASSERT_EQUALS(123.45, f.getDouble()); 6856 ASSERT_EQUALS(123.45, f.getDouble(status)); 6857 ASSERT_SUCCESS(status); 6858 ASSERT_EQUALS("123.45", f.getDecimalNumber(status)); 6859 ASSERT_SUCCESS(status); 6860 6861 f.setDecimalNumber("4.5678E7", status); 6862 int32_t n; 6863 n = f.getLong(); 6864 ASSERT_EQUALS(45678000, n); 6865 6866 status = U_ZERO_ERROR; 6867 f.setDecimalNumber("-123", status); 6868 ASSERT_SUCCESS(status); 6869 ASSERT_EQUALS( Formattable::kLong, f.getType()); 6870 ASSERT_EQUALS(-123, f.getLong()); 6871 ASSERT_EQUALS(-123, f.getLong(status)); 6872 ASSERT_SUCCESS(status); 6873 ASSERT_EQUALS("-123", f.getDecimalNumber(status)); 6874 ASSERT_SUCCESS(status); 6875 6876 status = U_ZERO_ERROR; 6877 f.setDecimalNumber("1234567890123", status); // Number too big for 32 bits 6878 ASSERT_SUCCESS(status); 6879 ASSERT_EQUALS( Formattable::kInt64, f.getType()); 6880 ASSERT_EQUALS(1234567890123LL, f.getInt64()); 6881 ASSERT_EQUALS(1234567890123LL, f.getInt64(status)); 6882 ASSERT_SUCCESS(status); 6883 ASSERT_EQUALS("1234567890123", f.getDecimalNumber(status)); 6884 ASSERT_SUCCESS(status); 6885 } 6886 6887 { 6888 UErrorCode status = U_ZERO_ERROR; 6889 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status); 6890 if (U_FAILURE(status) || fmtr == NULL) { 6891 dataerrln("Unable to create NumberFormat"); 6892 } else { 6893 UnicodeString formattedResult; 6894 StringPiece num("244444444444444444444444444444444444446.4"); 6895 fmtr->format(num, formattedResult, NULL, status); 6896 ASSERT_SUCCESS(status); 6897 ASSERT_EQUALS("244,444,444,444,444,444,444,444,444,444,444,444,446.4", formattedResult); 6898 //std::string ss; std::cout << formattedResult.toUTF8String(ss); 6899 delete fmtr; 6900 } 6901 } 6902 6903 { 6904 // Check formatting a DigitList. DigitList is internal, but this is 6905 // a critical interface that must work. 6906 UErrorCode status = U_ZERO_ERROR; 6907 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status); 6908 if (U_FAILURE(status) || fmtr == NULL) { 6909 dataerrln("Unable to create NumberFormat"); 6910 } else { 6911 UnicodeString formattedResult; 6912 DigitList dl; 6913 StringPiece num("123.4566666666666666666666666666666666621E+40"); 6914 dl.set(num, status); 6915 ASSERT_SUCCESS(status); 6916 fmtr->format(dl, formattedResult, NULL, status); 6917 ASSERT_SUCCESS(status); 6918 ASSERT_EQUALS("1,234,566,666,666,666,666,666,666,666,666,666,666,621,000", formattedResult); 6919 6920 status = U_ZERO_ERROR; 6921 num.set("666.666"); 6922 dl.set(num, status); 6923 FieldPosition pos(NumberFormat::FRACTION_FIELD); 6924 ASSERT_SUCCESS(status); 6925 formattedResult.remove(); 6926 fmtr->format(dl, formattedResult, pos, status); 6927 ASSERT_SUCCESS(status); 6928 ASSERT_EQUALS("666.666", formattedResult); 6929 ASSERT_EQUALS(4, pos.getBeginIndex()); 6930 ASSERT_EQUALS(7, pos.getEndIndex()); 6931 delete fmtr; 6932 } 6933 } 6934 6935 { 6936 // Check a parse with a formatter with a multiplier. 6937 UErrorCode status = U_ZERO_ERROR; 6938 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_PERCENT, status); 6939 if (U_FAILURE(status) || fmtr == NULL) { 6940 dataerrln("Unable to create NumberFormat"); 6941 } else { 6942 UnicodeString input = "1.84%"; 6943 Formattable result; 6944 fmtr->parse(input, result, status); 6945 ASSERT_SUCCESS(status); 6946 ASSERT_EQUALS(0, strcmp("0.0184", result.getDecimalNumber(status).data())); 6947 //std::cout << result.getDecimalNumber(status).data(); 6948 delete fmtr; 6949 } 6950 } 6951 6952 #if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC) 6953 /* 6954 * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod(). 6955 * See #9463 6956 */ 6957 { 6958 // Check that a parse returns a decimal number with full accuracy 6959 UErrorCode status = U_ZERO_ERROR; 6960 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status); 6961 if (U_FAILURE(status) || fmtr == NULL) { 6962 dataerrln("Unable to create NumberFormat"); 6963 } else { 6964 UnicodeString input = "1.002200044400088880000070000"; 6965 Formattable result; 6966 fmtr->parse(input, result, status); 6967 ASSERT_SUCCESS(status); 6968 ASSERT_EQUALS(0, strcmp("1.00220004440008888000007", result.getDecimalNumber(status).data())); 6969 ASSERT_EQUALS(1.00220004440008888, result.getDouble()); 6970 //std::cout << result.getDecimalNumber(status).data(); 6971 delete fmtr; 6972 } 6973 } 6974 #endif 6975 6976 } 6977 6978 void NumberFormatTest::TestCurrencyFractionDigits() { 6979 UErrorCode status = U_ZERO_ERROR; 6980 UnicodeString text1, text2; 6981 double value = 99.12345; 6982 6983 // Create currenct instance 6984 NumberFormat* fmt = NumberFormat::createCurrencyInstance("ja_JP", status); 6985 if (U_FAILURE(status) || fmt == NULL) { 6986 dataerrln("Unable to create NumberFormat"); 6987 } else { 6988 fmt->format(value, text1); 6989 6990 // Reset the same currency and format the test value again 6991 fmt->setCurrency(fmt->getCurrency(), status); 6992 ASSERT_SUCCESS(status); 6993 fmt->format(value, text2); 6994 6995 if (text1 != text2) { 6996 errln((UnicodeString)"NumberFormat::format() should return the same result - text1=" 6997 + text1 + " text2=" + text2); 6998 } 6999 delete fmt; 7000 } 7001 } 7002 7003 void NumberFormatTest::TestExponentParse() { 7004 7005 UErrorCode status = U_ZERO_ERROR; 7006 Formattable result; 7007 ParsePosition parsePos(0); 7008 7009 // set the exponent symbol 7010 status = U_ZERO_ERROR; 7011 DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getDefault(), status); 7012 if(U_FAILURE(status)) { 7013 dataerrln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)"); 7014 return; 7015 } 7016 7017 // create format instance 7018 status = U_ZERO_ERROR; 7019 DecimalFormat fmt("#####", symbols, status); 7020 if(U_FAILURE(status)) { 7021 errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)"); 7022 } 7023 7024 // parse the text 7025 fmt.parse("5.06e-27", result, parsePos); 7026 if(result.getType() != Formattable::kDouble && 7027 result.getDouble() != 5.06E-27 && 7028 parsePos.getIndex() != 8 7029 ) 7030 { 7031 errln("ERROR: parse failed - expected 5.06E-27, 8 - returned %d, %i", 7032 result.getDouble(), parsePos.getIndex()); 7033 } 7034 } 7035 7036 void NumberFormatTest::TestExplicitParents() { 7037 7038 /* Test that number formats are properly inherited from es_419 */ 7039 /* These could be subject to change if the CLDR data changes */ 7040 static const char* parentLocaleTests[][2]= { 7041 /* locale ID */ /* expected */ 7042 {"es_CO", "1.250,75" }, 7043 {"es_ES", "1.250,75" }, 7044 {"es_GQ", "1.250,75" }, 7045 {"es_MX", "1,250.75" }, 7046 {"es_US", "1,250.75" }, 7047 {"es_VE", "1.250,75" }, 7048 }; 7049 7050 UnicodeString s; 7051 7052 for(int i=0; i < (int)(sizeof(parentLocaleTests)/sizeof(parentLocaleTests[i])); i++){ 7053 UErrorCode status = U_ZERO_ERROR; 7054 const char *localeID = parentLocaleTests[i][0]; 7055 UnicodeString expected(parentLocaleTests[i][1], -1, US_INV); 7056 expected = expected.unescape(); 7057 char loc[256]={0}; 7058 uloc_canonicalize(localeID, loc, 256, &status); 7059 NumberFormat *fmt= NumberFormat::createInstance(Locale(loc), status); 7060 if(U_FAILURE(status)){ 7061 dataerrln("Could not create number formatter for locale %s - %s",localeID, u_errorName(status)); 7062 continue; 7063 } 7064 s.remove(); 7065 fmt->format(1250.75, s); 7066 if(s!=expected){ 7067 errln(UnicodeString("FAIL: Expected: ")+expected 7068 + UnicodeString(" Got: ") + s 7069 + UnicodeString( " for locale: ")+ UnicodeString(localeID) ); 7070 } 7071 if (U_FAILURE(status)){ 7072 errln((UnicodeString)"FAIL: Status " + (int32_t)status); 7073 } 7074 delete fmt; 7075 } 7076 7077 } 7078 7079 /** 7080 * Test available numbering systems API. 7081 */ 7082 void NumberFormatTest::TestAvailableNumberingSystems() { 7083 UErrorCode status = U_ZERO_ERROR; 7084 StringEnumeration *availableNumberingSystems = NumberingSystem::getAvailableNames(status); 7085 CHECK_DATA(status, "NumberingSystem::getAvailableNames()") 7086 7087 int32_t nsCount = availableNumberingSystems->count(status); 7088 if ( nsCount < 74 ) { 7089 errln("FAIL: Didn't get as many numbering systems as we had hoped for. Need at least 74, got %d",nsCount); 7090 } 7091 7092 /* A relatively simple test of the API. We call getAvailableNames() and cycle through */ 7093 /* each name returned, attempting to create a numbering system based on that name and */ 7094 /* verifying that the name returned from the resulting numbering system is the same */ 7095 /* one that we initially thought. */ 7096 7097 int32_t len; 7098 for ( int32_t i = 0 ; i < nsCount ; i++ ) { 7099 const char *nsname = availableNumberingSystems->next(&len,status); 7100 NumberingSystem* ns = NumberingSystem::createInstanceByName(nsname,status); 7101 logln("OK for ns = %s",nsname); 7102 if ( uprv_strcmp(nsname,ns->getName()) ) { 7103 errln("FAIL: Numbering system name didn't match for name = %s\n",nsname); 7104 } 7105 7106 delete ns; 7107 } 7108 7109 delete availableNumberingSystems; 7110 } 7111 7112 void 7113 NumberFormatTest::Test9087(void) 7114 { 7115 U_STRING_DECL(pattern,"#",1); 7116 U_STRING_INIT(pattern,"#",1); 7117 7118 U_STRING_DECL(infstr,"INF",3); 7119 U_STRING_INIT(infstr,"INF",3); 7120 7121 U_STRING_DECL(nanstr,"NAN",3); 7122 U_STRING_INIT(nanstr,"NAN",3); 7123 7124 UChar outputbuf[50] = {0}; 7125 UErrorCode status = U_ZERO_ERROR; 7126 UNumberFormat* fmt = unum_open(UNUM_PATTERN_DECIMAL,pattern,1,NULL,NULL,&status); 7127 if ( U_FAILURE(status) ) { 7128 dataerrln("FAIL: error in unum_open() - %s", u_errorName(status)); 7129 return; 7130 } 7131 7132 unum_setSymbol(fmt,UNUM_INFINITY_SYMBOL,infstr,3,&status); 7133 unum_setSymbol(fmt,UNUM_NAN_SYMBOL,nanstr,3,&status); 7134 if ( U_FAILURE(status) ) { 7135 errln("FAIL: error setting symbols"); 7136 } 7137 7138 double inf = uprv_getInfinity(); 7139 7140 unum_setAttribute(fmt,UNUM_ROUNDING_MODE,UNUM_ROUND_HALFEVEN); 7141 unum_setDoubleAttribute(fmt,UNUM_ROUNDING_INCREMENT,0); 7142 7143 UFieldPosition position = { 0, 0, 0}; 7144 unum_formatDouble(fmt,inf,outputbuf,50,&position,&status); 7145 7146 if ( u_strcmp(infstr, outputbuf)) { 7147 errln((UnicodeString)"FAIL: unexpected result for infinity - expected " + infstr + " got " + outputbuf); 7148 } 7149 7150 unum_close(fmt); 7151 } 7152 7153 #include "dcfmtimp.h" 7154 7155 void NumberFormatTest::TestFormatFastpaths() { 7156 #if UCONFIG_FORMAT_FASTPATHS_49 7157 logln("Sizeof DecimalFormat = %d, Sizeof DecimalFormatInternal=%d, UNUM_DECIMALFORMAT_INTERNAL_SIZE=%d\n", 7158 sizeof(DecimalFormat), sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE); 7159 if(UNUM_DECIMALFORMAT_INTERNAL_SIZE < sizeof(DecimalFormatInternal)) { 7160 errln("Error: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is only %d. Increase the #define?\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE); 7161 } else if(UNUM_DECIMALFORMAT_INTERNAL_SIZE > (sizeof(DecimalFormatInternal)+16)) { 7162 infoln("Note: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is %d. Decrease the #define? sizeof(DecimalFormat)=%d\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE, sizeof(DecimalFormat)); 7163 } 7164 #else 7165 infoln("NOTE: UCONFIG_FORMAT_FASTPATHS not set, test skipped."); 7166 #endif 7167 7168 // get some additional case 7169 { 7170 UErrorCode status=U_ZERO_ERROR; 7171 DecimalFormat df(UnicodeString("0000",""),status); 7172 if (U_FAILURE(status)) { 7173 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 7174 } else { 7175 int64_t long_number = 1; 7176 UnicodeString expect = "0001"; 7177 UnicodeString result; 7178 FieldPosition pos; 7179 df.format(long_number, result, pos); 7180 if(U_FAILURE(status)||expect!=result) { 7181 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")); 7182 } else { 7183 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")); 7184 } 7185 } 7186 } 7187 { 7188 UErrorCode status=U_ZERO_ERROR; 7189 DecimalFormat df(UnicodeString("0000000000000000000",""),status); 7190 if (U_FAILURE(status)) { 7191 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 7192 } else { 7193 int64_t long_number = U_INT64_MIN; // -9223372036854775808L; 7194 // uint8_t bits[8]; 7195 // memcpy(bits,&long_number,8); 7196 // for(int i=0;i<8;i++) { 7197 // logln("bits: %02X", (unsigned int)bits[i]); 7198 // } 7199 UnicodeString expect = "-9223372036854775808"; 7200 UnicodeString result; 7201 FieldPosition pos; 7202 df.format(long_number, result, pos); 7203 if(U_FAILURE(status)||expect!=result) { 7204 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808"); 7205 } else { 7206 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808"); 7207 } 7208 } 7209 } 7210 { 7211 UErrorCode status=U_ZERO_ERROR; 7212 DecimalFormat df(UnicodeString("0000000000000000000",""),status); 7213 if (U_FAILURE(status)) { 7214 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 7215 } else { 7216 int64_t long_number = U_INT64_MAX; // -9223372036854775808L; 7217 // uint8_t bits[8]; 7218 // memcpy(bits,&long_number,8); 7219 // for(int i=0;i<8;i++) { 7220 // logln("bits: %02X", (unsigned int)bits[i]); 7221 // } 7222 UnicodeString expect = "9223372036854775807"; 7223 UnicodeString result; 7224 FieldPosition pos; 7225 df.format(long_number, result, pos); 7226 if(U_FAILURE(status)||expect!=result) { 7227 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX"); 7228 } else { 7229 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX"); 7230 } 7231 } 7232 } 7233 { 7234 UErrorCode status=U_ZERO_ERROR; 7235 DecimalFormat df(UnicodeString("0000000000000000000",""),status); 7236 if (U_FAILURE(status)) { 7237 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 7238 } else { 7239 int64_t long_number = 0; 7240 // uint8_t bits[8]; 7241 // memcpy(bits,&long_number,8); 7242 // for(int i=0;i<8;i++) { 7243 // logln("bits: %02X", (unsigned int)bits[i]); 7244 // } 7245 UnicodeString expect = "0000000000000000000"; 7246 UnicodeString result; 7247 FieldPosition pos; 7248 df.format(long_number, result, pos); 7249 if(U_FAILURE(status)||expect!=result) { 7250 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0"); 7251 } else { 7252 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0"); 7253 } 7254 } 7255 } 7256 { 7257 UErrorCode status=U_ZERO_ERROR; 7258 DecimalFormat df(UnicodeString("0000000000000000000",""),status); 7259 if (U_FAILURE(status)) { 7260 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 7261 } else { 7262 int64_t long_number = U_INT64_MIN + 1; 7263 UnicodeString expect = "-9223372036854775807"; 7264 UnicodeString result; 7265 FieldPosition pos; 7266 df.format(long_number, result, pos); 7267 if(U_FAILURE(status)||expect!=result) { 7268 errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807"); 7269 } else { 7270 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807"); 7271 } 7272 } 7273 } 7274 } 7275 7276 7277 void NumberFormatTest::TestFormattableSize(void) { 7278 if(sizeof(FmtStackData) > UNUM_INTERNAL_STACKARRAY_SIZE) { 7279 errln("Error: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n", 7280 sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE); 7281 } else if(sizeof(FmtStackData) < UNUM_INTERNAL_STACKARRAY_SIZE) { 7282 logln("Warning: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n", 7283 sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE); 7284 } else { 7285 logln("sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n", 7286 sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE); 7287 } 7288 } 7289 7290 UBool NumberFormatTest::testFormattableAsUFormattable(const char *file, int line, Formattable &f) { 7291 UnicodeString fileLine = UnicodeString(file)+UnicodeString(":")+line+UnicodeString(": "); 7292 7293 UFormattable *u = f.toUFormattable(); 7294 logln(); 7295 if (u == NULL) { 7296 errln("%s:%d: Error: f.toUFormattable() retuned NULL."); 7297 return FALSE; 7298 } 7299 logln("%s:%d: comparing Formattable with UFormattable", file, line); 7300 logln(fileLine + toString(f)); 7301 7302 UErrorCode status = U_ZERO_ERROR; 7303 UErrorCode valueStatus = U_ZERO_ERROR; 7304 UFormattableType expectUType = UFMT_COUNT; // invalid 7305 7306 UBool triedExact = FALSE; // did we attempt an exact comparison? 7307 UBool exactMatch = FALSE; // was the exact comparison true? 7308 7309 switch( f.getType() ) { 7310 case Formattable::kDate: 7311 expectUType = UFMT_DATE; 7312 exactMatch = (f.getDate()==ufmt_getDate(u, &valueStatus)); 7313 triedExact = TRUE; 7314 break; 7315 case Formattable::kDouble: 7316 expectUType = UFMT_DOUBLE; 7317 exactMatch = (f.getDouble()==ufmt_getDouble(u, &valueStatus)); 7318 triedExact = TRUE; 7319 break; 7320 case Formattable::kLong: 7321 expectUType = UFMT_LONG; 7322 exactMatch = (f.getLong()==ufmt_getLong(u, &valueStatus)); 7323 triedExact = TRUE; 7324 break; 7325 case Formattable::kString: 7326 expectUType = UFMT_STRING; 7327 { 7328 UnicodeString str; 7329 f.getString(str); 7330 int32_t len; 7331 const UChar* uch = ufmt_getUChars(u, &len, &valueStatus); 7332 if(U_SUCCESS(valueStatus)) { 7333 UnicodeString str2(uch, len); 7334 assertTrue("UChar* NULL-terminated", uch[len]==0); 7335 exactMatch = (str == str2); 7336 } 7337 triedExact = TRUE; 7338 } 7339 break; 7340 case Formattable::kArray: 7341 expectUType = UFMT_ARRAY; 7342 triedExact = TRUE; 7343 { 7344 int32_t count = ufmt_getArrayLength(u, &valueStatus); 7345 int32_t count2; 7346 const Formattable *array2 = f.getArray(count2); 7347 exactMatch = assertEquals(fileLine + " array count", count, count2); 7348 7349 if(exactMatch) { 7350 for(int i=0;U_SUCCESS(valueStatus) && i<count;i++) { 7351 UFormattable *uu = ufmt_getArrayItemByIndex(u, i, &valueStatus); 7352 if(*Formattable::fromUFormattable(uu) != (array2[i])) { 7353 errln("%s:%d: operator== did not match at index[%d] - %p vs %p", file, line, i, 7354 (const void*)Formattable::fromUFormattable(uu), (const void*)&(array2[i])); 7355 exactMatch = FALSE; 7356 } else { 7357 if(!testFormattableAsUFormattable("(sub item)",i,*Formattable::fromUFormattable(uu))) { 7358 exactMatch = FALSE; 7359 } 7360 } 7361 } 7362 } 7363 } 7364 break; 7365 case Formattable::kInt64: 7366 expectUType = UFMT_INT64; 7367 exactMatch = (f.getInt64()==ufmt_getInt64(u, &valueStatus)); 7368 triedExact = TRUE; 7369 break; 7370 case Formattable::kObject: 7371 expectUType = UFMT_OBJECT; 7372 exactMatch = (f.getObject()==ufmt_getObject(u, &valueStatus)); 7373 triedExact = TRUE; 7374 break; 7375 } 7376 UFormattableType uType = ufmt_getType(u, &status); 7377 7378 if(U_FAILURE(status)) { 7379 errln("%s:%d: Error calling ufmt_getType - %s", file, line, u_errorName(status)); 7380 return FALSE; 7381 } 7382 7383 if(uType != expectUType) { 7384 errln("%s:%d: got type (%d) expected (%d) from ufmt_getType", file, line, (int) uType, (int) expectUType); 7385 } 7386 7387 if(triedExact) { 7388 if(U_FAILURE(valueStatus)) { 7389 errln("%s:%d: got err %s trying to ufmt_get...() for exact match check", file, line, u_errorName(valueStatus)); 7390 } else if(!exactMatch) { 7391 errln("%s:%d: failed exact match for the Formattable type", file, line); 7392 } else { 7393 logln("%s:%d: exact match OK", file, line); 7394 } 7395 } else { 7396 logln("%s:%d: note, did not attempt exact match for this formattable type", file, line); 7397 } 7398 7399 if( assertEquals(fileLine + " isNumeric()", f.isNumeric(), ufmt_isNumeric(u)) 7400 && f.isNumeric()) { 7401 UErrorCode convStatus = U_ZERO_ERROR; 7402 7403 if(uType != UFMT_INT64) { // may fail to compare 7404 assertTrue(fileLine + " as doubles ==", f.getDouble(convStatus)==ufmt_getDouble(u, &convStatus)); 7405 } 7406 7407 if( assertSuccess(fileLine + " (numeric conversion status)", convStatus) ) { 7408 StringPiece fDecNum = f.getDecimalNumber(convStatus); 7409 #if 1 7410 int32_t len; 7411 const char *decNumChars = ufmt_getDecNumChars(u, &len, &convStatus); 7412 #else 7413 // copy version 7414 char decNumChars[200]; 7415 int32_t len = ufmt_getDecNumChars(u, decNumChars, 200, &convStatus); 7416 #endif 7417 7418 if( assertSuccess(fileLine + " (decNumbers conversion)", convStatus) ) { 7419 logln(fileLine + decNumChars); 7420 assertEquals(fileLine + " decNumChars length==", len, fDecNum.length()); 7421 assertEquals(fileLine + " decNumChars digits", decNumChars, fDecNum.data()); 7422 } 7423 7424 UErrorCode int64ConversionF = U_ZERO_ERROR; 7425 int64_t l = f.getInt64(int64ConversionF); 7426 UErrorCode int64ConversionU = U_ZERO_ERROR; 7427 int64_t r = ufmt_getInt64(u, &int64ConversionU); 7428 7429 if( (l==r) 7430 && ( uType != UFMT_INT64 ) // int64 better not overflow 7431 && (U_INVALID_FORMAT_ERROR==int64ConversionU) 7432 && (U_INVALID_FORMAT_ERROR==int64ConversionF) ) { 7433 logln("%s:%d: OK: 64 bit overflow", file, line); 7434 } else { 7435 assertEquals(fileLine + " as int64 ==", l, r); 7436 assertSuccess(fileLine + " Formattable.getnt64()", int64ConversionF); 7437 assertSuccess(fileLine + " ufmt_getInt64()", int64ConversionU); 7438 } 7439 } 7440 } 7441 return exactMatch || !triedExact; 7442 } 7443 7444 void NumberFormatTest::TestUFormattable(void) { 7445 { 7446 // test that a default formattable is equal to Formattable() 7447 UErrorCode status = U_ZERO_ERROR; 7448 LocalUFormattablePointer defaultUFormattable(ufmt_open(&status)); 7449 assertSuccess("calling umt_open", status); 7450 Formattable defaultFormattable; 7451 assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()", 7452 (defaultFormattable 7453 == *(Formattable::fromUFormattable(defaultUFormattable.getAlias())))); 7454 assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()", 7455 (defaultFormattable 7456 == *(Formattable::fromUFormattable(defaultUFormattable.getAlias())))); 7457 assertTrue((UnicodeString)"comparing Formattable() round tripped through UFormattable", 7458 (defaultFormattable 7459 == *(Formattable::fromUFormattable(defaultFormattable.toUFormattable())))); 7460 assertTrue((UnicodeString)"comparing &Formattable() round tripped through UFormattable", 7461 ((&defaultFormattable) 7462 == Formattable::fromUFormattable(defaultFormattable.toUFormattable()))); 7463 assertFalse((UnicodeString)"comparing &Formattable() with ufmt_open()", 7464 ((&defaultFormattable) 7465 == Formattable::fromUFormattable(defaultUFormattable.getAlias()))); 7466 testFormattableAsUFormattable(__FILE__, __LINE__, defaultFormattable); 7467 } 7468 // test some random Formattables 7469 { 7470 Formattable f(ucal_getNow(), Formattable::kIsDate); 7471 testFormattableAsUFormattable(__FILE__, __LINE__, f); 7472 } 7473 { 7474 Formattable f((double)1.61803398874989484820); // golden ratio 7475 testFormattableAsUFormattable(__FILE__, __LINE__, f); 7476 } 7477 { 7478 Formattable f((int64_t)80994231587905127LL); // weight of the moon, in kilotons http://solarsystem.nasa.gov/planets/profile.cfm?Display=Facts&Object=Moon 7479 testFormattableAsUFormattable(__FILE__, __LINE__, f); 7480 } 7481 { 7482 Formattable f((int32_t)4); // random number, source: http://www.xkcd.com/221/ 7483 testFormattableAsUFormattable(__FILE__, __LINE__, f); 7484 } 7485 { 7486 Formattable f("Hello world."); // should be invariant? 7487 testFormattableAsUFormattable(__FILE__, __LINE__, f); 7488 } 7489 { 7490 UErrorCode status2 = U_ZERO_ERROR; 7491 Formattable f(StringPiece("73476730924573500000000.0"), status2); // weight of the moon, kg 7492 assertSuccess("Constructing a StringPiece", status2); 7493 testFormattableAsUFormattable(__FILE__, __LINE__, f); 7494 } 7495 { 7496 UErrorCode status2 = U_ZERO_ERROR; 7497 UObject *obj = new Locale(); 7498 Formattable f(obj); 7499 assertSuccess("Constructing a Formattable from a default constructed Locale()", status2); 7500 testFormattableAsUFormattable(__FILE__, __LINE__, f); 7501 } 7502 { 7503 const Formattable array[] = { 7504 Formattable(ucal_getNow(), Formattable::kIsDate), 7505 Formattable((int32_t)4), 7506 Formattable((double)1.234), 7507 }; 7508 7509 Formattable fa(array, 3); 7510 testFormattableAsUFormattable(__FILE__, __LINE__, fa); 7511 } 7512 } 7513 7514 void NumberFormatTest::TestSignificantDigits(void) { 7515 double input[] = { 7516 0, 0, 7517 0.1, -0.1, 7518 123, -123, 7519 12345, -12345, 7520 123.45, -123.45, 7521 123.44501, -123.44501, 7522 0.001234, -0.001234, 7523 0.00000000123, -0.00000000123, 7524 0.0000000000000000000123, -0.0000000000000000000123, 7525 1.2, -1.2, 7526 0.0000000012344501, -0.0000000012344501, 7527 123445.01, -123445.01, 7528 12344501000000000000000000000000000.0, -12344501000000000000000000000000000.0, 7529 }; 7530 const char* expected[] = { 7531 "0.00", "0.00", 7532 "0.100", "-0.100", 7533 "123", "-123", 7534 "12345", "-12345", 7535 "123.45", "-123.45", 7536 "123.45", "-123.45", 7537 "0.001234", "-0.001234", 7538 "0.00000000123", "-0.00000000123", 7539 "0.0000000000000000000123", "-0.0000000000000000000123", 7540 "1.20", "-1.20", 7541 "0.0000000012345", "-0.0000000012345", 7542 "123450", "-123450", 7543 "12345000000000000000000000000000000", "-12345000000000000000000000000000000", 7544 }; 7545 7546 UErrorCode status = U_ZERO_ERROR; 7547 Locale locale("en_US"); 7548 LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>( 7549 NumberFormat::createInstance(locale, status))); 7550 CHECK_DATA(status,"NumberFormat::createInstance") 7551 7552 numberFormat->setSignificantDigitsUsed(TRUE); 7553 numberFormat->setMinimumSignificantDigits(3); 7554 numberFormat->setMaximumSignificantDigits(5); 7555 numberFormat->setGroupingUsed(false); 7556 7557 UnicodeString result; 7558 UnicodeString expectedResult; 7559 for (unsigned int i = 0; i < sizeof(input)/sizeof(double); ++i) { 7560 numberFormat->format(input[i], result); 7561 UnicodeString expectedResult(expected[i]); 7562 if (result != expectedResult) { 7563 errln((UnicodeString)"Expected: '" + expectedResult + "' got '" + result); 7564 } 7565 result.remove(); 7566 } 7567 } 7568 7569 void NumberFormatTest::TestShowZero() { 7570 UErrorCode status = U_ZERO_ERROR; 7571 Locale locale("en_US"); 7572 LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>( 7573 NumberFormat::createInstance(locale, status))); 7574 CHECK_DATA(status, "NumberFormat::createInstance") 7575 7576 numberFormat->setSignificantDigitsUsed(TRUE); 7577 numberFormat->setMaximumSignificantDigits(3); 7578 7579 UnicodeString result; 7580 numberFormat->format(0.0, result); 7581 if (result != "0") { 7582 errln((UnicodeString)"Expected: 0, got " + result); 7583 } 7584 } 7585 7586 void NumberFormatTest::TestBug9936() { 7587 UErrorCode status = U_ZERO_ERROR; 7588 Locale locale("en_US"); 7589 LocalPointer<DecimalFormat> numberFormat(static_cast<DecimalFormat*>( 7590 NumberFormat::createInstance(locale, status))); 7591 if (U_FAILURE(status)) { 7592 dataerrln("File %s, Line %d: status = %s.\n", __FILE__, __LINE__, u_errorName(status)); 7593 return; 7594 } 7595 7596 if (numberFormat->areSignificantDigitsUsed() == TRUE) { 7597 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__); 7598 } 7599 numberFormat->setSignificantDigitsUsed(TRUE); 7600 if (numberFormat->areSignificantDigitsUsed() == FALSE) { 7601 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__); 7602 } 7603 7604 numberFormat->setSignificantDigitsUsed(FALSE); 7605 if (numberFormat->areSignificantDigitsUsed() == TRUE) { 7606 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__); 7607 } 7608 7609 numberFormat->setMinimumSignificantDigits(3); 7610 if (numberFormat->areSignificantDigitsUsed() == FALSE) { 7611 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__); 7612 } 7613 7614 numberFormat->setSignificantDigitsUsed(FALSE); 7615 numberFormat->setMaximumSignificantDigits(6); 7616 if (numberFormat->areSignificantDigitsUsed() == FALSE) { 7617 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__); 7618 } 7619 7620 } 7621 7622 void NumberFormatTest::TestParseNegativeWithFaLocale() { 7623 UErrorCode status = U_ZERO_ERROR; 7624 DecimalFormat *test = (DecimalFormat *) NumberFormat::createInstance("fa", status); 7625 CHECK_DATA(status, "NumberFormat::createInstance") 7626 test->setLenient(TRUE); 7627 Formattable af; 7628 ParsePosition ppos; 7629 UnicodeString value("\\u200e-0,5"); 7630 value = value.unescape(); 7631 test->parse(value, af, ppos); 7632 if (ppos.getIndex() == 0) { 7633 errln("Expected -0,5 to parse for Farsi."); 7634 } 7635 delete test; 7636 } 7637 7638 void NumberFormatTest::TestParseNegativeWithAlternateMinusSign() { 7639 UErrorCode status = U_ZERO_ERROR; 7640 DecimalFormat *test = (DecimalFormat *) NumberFormat::createInstance("en", status); 7641 CHECK_DATA(status, "NumberFormat::createInstance") 7642 test->setLenient(TRUE); 7643 Formattable af; 7644 ParsePosition ppos; 7645 UnicodeString value("\\u208B0.5"); 7646 value = value.unescape(); 7647 test->parse(value, af, ppos); 7648 if (ppos.getIndex() == 0) { 7649 errln(UnicodeString("Expected ") + value + UnicodeString(" to parse.")); 7650 } 7651 delete test; 7652 } 7653 7654 void NumberFormatTest::TestCustomCurrencySignAndSeparator() { 7655 UErrorCode status = U_ZERO_ERROR; 7656 DecimalFormatSymbols custom(Locale::getUS(), status); 7657 CHECK(status, "DecimalFormatSymbols constructor"); 7658 7659 custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "*"); 7660 custom.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, "^"); 7661 custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, ":"); 7662 7663 UnicodeString pat(" #,##0.00"); 7664 pat.insert(0, (UChar)0x00A4); 7665 7666 DecimalFormat fmt(pat, custom, status); 7667 CHECK(status, "DecimalFormat constructor"); 7668 7669 UnicodeString numstr("* 1^234:56"); 7670 expect2(fmt, (Formattable)((double)1234.56), numstr); 7671 } 7672 7673 typedef struct { 7674 const char * locale; 7675 UBool lenient; 7676 UnicodeString numString; 7677 double value; 7678 } SignsAndMarksItem; 7679 7680 7681 void NumberFormatTest::TestParseSignsAndMarks() { 7682 const SignsAndMarksItem items[] = { 7683 // locale lenient numString value 7684 { "en", FALSE, CharsToUnicodeString("12"), 12 }, 7685 { "en", TRUE, CharsToUnicodeString("12"), 12 }, 7686 { "en", FALSE, CharsToUnicodeString("-23"), -23 }, 7687 { "en", TRUE, CharsToUnicodeString("-23"), -23 }, 7688 { "en", TRUE, CharsToUnicodeString("- 23"), -23 }, 7689 { "en", FALSE, CharsToUnicodeString("\\u200E-23"), -23 }, 7690 { "en", TRUE, CharsToUnicodeString("\\u200E-23"), -23 }, 7691 { "en", TRUE, CharsToUnicodeString("\\u200E- 23"), -23 }, 7692 7693 { "en@numbers=arab", FALSE, CharsToUnicodeString("\\u0663\\u0664"), 34 }, 7694 { "en@numbers=arab", TRUE, CharsToUnicodeString("\\u0663\\u0664"), 34 }, 7695 { "en@numbers=arab", FALSE, CharsToUnicodeString("-\\u0664\\u0665"), -45 }, 7696 { "en@numbers=arab", TRUE, CharsToUnicodeString("-\\u0664\\u0665"), -45 }, 7697 { "en@numbers=arab", TRUE, CharsToUnicodeString("- \\u0664\\u0665"), -45 }, 7698 { "en@numbers=arab", FALSE, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 }, 7699 { "en@numbers=arab", TRUE, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 }, 7700 { "en@numbers=arab", TRUE, CharsToUnicodeString("\\u200F- \\u0664\\u0665"), -45 }, 7701 7702 { "en@numbers=arabext", FALSE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 }, 7703 { "en@numbers=arabext", TRUE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 }, 7704 { "en@numbers=arabext", FALSE, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 }, 7705 { "en@numbers=arabext", TRUE, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 }, 7706 { "en@numbers=arabext", TRUE, CharsToUnicodeString("- \\u06F6\\u06F7"), -67 }, 7707 { "en@numbers=arabext", FALSE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 }, 7708 { "en@numbers=arabext", TRUE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 }, 7709 { "en@numbers=arabext", TRUE, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 }, 7710 7711 { "he", FALSE, CharsToUnicodeString("12"), 12 }, 7712 { "he", TRUE, CharsToUnicodeString("12"), 12 }, 7713 { "he", FALSE, CharsToUnicodeString("-23"), -23 }, 7714 { "he", TRUE, CharsToUnicodeString("-23"), -23 }, 7715 { "he", TRUE, CharsToUnicodeString("- 23"), -23 }, 7716 { "he", FALSE, CharsToUnicodeString("\\u200E-23"), -23 }, 7717 { "he", TRUE, CharsToUnicodeString("\\u200E-23"), -23 }, 7718 { "he", TRUE, CharsToUnicodeString("\\u200E- 23"), -23 }, 7719 7720 { "ar", FALSE, CharsToUnicodeString("\\u0663\\u0664"), 34 }, 7721 { "ar", TRUE, CharsToUnicodeString("\\u0663\\u0664"), 34 }, 7722 { "ar", FALSE, CharsToUnicodeString("-\\u0664\\u0665"), -45 }, 7723 { "ar", TRUE, CharsToUnicodeString("-\\u0664\\u0665"), -45 }, 7724 { "ar", TRUE, CharsToUnicodeString("- \\u0664\\u0665"), -45 }, 7725 { "ar", FALSE, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 }, 7726 { "ar", TRUE, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 }, 7727 { "ar", TRUE, CharsToUnicodeString("\\u200F- \\u0664\\u0665"), -45 }, 7728 7729 { "ar_MA", FALSE, CharsToUnicodeString("12"), 12 }, 7730 { "ar_MA", TRUE, CharsToUnicodeString("12"), 12 }, 7731 { "ar_MA", FALSE, CharsToUnicodeString("-23"), -23 }, 7732 { "ar_MA", TRUE, CharsToUnicodeString("-23"), -23 }, 7733 { "ar_MA", TRUE, CharsToUnicodeString("- 23"), -23 }, 7734 { "ar_MA", FALSE, CharsToUnicodeString("\\u200E-23"), -23 }, 7735 { "ar_MA", TRUE, CharsToUnicodeString("\\u200E-23"), -23 }, 7736 { "ar_MA", TRUE, CharsToUnicodeString("\\u200E- 23"), -23 }, 7737 7738 { "fa", FALSE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 }, 7739 { "fa", TRUE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 }, 7740 { "fa", FALSE, CharsToUnicodeString("\\u2212\\u06F6\\u06F7"), -67 }, 7741 { "fa", TRUE, CharsToUnicodeString("\\u2212\\u06F6\\u06F7"), -67 }, 7742 { "fa", TRUE, CharsToUnicodeString("\\u2212 \\u06F6\\u06F7"), -67 }, 7743 { "fa", FALSE, CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"), -67 }, 7744 { "fa", TRUE, CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"), -67 }, 7745 { "fa", TRUE, CharsToUnicodeString("\\u200E\\u2212\\u200E \\u06F6\\u06F7"), -67 }, 7746 7747 { "ps", FALSE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 }, 7748 { "ps", TRUE, CharsToUnicodeString("\\u06F5\\u06F6"), 56 }, 7749 { "ps", FALSE, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 }, 7750 { "ps", TRUE, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 }, 7751 { "ps", TRUE, CharsToUnicodeString("- \\u06F6\\u06F7"), -67 }, 7752 { "ps", FALSE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 }, 7753 { "ps", TRUE, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 }, 7754 { "ps", TRUE, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 }, 7755 { "ps", FALSE, CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"), -67 }, 7756 { "ps", TRUE, CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"), -67 }, 7757 { "ps", TRUE, CharsToUnicodeString("-\\u200E \\u06F6\\u06F7"), -67 }, 7758 // terminator 7759 { NULL, 0, UnicodeString(""), 0 }, 7760 }; 7761 7762 const SignsAndMarksItem * itemPtr; 7763 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) { 7764 UErrorCode status = U_ZERO_ERROR; 7765 NumberFormat *numfmt = NumberFormat::createInstance(Locale(itemPtr->locale), status); 7766 if (U_SUCCESS(status)) { 7767 numfmt->setLenient(itemPtr->lenient); 7768 Formattable fmtobj; 7769 ParsePosition ppos; 7770 numfmt->parse(itemPtr->numString, fmtobj, ppos); 7771 if (ppos.getIndex() == itemPtr->numString.length()) { 7772 double parsedValue = fmtobj.getDouble(status); 7773 if (U_FAILURE(status) || parsedValue != itemPtr->value) { 7774 errln((UnicodeString)"FAIL: locale " + itemPtr->locale + ", lenient " + itemPtr->lenient + ", parse of \"" + itemPtr->numString + "\" gives value " + parsedValue); 7775 } 7776 } else { 7777 errln((UnicodeString)"FAIL: locale " + itemPtr->locale + ", lenient " + itemPtr->lenient + ", parse of \"" + itemPtr->numString + "\" gives position " + ppos.getIndex()); 7778 } 7779 } else { 7780 dataerrln("FAIL: NumberFormat::createInstance for locale % gives error %s", itemPtr->locale, u_errorName(status)); 7781 } 7782 delete numfmt; 7783 } 7784 } 7785 7786 typedef struct { 7787 DecimalFormat::ERoundingMode mode; 7788 double value; 7789 UnicodeString expected; 7790 } Test10419Data; 7791 7792 7793 // Tests that rounding works right when fractional digits is set to 0. 7794 void NumberFormatTest::Test10419RoundingWith0FractionDigits() { 7795 const Test10419Data items[] = { 7796 { DecimalFormat::kRoundCeiling, 1.488, "2"}, 7797 { DecimalFormat::kRoundDown, 1.588, "1"}, 7798 { DecimalFormat::kRoundFloor, 1.888, "1"}, 7799 { DecimalFormat::kRoundHalfDown, 1.5, "1"}, 7800 { DecimalFormat::kRoundHalfEven, 2.5, "2"}, 7801 { DecimalFormat::kRoundHalfUp, 2.5, "3"}, 7802 { DecimalFormat::kRoundUp, 1.5, "2"}, 7803 }; 7804 UErrorCode status = U_ZERO_ERROR; 7805 LocalPointer<DecimalFormat> decfmt((DecimalFormat *) NumberFormat::createInstance(Locale("en_US"), status)); 7806 if (U_FAILURE(status)) { 7807 dataerrln("Failure creating DecimalFormat %s", u_errorName(status)); 7808 return; 7809 } 7810 for (int32_t i = 0; i < (int32_t) (sizeof(items) / sizeof(items[0])); ++i) { 7811 decfmt->setRoundingMode(items[i].mode); 7812 decfmt->setMaximumFractionDigits(0); 7813 UnicodeString actual; 7814 if (items[i].expected != decfmt->format(items[i].value, actual)) { 7815 errln("Expected " + items[i].expected + ", got " + actual); 7816 } 7817 } 7818 } 7819 7820 void NumberFormatTest::Test10468ApplyPattern() { 7821 // Padding char of fmt is now 'a' 7822 UErrorCode status = U_ZERO_ERROR; 7823 DecimalFormat fmt("'I''ll'*a###.##", status); 7824 7825 if (U_FAILURE(status)) { 7826 errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status)); 7827 return; 7828 } 7829 7830 if (fmt.getPadCharacterString() != UnicodeString("a")) { 7831 errln("Padding character should be 'a'."); 7832 return; 7833 } 7834 7835 // Padding char of fmt ought to be '*' since that is the default and no 7836 // explicit padding char is specified in the new pattern. 7837 fmt.applyPattern("AA#,##0.00ZZ", status); 7838 7839 // Oops this still prints 'a' even though we changed the pattern. 7840 if (fmt.getPadCharacterString() != UnicodeString(" ")) { 7841 errln("applyPattern did not clear padding character."); 7842 } 7843 } 7844 7845 void NumberFormatTest::TestRoundingScientific10542() { 7846 UErrorCode status = U_ZERO_ERROR; 7847 DecimalFormat format("0.00E0", status); 7848 if (U_FAILURE(status)) { 7849 errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status)); 7850 return; 7851 } 7852 7853 DecimalFormat::ERoundingMode roundingModes[] = { 7854 DecimalFormat::kRoundCeiling, 7855 DecimalFormat::kRoundDown, 7856 DecimalFormat::kRoundFloor, 7857 DecimalFormat::kRoundHalfDown, 7858 DecimalFormat::kRoundHalfEven, 7859 DecimalFormat::kRoundHalfUp, 7860 DecimalFormat::kRoundUp}; 7861 const char *descriptions[] = { 7862 "Round Ceiling", 7863 "Round Down", 7864 "Round Floor", 7865 "Round half down", 7866 "Round half even", 7867 "Round half up", 7868 "Round up"}; 7869 7870 { 7871 double values[] = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016}; 7872 // The order of these expected values correspond to the order of roundingModes and the order of values. 7873 const char *expected[] = { 7874 "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.02E-3", "3.02E-3", "3.02E-3", 7875 "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.01E-3", 7876 "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.01E-3", "3.01E-3", "3.01E-3", 7877 "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.02E-3", 7878 "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3", 7879 "-3.01E-3", "-3.01E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3", 7880 "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.02E-3", "3.02E-3", "3.02E-3"}; 7881 verifyRounding( 7882 format, 7883 values, 7884 expected, 7885 roundingModes, 7886 descriptions, 7887 (int32_t) (sizeof(values) / sizeof(values[0])), 7888 (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); 7889 } 7890 { 7891 double values[] = {-3006.0, -3005, -3004, 3014, 3015, 3016}; 7892 // The order of these expected values correspond to the order of roundingModes and the order of values. 7893 const char *expected[] = { 7894 "-3.00E3", "-3.00E3", "-3.00E3", "3.02E3", "3.02E3", "3.02E3", 7895 "-3.00E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.01E3", 7896 "-3.01E3", "-3.01E3", "-3.01E3", "3.01E3", "3.01E3", "3.01E3", 7897 "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.02E3", 7898 "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3", 7899 "-3.01E3", "-3.01E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3", 7900 "-3.01E3", "-3.01E3", "-3.01E3", "3.02E3", "3.02E3", "3.02E3"}; 7901 verifyRounding( 7902 format, 7903 values, 7904 expected, 7905 roundingModes, 7906 descriptions, 7907 (int32_t) (sizeof(values) / sizeof(values[0])), 7908 (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); 7909 } 7910 /* Commented out for now until we decide how rounding to zero should work, +0 vs. -0 7911 { 7912 double values[] = {0.0, -0.0}; 7913 // The order of these expected values correspond to the order of roundingModes and the order of values. 7914 const char *expected[] = { 7915 "0.00E0", "-0.00E0", 7916 "0.00E0", "-0.00E0", 7917 "0.00E0", "-0.00E0", 7918 "0.00E0", "-0.00E0", 7919 "0.00E0", "-0.00E0", 7920 "0.00E0", "-0.00E0", 7921 "0.00E0", "-0.00E0"}; 7922 verifyRounding( 7923 format, 7924 values, 7925 expected, 7926 roundingModes, 7927 descriptions, 7928 (int32_t) (sizeof(values) / sizeof(values[0])), 7929 (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); 7930 } 7931 */ 7932 { 7933 7934 double values[] = {1e25, 1e25 + 1e15, 1e25 - 1e15}; 7935 // The order of these expected values correspond to the order of roundingModes and the order of values. 7936 const char *expected[] = { 7937 "1.00E25", "1.01E25", "1.00E25", 7938 "1.00E25", "1.00E25", "9.99E24", 7939 "1.00E25", "1.00E25", "9.99E24", 7940 "1.00E25", "1.00E25", "1.00E25", 7941 "1.00E25", "1.00E25", "1.00E25", 7942 "1.00E25", "1.00E25", "1.00E25", 7943 "1.00E25", "1.01E25", "1.00E25"}; 7944 verifyRounding( 7945 format, 7946 values, 7947 expected, 7948 roundingModes, 7949 descriptions, 7950 (int32_t) (sizeof(values) / sizeof(values[0])), 7951 (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); 7952 } 7953 { 7954 double values[] = {-1e25, -1e25 + 1e15, -1e25 - 1e15}; 7955 // The order of these expected values correspond to the order of roundingModes and the order of values. 7956 const char *expected[] = { 7957 "-1.00E25", "-9.99E24", "-1.00E25", 7958 "-1.00E25", "-9.99E24", "-1.00E25", 7959 "-1.00E25", "-1.00E25", "-1.01E25", 7960 "-1.00E25", "-1.00E25", "-1.00E25", 7961 "-1.00E25", "-1.00E25", "-1.00E25", 7962 "-1.00E25", "-1.00E25", "-1.00E25", 7963 "-1.00E25", "-1.00E25", "-1.01E25"}; 7964 verifyRounding( 7965 format, 7966 values, 7967 expected, 7968 roundingModes, 7969 descriptions, 7970 (int32_t) (sizeof(values) / sizeof(values[0])), 7971 (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); 7972 } 7973 { 7974 double values[] = {1e-25, 1e-25 + 1e-35, 1e-25 - 1e-35}; 7975 // The order of these expected values correspond to the order of roundingModes and the order of values. 7976 const char *expected[] = { 7977 "1.00E-25", "1.01E-25", "1.00E-25", 7978 "1.00E-25", "1.00E-25", "9.99E-26", 7979 "1.00E-25", "1.00E-25", "9.99E-26", 7980 "1.00E-25", "1.00E-25", "1.00E-25", 7981 "1.00E-25", "1.00E-25", "1.00E-25", 7982 "1.00E-25", "1.00E-25", "1.00E-25", 7983 "1.00E-25", "1.01E-25", "1.00E-25"}; 7984 verifyRounding( 7985 format, 7986 values, 7987 expected, 7988 roundingModes, 7989 descriptions, 7990 (int32_t) (sizeof(values) / sizeof(values[0])), 7991 (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); 7992 } 7993 { 7994 double values[] = {-1e-25, -1e-25 + 1e-35, -1e-25 - 1e-35}; 7995 // The order of these expected values correspond to the order of roundingModes and the order of values. 7996 const char *expected[] = { 7997 "-1.00E-25", "-9.99E-26", "-1.00E-25", 7998 "-1.00E-25", "-9.99E-26", "-1.00E-25", 7999 "-1.00E-25", "-1.00E-25", "-1.01E-25", 8000 "-1.00E-25", "-1.00E-25", "-1.00E-25", 8001 "-1.00E-25", "-1.00E-25", "-1.00E-25", 8002 "-1.00E-25", "-1.00E-25", "-1.00E-25", 8003 "-1.00E-25", "-1.00E-25", "-1.01E-25"}; 8004 verifyRounding( 8005 format, 8006 values, 8007 expected, 8008 roundingModes, 8009 descriptions, 8010 (int32_t) (sizeof(values) / sizeof(values[0])), 8011 (int32_t) (sizeof(roundingModes) / sizeof(roundingModes[0]))); 8012 } 8013 } 8014 8015 void NumberFormatTest::TestZeroScientific10547() { 8016 UErrorCode status = U_ZERO_ERROR; 8017 DecimalFormat fmt("0.00E0", status); 8018 if (!assertSuccess("Formt creation", status)) { 8019 return; 8020 } 8021 UnicodeString out; 8022 fmt.format(-0.0, out); 8023 assertEquals("format", "-0.00E0", out); 8024 } 8025 8026 void NumberFormatTest::verifyRounding( 8027 DecimalFormat& format, 8028 const double *values, 8029 const char * const *expected, 8030 const DecimalFormat::ERoundingMode *roundingModes, 8031 const char * const *descriptions, 8032 int32_t valueSize, 8033 int32_t roundingModeSize) { 8034 for (int32_t i = 0; i < roundingModeSize; ++i) { 8035 format.setRoundingMode(roundingModes[i]); 8036 for (int32_t j = 0; j < valueSize; j++) { 8037 UnicodeString currentExpected(expected[i * valueSize + j]); 8038 currentExpected = currentExpected.unescape(); 8039 UnicodeString actual; 8040 format.format(values[j], actual); 8041 if (currentExpected != actual) { 8042 char buffer[256]; 8043 sprintf( 8044 buffer, 8045 "For %s value %f, expected ", 8046 descriptions[i], 8047 values[j]); 8048 errln(UnicodeString(buffer) + currentExpected + ", got " + actual); 8049 } 8050 } 8051 } 8052 } 8053 8054 void NumberFormatTest::TestAccountingCurrency() { 8055 UErrorCode status = U_ZERO_ERROR; 8056 UNumberFormatStyle style = UNUM_CURRENCY_ACCOUNTING; 8057 8058 expect(NumberFormat::createInstance("en_US", style, status), 8059 (Formattable)1234.5, "$1,234.50", TRUE, status); 8060 expect(NumberFormat::createInstance("en_US", style, status), 8061 (Formattable)-1234.5, "($1,234.50)", TRUE, status); 8062 expect(NumberFormat::createInstance("en_US", style, status), 8063 (Formattable)0, "$0.00", TRUE, status); 8064 expect(NumberFormat::createInstance("en_US", style, status), 8065 (Formattable)-0.2, "($0.20)", TRUE, status); 8066 expect(NumberFormat::createInstance("ja_JP", style, status), 8067 (Formattable)10000, UnicodeString("\\uFFE510,000").unescape(), TRUE, status); 8068 expect(NumberFormat::createInstance("ja_JP", style, status), 8069 (Formattable)-1000.5, UnicodeString("(\\uFFE51,000)").unescape(), FALSE, status); 8070 expect(NumberFormat::createInstance("de_DE", style, status), 8071 (Formattable)-23456.7, UnicodeString("-23.456,70\\u00A0\\u20AC").unescape(), TRUE, status); 8072 } 8073 8074 // for #5186 8075 void NumberFormatTest::TestEquality() { 8076 UErrorCode status = U_ZERO_ERROR; 8077 DecimalFormatSymbols* symbols = new DecimalFormatSymbols(Locale("root"), status); 8078 if (U_FAILURE(status)) { 8079 dataerrln("Fail: can't create DecimalFormatSymbols for root"); 8080 return; 8081 } 8082 UnicodeString pattern("#,##0.###"); 8083 DecimalFormat* fmtBase = new DecimalFormat(pattern, symbols, status); 8084 if (U_FAILURE(status)) { 8085 dataerrln("Fail: can't create DecimalFormat using root symbols"); 8086 return; 8087 } 8088 8089 DecimalFormat* fmtClone = (DecimalFormat*)fmtBase->clone(); 8090 fmtClone->setFormatWidth(fmtBase->getFormatWidth() + 32); 8091 if (*fmtClone == *fmtBase) { 8092 errln("Error: DecimalFormat == does not distinguish objects that differ only in FormatWidth"); 8093 } 8094 delete fmtClone; 8095 8096 delete fmtBase; 8097 } 8098 8099 void NumberFormatTest::TestCurrencyUsage() { 8100 double agent = 123.567; 8101 8102 UErrorCode status; 8103 DecimalFormat *fmt; 8104 8105 // compare the Currency and Currency Cash Digits 8106 // Note that as of CLDR 26: 8107 // * TWD switches from 0 decimals to 2; PKR still has 0, so change test to that 8108 // * CAD and all other currencies that rounded to .05 no longer do 8109 // 1st time for getter/setter, 2nd time for factory method 8110 Locale enUS_PKR("en_US@currency=PKR"); 8111 8112 for(int i=0; i<2; i++){ 8113 status = U_ZERO_ERROR; 8114 if(i == 0){ 8115 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_PKR, UNUM_CURRENCY, status); 8116 if (assertSuccess("en_US@currency=PKR/CURRENCY", status, TRUE) == FALSE) { 8117 continue; 8118 } 8119 8120 UnicodeString original; 8121 fmt->format(agent,original); 8122 assertEquals("Test Currency Usage 1", UnicodeString("PKR124"), original); 8123 8124 // test the getter here 8125 UCurrencyUsage curUsage = fmt->getCurrencyUsage(); 8126 assertEquals("Test usage getter - standard", curUsage, UCURR_USAGE_STANDARD); 8127 8128 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status); 8129 }else{ 8130 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_PKR, UNUM_CASH_CURRENCY, status); 8131 if (assertSuccess("en_US@currency=PKR/CASH", status, TRUE) == FALSE) { 8132 continue; 8133 } 8134 } 8135 8136 // must be usage = cash 8137 UCurrencyUsage curUsage = fmt->getCurrencyUsage(); 8138 assertEquals("Test usage getter - cash", curUsage, UCURR_USAGE_CASH); 8139 8140 UnicodeString cash_currency; 8141 fmt->format(agent,cash_currency); 8142 assertEquals("Test Currency Usage 2", UnicodeString("PKR124"), cash_currency); 8143 delete fmt; 8144 } 8145 8146 // compare the Currency and Currency Cash Rounding 8147 // 1st time for getter/setter, 2nd time for factory method 8148 Locale enUS_CAD("en_US@currency=CAD"); 8149 for(int i=0; i<2; i++){ 8150 status = U_ZERO_ERROR; 8151 if(i == 0){ 8152 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CURRENCY, status); 8153 if (assertSuccess("en_US@currency=CAD/CURRENCY", status, TRUE) == FALSE) { 8154 continue; 8155 } 8156 8157 UnicodeString original_rounding; 8158 fmt->format(agent, original_rounding); 8159 assertEquals("Test Currency Usage 3", UnicodeString("CA$123.57"), original_rounding); 8160 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status); 8161 }else{ 8162 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status); 8163 if (assertSuccess("en_US@currency=CAD/CASH", status, TRUE) == FALSE) { 8164 continue; 8165 } 8166 } 8167 8168 UnicodeString cash_rounding_currency; 8169 fmt->format(agent, cash_rounding_currency); 8170 assertEquals("Test Currency Usage 4", UnicodeString("CA$123.57"), cash_rounding_currency); 8171 delete fmt; 8172 } 8173 8174 // Test the currency change 8175 // 1st time for getter/setter, 2nd time for factory method 8176 const UChar CUR_PKR[] = {0x50, 0x4B, 0x52, 0}; 8177 for(int i=0; i<2; i++){ 8178 status = U_ZERO_ERROR; 8179 if(i == 0){ 8180 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CURRENCY, status); 8181 if (assertSuccess("en_US@currency=CAD/CURRENCY", status, TRUE) == FALSE) { 8182 continue; 8183 } 8184 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status); 8185 }else{ 8186 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status); 8187 if (assertSuccess("en_US@currency=CAD/CASH", status, TRUE) == FALSE) { 8188 continue; 8189 } 8190 } 8191 8192 UnicodeString cur_original; 8193 fmt->format(agent, cur_original); 8194 assertEquals("Test Currency Usage 5", UnicodeString("CA$123.57"), cur_original); 8195 8196 fmt->setCurrency(CUR_PKR, status); 8197 assertSuccess("Set currency to PKR", status); 8198 8199 UnicodeString PKR_changed; 8200 fmt->format(agent, PKR_changed); 8201 assertEquals("Test Currency Usage 6", UnicodeString("PKR124"), PKR_changed); 8202 delete fmt; 8203 } 8204 } 8205 8206 void NumberFormatTest::TestNumberFormatTestTuple() { 8207 NumberFormatTestTuple tuple; 8208 UErrorCode status = U_ZERO_ERROR; 8209 8210 tuple.setField( 8211 NumberFormatTestTuple::getFieldByName("locale"), 8212 "en", 8213 status); 8214 tuple.setField( 8215 NumberFormatTestTuple::getFieldByName("pattern"), 8216 "#,##0.00", 8217 status); 8218 tuple.setField( 8219 NumberFormatTestTuple::getFieldByName("minIntegerDigits"), 8220 "-10", 8221 status); 8222 if (!assertSuccess("", status)) { 8223 return; 8224 } 8225 8226 // only what we set should be set. 8227 assertEquals("", "en", tuple.locale.getName()); 8228 assertEquals("", "#,##0.00", tuple.pattern); 8229 assertEquals("", -10, tuple.minIntegerDigits); 8230 assertTrue("", tuple.localeFlag); 8231 assertTrue("", tuple.patternFlag); 8232 assertTrue("", tuple.minIntegerDigitsFlag); 8233 assertFalse("", tuple.formatFlag); 8234 8235 UnicodeString appendTo; 8236 assertEquals( 8237 "", 8238 "{locale: en, pattern: #,##0.00, minIntegerDigits: -10}", 8239 tuple.toString(appendTo)); 8240 8241 tuple.clear(); 8242 appendTo.remove(); 8243 assertEquals( 8244 "", 8245 "{}", 8246 tuple.toString(appendTo)); 8247 tuple.setField( 8248 NumberFormatTestTuple::getFieldByName("aBadFieldName"), 8249 "someValue", 8250 status); 8251 if (status != U_ILLEGAL_ARGUMENT_ERROR) { 8252 errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 8253 } 8254 status = U_ZERO_ERROR; 8255 tuple.setField( 8256 NumberFormatTestTuple::getFieldByName("minIntegerDigits"), 8257 "someBadValue", 8258 status); 8259 if (status != U_ILLEGAL_ARGUMENT_ERROR) { 8260 errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 8261 } 8262 } 8263 8264 void 8265 NumberFormatTest::TestDataDriven() { 8266 NumberFormatTestDataDriven dd; 8267 dd.setCaller(this); 8268 dd.run("numberformattestspecification.txt", FALSE); 8269 } 8270 8271 8272 // Check the constant MAX_INT64_IN_DOUBLE. 8273 // The value should convert to a double with no loss of precision. 8274 // A failure may indicate a platform with a different double format, requiring 8275 // a revision to the constant. 8276 // 8277 // Note that this is actually hard to test, because the language standard gives 8278 // compilers considerable flexibility to do unexpected things with rounding and 8279 // with overflow in simple int to/from float conversions. Some compilers will completely optimize 8280 // away a simple round-trip conversion from int64_t -> double -> int64_t. 8281 8282 void NumberFormatTest::TestDoubleLimit11439() { 8283 char buf[50]; 8284 for (int64_t num = MAX_INT64_IN_DOUBLE-10; num<=MAX_INT64_IN_DOUBLE; num++) { 8285 sprintf(buf, "%lld", (long long)num); 8286 double fNum = 0.0; 8287 sscanf(buf, "%lf", &fNum); 8288 int64_t rtNum = fNum; 8289 if (num != rtNum) { 8290 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__, __LINE__, (long long)num, (long long)rtNum); 8291 return; 8292 } 8293 } 8294 for (int64_t num = -MAX_INT64_IN_DOUBLE+10; num>=-MAX_INT64_IN_DOUBLE; num--) { 8295 sprintf(buf, "%lld", (long long)num); 8296 double fNum = 0.0; 8297 sscanf(buf, "%lf", &fNum); 8298 int64_t rtNum = fNum; 8299 if (num != rtNum) { 8300 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__, __LINE__, (long long)num, (long long)rtNum); 8301 return; 8302 } 8303 } 8304 } 8305 8306 void NumberFormatTest::TestFastPathConsistent11524() { 8307 UErrorCode status = U_ZERO_ERROR; 8308 NumberFormat *fmt = NumberFormat::createInstance("en", status); 8309 if (U_FAILURE(status) || fmt == NULL) { 8310 dataerrln("Failed call to NumberFormat::createInstance() - %s", u_errorName(status)); 8311 return; 8312 } 8313 fmt->setMaximumIntegerDigits(INT32_MIN); 8314 UnicodeString appendTo; 8315 assertEquals("", "0", fmt->format(123, appendTo)); 8316 appendTo.remove(); 8317 assertEquals("", "0", fmt->format(12345, appendTo)); 8318 delete fmt; 8319 } 8320 8321 void NumberFormatTest::TestGetAffixes() { 8322 UErrorCode status = U_ZERO_ERROR; 8323 DecimalFormatSymbols sym("en_US", status); 8324 UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4"); 8325 pattern = pattern.unescape(); 8326 DecimalFormat fmt(pattern, sym, status); 8327 if (U_FAILURE(status)) { 8328 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 8329 return; 8330 } 8331 UnicodeString affixStr; 8332 assertEquals("", "US dollars ", fmt.getPositivePrefix(affixStr)); 8333 assertEquals("", " %USD", fmt.getPositiveSuffix(affixStr)); 8334 assertEquals("", "-US dollars ", fmt.getNegativePrefix(affixStr)); 8335 assertEquals("", " %USD", fmt.getNegativeSuffix(affixStr)); 8336 8337 // Test equality with affixes. set affix methods can't capture special 8338 // characters which is why equality should fail. 8339 { 8340 DecimalFormat fmtCopy(fmt); 8341 assertTrue("", fmt == fmtCopy); 8342 UnicodeString someAffix; 8343 fmtCopy.setPositivePrefix(fmtCopy.getPositivePrefix(someAffix)); 8344 assertTrue("", fmt != fmtCopy); 8345 } 8346 { 8347 DecimalFormat fmtCopy(fmt); 8348 assertTrue("", fmt == fmtCopy); 8349 UnicodeString someAffix; 8350 fmtCopy.setPositiveSuffix(fmtCopy.getPositiveSuffix(someAffix)); 8351 assertTrue("", fmt != fmtCopy); 8352 } 8353 { 8354 DecimalFormat fmtCopy(fmt); 8355 assertTrue("", fmt == fmtCopy); 8356 UnicodeString someAffix; 8357 fmtCopy.setNegativePrefix(fmtCopy.getNegativePrefix(someAffix)); 8358 assertTrue("", fmt != fmtCopy); 8359 } 8360 { 8361 DecimalFormat fmtCopy(fmt); 8362 assertTrue("", fmt == fmtCopy); 8363 UnicodeString someAffix; 8364 fmtCopy.setNegativeSuffix(fmtCopy.getNegativeSuffix(someAffix)); 8365 assertTrue("", fmt != fmtCopy); 8366 } 8367 fmt.setPositivePrefix("Don't"); 8368 fmt.setPositiveSuffix("do"); 8369 UnicodeString someAffix("be''eet\\u00a4\\u00a4\\u00a4 it."); 8370 someAffix = someAffix.unescape(); 8371 fmt.setNegativePrefix(someAffix); 8372 fmt.setNegativeSuffix("%"); 8373 assertEquals("", "Don't", fmt.getPositivePrefix(affixStr)); 8374 assertEquals("", "do", fmt.getPositiveSuffix(affixStr)); 8375 assertEquals("", someAffix, fmt.getNegativePrefix(affixStr)); 8376 assertEquals("", "%", fmt.getNegativeSuffix(affixStr)); 8377 } 8378 8379 void NumberFormatTest::TestToPatternScientific11648() { 8380 UErrorCode status = U_ZERO_ERROR; 8381 Locale en("en"); 8382 DecimalFormatSymbols sym(en, status); 8383 DecimalFormat fmt("0.00", sym, status); 8384 if (U_FAILURE(status)) { 8385 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 8386 return; 8387 } 8388 fmt.setScientificNotation(TRUE); 8389 UnicodeString pattern; 8390 assertEquals("", "0.00E0", fmt.toPattern(pattern)); 8391 DecimalFormat fmt2(pattern, sym, status); 8392 assertSuccess("", status); 8393 } 8394 8395 void NumberFormatTest::TestBenchmark() { 8396 /* 8397 UErrorCode status = U_ZERO_ERROR; 8398 Locale en("en"); 8399 DecimalFormatSymbols sym(en, status); 8400 DecimalFormat fmt("0.0000000", new DecimalFormatSymbols(sym), status); 8401 // DecimalFormat fmt("0.00000E0", new DecimalFormatSymbols(sym), status); 8402 // DecimalFormat fmt("0", new DecimalFormatSymbols(sym), status); 8403 FieldPosition fpos(0); 8404 clock_t start = clock(); 8405 for (int32_t i = 0; i < 1000000; ++i) { 8406 UnicodeString append; 8407 fmt.format(3.0, append, fpos, status); 8408 // fmt.format(4.6692016, append, fpos, status); 8409 // fmt.format(1234567.8901, append, fpos, status); 8410 // fmt.format(2.99792458E8, append, fpos, status); 8411 // fmt.format(31, append); 8412 } 8413 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC); 8414 assertSuccess("", status); 8415 8416 UErrorCode status = U_ZERO_ERROR; 8417 MessageFormat fmt("{0, plural, one {I have # friend.} other {I have # friends.}}", status); 8418 FieldPosition fpos(0); 8419 Formattable one(1.0); 8420 Formattable three(3.0); 8421 clock_t start = clock(); 8422 for (int32_t i = 0; i < 500000; ++i) { 8423 UnicodeString append; 8424 fmt.format(&one, 1, append, fpos, status); 8425 UnicodeString append2; 8426 fmt.format(&three, 1, append2, fpos, status); 8427 } 8428 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC); 8429 assertSuccess("", status); 8430 8431 UErrorCode status = U_ZERO_ERROR; 8432 Locale en("en"); 8433 Measure measureC(23, MeasureUnit::createCelsius(status), status); 8434 MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status); 8435 FieldPosition fpos(0); 8436 clock_t start = clock(); 8437 for (int32_t i = 0; i < 1000000; ++i) { 8438 UnicodeString appendTo; 8439 fmt.formatMeasures( 8440 &measureC, 1, appendTo, fpos, status); 8441 } 8442 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC); 8443 assertSuccess("", status); 8444 */ 8445 } 8446 8447 void NumberFormatTest::TestFractionalDigitsForCurrency() { 8448 UErrorCode status = U_ZERO_ERROR; 8449 LocalPointer<NumberFormat> fmt(NumberFormat::createCurrencyInstance("en", status)); 8450 if (U_FAILURE(status)) { 8451 dataerrln("Error creating NumberFormat - %s", u_errorName(status)); 8452 return; 8453 } 8454 UChar JPY[] = {0x4A, 0x50, 0x59, 0x0}; 8455 fmt->setCurrency(JPY, status); 8456 if (!assertSuccess("", status)) { 8457 return; 8458 } 8459 assertEquals("", 0, fmt->getMaximumFractionDigits()); 8460 } 8461 8462 8463 void NumberFormatTest::TestFormatCurrencyPlural() { 8464 UErrorCode status = U_ZERO_ERROR; 8465 Locale locale = Locale::createCanonical("en_US"); 8466 NumberFormat *fmt = NumberFormat::createInstance(locale, UNUM_CURRENCY_PLURAL, status); 8467 if (U_FAILURE(status)) { 8468 dataerrln("Error creating NumberFormat - %s", u_errorName(status)); 8469 return; 8470 } 8471 UnicodeString formattedNum; 8472 fmt->format(11234.567, formattedNum, NULL, status); 8473 assertEquals("", "11,234.57 US dollars", formattedNum); 8474 delete fmt; 8475 } 8476 8477 void NumberFormatTest::TestCtorApplyPatternDifference() { 8478 UErrorCode status = U_ZERO_ERROR; 8479 DecimalFormatSymbols sym("en_US", status); 8480 UnicodeString pattern("\\u00a40"); 8481 DecimalFormat fmt(pattern.unescape(), sym, status); 8482 if (U_FAILURE(status)) { 8483 dataerrln("Error creating DecimalFormat - %s", u_errorName(status)); 8484 return; 8485 } 8486 UnicodeString result; 8487 assertEquals( 8488 "ctor favors precision of currency", 8489 "$5.00", 8490 fmt.format(5, result)); 8491 result.remove(); 8492 fmt.applyPattern(pattern.unescape(), status); 8493 assertEquals( 8494 "applyPattern favors precision of pattern", 8495 "$5", 8496 fmt.format(5, result)); 8497 } 8498 8499 void NumberFormatTest::Test11868() { 8500 double posAmt = 34.567; 8501 double negAmt = -9876.543; 8502 8503 Locale selectedLocale("en_US"); 8504 UErrorCode status = U_ZERO_ERROR; 8505 8506 UnicodeString result; 8507 FieldPosition fpCurr(UNUM_CURRENCY_FIELD); 8508 LocalPointer<NumberFormat> fmt( 8509 NumberFormat::createInstance( 8510 selectedLocale, UNUM_CURRENCY_PLURAL, status)); 8511 if (!assertSuccess("Format creation", status)) { 8512 return; 8513 } 8514 fmt->format(posAmt, result, fpCurr, status); 8515 assertEquals("", "34.57 US dollars", result); 8516 assertEquals("begin index", 6, fpCurr.getBeginIndex()); 8517 assertEquals("end index", 16, fpCurr.getEndIndex()); 8518 8519 // Test field position iterator 8520 { 8521 NumberFormatTest_Attributes attributes[] = { 8522 {UNUM_INTEGER_FIELD, 0, 2}, 8523 {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3}, 8524 {UNUM_FRACTION_FIELD, 3, 5}, 8525 {UNUM_CURRENCY_FIELD, 6, 16}, 8526 {0, -1, 0}}; 8527 UnicodeString result; 8528 FieldPositionIterator iter; 8529 fmt->format(posAmt, result, &iter, status); 8530 assertEquals("", "34.57 US dollars", result); 8531 verifyFieldPositionIterator(attributes, iter); 8532 } 8533 8534 result.remove(); 8535 fmt->format(negAmt, result, fpCurr, status); 8536 assertEquals("", "-9,876.54 US dollars", result); 8537 assertEquals("begin index", 10, fpCurr.getBeginIndex()); 8538 assertEquals("end index", 20, fpCurr.getEndIndex()); 8539 8540 // Test field position iterator 8541 { 8542 NumberFormatTest_Attributes attributes[] = { 8543 {UNUM_SIGN_FIELD, 0, 1}, 8544 {UNUM_GROUPING_SEPARATOR_FIELD, 2, 3}, 8545 {UNUM_INTEGER_FIELD, 1, 6}, 8546 {UNUM_DECIMAL_SEPARATOR_FIELD, 6, 7}, 8547 {UNUM_FRACTION_FIELD, 7, 9}, 8548 {UNUM_CURRENCY_FIELD, 10, 20}, 8549 {0, -1, 0}}; 8550 UnicodeString result; 8551 FieldPositionIterator iter; 8552 fmt->format(negAmt, result, &iter, status); 8553 assertEquals("", "-9,876.54 US dollars", result); 8554 verifyFieldPositionIterator(attributes, iter); 8555 } 8556 } 8557 8558 void NumberFormatTest::Test10727_RoundingZero() { 8559 DigitList d; 8560 d.set(-0.0); 8561 assertFalse("", d.isPositive()); 8562 d.round(3); 8563 assertFalse("", d.isPositive()); 8564 } 8565 8566 void NumberFormatTest::Test11376_getAndSetPositivePrefix() { 8567 { 8568 const UChar USD[] = {0x55, 0x53, 0x44, 0x0}; 8569 UErrorCode status = U_ZERO_ERROR; 8570 LocalPointer<NumberFormat> fmt( 8571 NumberFormat::createCurrencyInstance("en", status)); 8572 if (!assertSuccess("", status)) { 8573 return; 8574 } 8575 DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias(); 8576 dfmt->setCurrency(USD); 8577 UnicodeString result; 8578 8579 // This line should be a no-op. I am setting the positive prefix 8580 // to be the same thing it was before. 8581 dfmt->setPositivePrefix(dfmt->getPositivePrefix(result)); 8582 8583 UnicodeString appendTo; 8584 assertEquals("", "$3.78", dfmt->format(3.78, appendTo, status)); 8585 assertSuccess("", status); 8586 } 8587 { 8588 const UChar USD[] = {0x55, 0x53, 0x44, 0x0}; 8589 UErrorCode status = U_ZERO_ERROR; 8590 LocalPointer<NumberFormat> fmt( 8591 NumberFormat::createInstance("en", UNUM_CURRENCY_PLURAL, status)); 8592 if (!assertSuccess("", status)) { 8593 return; 8594 } 8595 DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias(); 8596 UnicodeString result; 8597 UnicodeString tripleIntlCurrency(" \\u00a4\\u00a4\\u00a4"); 8598 tripleIntlCurrency = tripleIntlCurrency.unescape(); 8599 assertEquals("", tripleIntlCurrency, dfmt->getPositiveSuffix(result)); 8600 dfmt->setCurrency(USD); 8601 8602 // getPositiveSuffix() always returns the suffix for the 8603 // "other" plural category 8604 assertEquals("", " US dollars", dfmt->getPositiveSuffix(result)); 8605 UnicodeString appendTo; 8606 assertEquals("", "3.78 US dollars", dfmt->format(3.78, appendTo, status)); 8607 assertEquals("", " US dollars", dfmt->getPositiveSuffix(result)); 8608 dfmt->setPositiveSuffix("booya"); 8609 appendTo.remove(); 8610 assertEquals("", "3.78booya", dfmt->format(3.78, appendTo, status)); 8611 assertEquals("", "booya", dfmt->getPositiveSuffix(result)); 8612 } 8613 } 8614 8615 void NumberFormatTest::Test11475_signRecognition() { 8616 UErrorCode status = U_ZERO_ERROR; 8617 DecimalFormatSymbols sym("en", status); 8618 UnicodeString result; 8619 { 8620 DecimalFormat fmt("+0.00", sym, status); 8621 if (!assertSuccess("", status)) { 8622 return; 8623 } 8624 NumberFormatTest_Attributes attributes[] = { 8625 {UNUM_SIGN_FIELD, 0, 1}, 8626 {UNUM_INTEGER_FIELD, 1, 2}, 8627 {UNUM_DECIMAL_SEPARATOR_FIELD, 2, 3}, 8628 {UNUM_FRACTION_FIELD, 3, 5}, 8629 {0, -1, 0}}; 8630 UnicodeString result; 8631 FieldPositionIterator iter; 8632 fmt.format(2.3, result, &iter, status); 8633 assertEquals("", "+2.30", result); 8634 verifyFieldPositionIterator(attributes, iter); 8635 } 8636 { 8637 DecimalFormat fmt("++0.00+;-(#)--", sym, status); 8638 if (!assertSuccess("", status)) { 8639 return; 8640 } 8641 { 8642 NumberFormatTest_Attributes attributes[] = { 8643 {UNUM_SIGN_FIELD, 0, 2}, 8644 {UNUM_INTEGER_FIELD, 2, 3}, 8645 {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4}, 8646 {UNUM_FRACTION_FIELD, 4, 6}, 8647 {UNUM_SIGN_FIELD, 6, 7}, 8648 {0, -1, 0}}; 8649 UnicodeString result; 8650 FieldPositionIterator iter; 8651 fmt.format(2.3, result, &iter, status); 8652 assertEquals("", "++2.30+", result); 8653 verifyFieldPositionIterator(attributes, iter); 8654 } 8655 { 8656 NumberFormatTest_Attributes attributes[] = { 8657 {UNUM_SIGN_FIELD, 0, 1}, 8658 {UNUM_INTEGER_FIELD, 2, 3}, 8659 {UNUM_DECIMAL_SEPARATOR_FIELD, 3, 4}, 8660 {UNUM_FRACTION_FIELD, 4, 6}, 8661 {UNUM_SIGN_FIELD, 7, 9}, 8662 {0, -1, 0}}; 8663 UnicodeString result; 8664 FieldPositionIterator iter; 8665 fmt.format(-2.3, result, &iter, status); 8666 assertEquals("", "-(2.30)--", result); 8667 verifyFieldPositionIterator(attributes, iter); 8668 } 8669 } 8670 } 8671 8672 void NumberFormatTest::Test11640_getAffixes() { 8673 UErrorCode status = U_ZERO_ERROR; 8674 DecimalFormatSymbols symbols("en_US", status); 8675 if (!assertSuccess("", status)) { 8676 return; 8677 } 8678 UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4"); 8679 pattern = pattern.unescape(); 8680 DecimalFormat fmt(pattern, symbols, status); 8681 if (!assertSuccess("", status)) { 8682 return; 8683 } 8684 UnicodeString affixStr; 8685 assertEquals("", "US dollars ", fmt.getPositivePrefix(affixStr)); 8686 assertEquals("", " %USD", fmt.getPositiveSuffix(affixStr)); 8687 assertEquals("", "-US dollars ", fmt.getNegativePrefix(affixStr)); 8688 assertEquals("", " %USD", fmt.getNegativeSuffix(affixStr)); 8689 } 8690 8691 void NumberFormatTest::Test11649_toPatternWithMultiCurrency() { 8692 UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00"); 8693 pattern = pattern.unescape(); 8694 UErrorCode status = U_ZERO_ERROR; 8695 DecimalFormat fmt(pattern, status); 8696 if (!assertSuccess("", status)) { 8697 return; 8698 } 8699 static UChar USD[] = {0x55, 0x53, 0x44, 0x0}; 8700 fmt.setCurrency(USD); 8701 UnicodeString appendTo; 8702 8703 assertEquals("", "US dollars 12.34", fmt.format(12.34, appendTo)); 8704 8705 UnicodeString topattern; 8706 fmt.toPattern(topattern); 8707 DecimalFormat fmt2(topattern, status); 8708 if (!assertSuccess("", status)) { 8709 return; 8710 } 8711 fmt2.setCurrency(USD); 8712 8713 appendTo.remove(); 8714 assertEquals("", "US dollars 12.34", fmt2.format(12.34, appendTo)); 8715 } 8716 8717 8718 void NumberFormatTest::verifyFieldPositionIterator( 8719 NumberFormatTest_Attributes *expected, FieldPositionIterator &iter) { 8720 int32_t idx = 0; 8721 FieldPosition fp; 8722 while (iter.next(fp)) { 8723 if (expected[idx].spos == -1) { 8724 errln("Iterator should have ended. got %d", fp.getField()); 8725 return; 8726 } 8727 assertEquals("id", expected[idx].id, fp.getField()); 8728 assertEquals("start", expected[idx].spos, fp.getBeginIndex()); 8729 assertEquals("end", expected[idx].epos, fp.getEndIndex()); 8730 ++idx; 8731 } 8732 if (expected[idx].spos != -1) { 8733 errln("Premature end of iterator. expected %d", expected[idx].id); 8734 } 8735 } 8736 8737 8738 8739 #endif /* #if !UCONFIG_NO_FORMATTING */ 8740