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