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