"Fossies" - the Fresh Open Source Software Archive

Member "icu/source/test/intltest/numfmtst.cpp" (22 Apr 2020, 375949 Bytes) of package /linux/misc/icu4c-67_1-src.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes reports for "numfmtst.cpp": 67rc_vs_67_1 or 66_1_vs_67_1.

    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/currpinf.h"
   19 #include "unicode/dcfmtsym.h"
   20 #include "unicode/decimfmt.h"
   21 #include "unicode/localpointer.h"
   22 #include "unicode/ucurr.h"
   23 #include "unicode/ustring.h"
   24 #include "unicode/measfmt.h"
   25 #include "unicode/curramt.h"
   26 #include "unicode/strenum.h"
   27 #include "textfile.h"
   28 #include "tokiter.h"
   29 #include "charstr.h"
   30 #include "cstr.h"
   31 #include "putilimp.h"
   32 #include "winnmtst.h"
   33 #include <cmath>
   34 #include <float.h>
   35 #include <string.h>
   36 #include <stdlib.h>
   37 #include "cmemory.h"
   38 #include "cstring.h"
   39 #include "unicode/numsys.h"
   40 #include "fmtableimp.h"
   41 #include "numberformattesttuple.h"
   42 #include "unicode/msgfmt.h"
   43 #include "number_decimalquantity.h"
   44 #include "unicode/numberformatter.h"
   45 
   46 #if (U_PLATFORM == U_PF_AIX) || (U_PLATFORM == U_PF_OS390)
   47 // These should not be macros. If they are,
   48 // replace them with std::isnan and std::isinf
   49 #if defined(isnan)
   50 #undef isnan
   51 namespace std {
   52  bool isnan(double x) {
   53    return _isnan(x);
   54  }
   55 }
   56 #endif
   57 #if defined(isinf)
   58 #undef isinf
   59 namespace std {
   60  bool isinf(double x) {
   61    return _isinf(x);
   62  }
   63 }
   64 #endif
   65 #endif
   66 
   67 using icu::number::impl::DecimalQuantity;
   68 using namespace icu::number;
   69 
   70 //#define NUMFMTST_CACHE_DEBUG 1
   71 #include "stdio.h" /* for sprintf */
   72 // #include "iostream"   // for cout
   73 
   74 //#define NUMFMTST_DEBUG 1
   75 
   76 static const UChar EUR[] = {69,85,82,0}; // "EUR"
   77 static const UChar ISO_CURRENCY_USD[] = {0x55, 0x53, 0x44, 0}; // "USD"
   78 
   79 
   80 // *****************************************************************************
   81 // class NumberFormatTest
   82 // *****************************************************************************
   83 
   84 #define CHECK(status,str) UPRV_BLOCK_MACRO_BEGIN { \
   85     if (U_FAILURE(status)) { \
   86         errcheckln(status, UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); \
   87         return; \
   88     } \
   89 } UPRV_BLOCK_MACRO_END
   90 #define CHECK_DATA(status,str) UPRV_BLOCK_MACRO_BEGIN { \
   91     if (U_FAILURE(status)) { \
   92         dataerrln(UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); \
   93         return; \
   94     } \
   95 } UPRV_BLOCK_MACRO_END
   96 
   97 void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
   98 {
   99   TESTCASE_AUTO_BEGIN;
  100   TESTCASE_AUTO(TestCurrencySign);
  101   TESTCASE_AUTO(TestCurrency);
  102   TESTCASE_AUTO(TestParse);
  103   TESTCASE_AUTO(TestRounding487);
  104   TESTCASE_AUTO(TestQuotes);
  105   TESTCASE_AUTO(TestExponential);
  106   TESTCASE_AUTO(TestPatterns);
  107   TESTCASE_AUTO(Test20186_SpacesAroundSemicolon);
  108 
  109   // Upgrade to alphaWorks - liu 5/99
  110   TESTCASE_AUTO(TestExponent);
  111   TESTCASE_AUTO(TestScientific);
  112   TESTCASE_AUTO(TestPad);
  113   TESTCASE_AUTO(TestPatterns2);
  114   TESTCASE_AUTO(TestSecondaryGrouping);
  115   TESTCASE_AUTO(TestSurrogateSupport);
  116   TESTCASE_AUTO(TestAPI);
  117 
  118   TESTCASE_AUTO(TestCurrencyObject);
  119   TESTCASE_AUTO(TestCurrencyPatterns);
  120   //TESTCASE_AUTO(TestDigitList);
  121   TESTCASE_AUTO(TestWhiteSpaceParsing);
  122   TESTCASE_AUTO(TestComplexCurrency);  // This test removed because CLDR no longer uses choice formats in currency symbols.
  123   TESTCASE_AUTO(TestRegCurrency);
  124   TESTCASE_AUTO(TestSymbolsWithBadLocale);
  125   TESTCASE_AUTO(TestAdoptDecimalFormatSymbols);
  126 
  127   TESTCASE_AUTO(TestScientific2);
  128   TESTCASE_AUTO(TestScientificGrouping);
  129   TESTCASE_AUTO(TestInt64);
  130 
  131   TESTCASE_AUTO(TestPerMill);
  132   TESTCASE_AUTO(TestIllegalPatterns);
  133   TESTCASE_AUTO(TestCases);
  134 
  135   TESTCASE_AUTO(TestCurrencyNames);
  136   TESTCASE_AUTO(Test20484_NarrowSymbolFallback);
  137   TESTCASE_AUTO(TestCurrencyAmount);
  138   TESTCASE_AUTO(TestCurrencyUnit);
  139   TESTCASE_AUTO(TestCoverage);
  140   TESTCASE_AUTO(TestLocalizedPatternSymbolCoverage);
  141   TESTCASE_AUTO(TestJB3832);
  142   TESTCASE_AUTO(TestHost);
  143   TESTCASE_AUTO(TestHostClone);
  144   TESTCASE_AUTO(TestCurrencyFormat);
  145   TESTCASE_AUTO(TestRounding);
  146   TESTCASE_AUTO(TestNonpositiveMultiplier);
  147   TESTCASE_AUTO(TestNumberingSystems);
  148   TESTCASE_AUTO(TestSpaceParsing);
  149   TESTCASE_AUTO(TestMultiCurrencySign);
  150   TESTCASE_AUTO(TestCurrencyFormatForMixParsing);
  151   TESTCASE_AUTO(TestMismatchedCurrencyFormatFail);
  152   TESTCASE_AUTO(TestDecimalFormatCurrencyParse);
  153   TESTCASE_AUTO(TestCurrencyIsoPluralFormat);
  154   TESTCASE_AUTO(TestCurrencyParsing);
  155   TESTCASE_AUTO(TestParseCurrencyInUCurr);
  156   TESTCASE_AUTO(TestFormatAttributes);
  157   TESTCASE_AUTO(TestFieldPositionIterator);
  158   TESTCASE_AUTO(TestDecimal);
  159   TESTCASE_AUTO(TestCurrencyFractionDigits);
  160   TESTCASE_AUTO(TestExponentParse);
  161   TESTCASE_AUTO(TestExplicitParents);
  162   TESTCASE_AUTO(TestLenientParse);
  163   TESTCASE_AUTO(TestAvailableNumberingSystems);
  164   TESTCASE_AUTO(TestRoundingPattern);
  165   TESTCASE_AUTO(Test9087);
  166   TESTCASE_AUTO(TestFormatFastpaths);
  167   TESTCASE_AUTO(TestFormattableSize);
  168   TESTCASE_AUTO(TestUFormattable);
  169   TESTCASE_AUTO(TestSignificantDigits);
  170   TESTCASE_AUTO(TestShowZero);
  171   TESTCASE_AUTO(TestCompatibleCurrencies);
  172   TESTCASE_AUTO(TestBug9936);
  173   TESTCASE_AUTO(TestParseNegativeWithFaLocale);
  174   TESTCASE_AUTO(TestParseNegativeWithAlternateMinusSign);
  175   TESTCASE_AUTO(TestCustomCurrencySignAndSeparator);
  176   TESTCASE_AUTO(TestParseSignsAndMarks);
  177   TESTCASE_AUTO(Test10419RoundingWith0FractionDigits);
  178   TESTCASE_AUTO(Test10468ApplyPattern);
  179   TESTCASE_AUTO(TestRoundingScientific10542);
  180   TESTCASE_AUTO(TestZeroScientific10547);
  181   TESTCASE_AUTO(TestAccountingCurrency);
  182   TESTCASE_AUTO(TestCurrencyFormatForMissingLocale);
  183   TESTCASE_AUTO(TestEquality);
  184   TESTCASE_AUTO(TestCurrencyUsage);
  185   TESTCASE_AUTO(TestDoubleLimit11439);
  186   TESTCASE_AUTO(TestGetAffixes);
  187   TESTCASE_AUTO(TestToPatternScientific11648);
  188   TESTCASE_AUTO(TestBenchmark);
  189   TESTCASE_AUTO(TestCtorApplyPatternDifference);
  190   TESTCASE_AUTO(TestFractionalDigitsForCurrency);
  191   TESTCASE_AUTO(TestFormatCurrencyPlural);
  192   TESTCASE_AUTO(Test11868);
  193   TESTCASE_AUTO(Test11739_ParseLongCurrency);
  194   TESTCASE_AUTO(Test13035_MultiCodePointPaddingInPattern);
  195   TESTCASE_AUTO(Test13737_ParseScientificStrict);
  196   TESTCASE_AUTO(Test10727_RoundingZero);
  197   TESTCASE_AUTO(Test11376_getAndSetPositivePrefix);
  198   TESTCASE_AUTO(Test11475_signRecognition);
  199   TESTCASE_AUTO(Test11640_getAffixes);
  200   TESTCASE_AUTO(Test11649_toPatternWithMultiCurrency);
  201   TESTCASE_AUTO(Test13327_numberingSystemBufferOverflow);
  202   TESTCASE_AUTO(Test13391_chakmaParsing);
  203   TESTCASE_AUTO(Test11735_ExceptionIssue);
  204   TESTCASE_AUTO(Test11035_FormatCurrencyAmount);
  205   TESTCASE_AUTO(Test11318_DoubleConversion);
  206   TESTCASE_AUTO(TestParsePercentRegression);
  207   TESTCASE_AUTO(TestMultiplierWithScale);
  208   TESTCASE_AUTO(TestFastFormatInt32);
  209   TESTCASE_AUTO(Test11646_Equality);
  210   TESTCASE_AUTO(TestParseNaN);
  211   TESTCASE_AUTO(TestFormatFailIfMoreThanMaxDigits);
  212   TESTCASE_AUTO(TestParseCaseSensitive);
  213   TESTCASE_AUTO(TestParseNoExponent);
  214   TESTCASE_AUTO(TestSignAlwaysShown);
  215   TESTCASE_AUTO(TestMinimumGroupingDigits);
  216   TESTCASE_AUTO(Test11897_LocalizedPatternSeparator);
  217   TESTCASE_AUTO(Test13055_PercentageRounding);
  218   TESTCASE_AUTO(Test11839);
  219   TESTCASE_AUTO(Test10354);
  220   TESTCASE_AUTO(Test11645_ApplyPatternEquality);
  221   TESTCASE_AUTO(Test12567);
  222   TESTCASE_AUTO(Test11626_CustomizeCurrencyPluralInfo);
  223   TESTCASE_AUTO(Test20073_StrictPercentParseErrorIndex);
  224   TESTCASE_AUTO(Test13056_GroupingSize);
  225   TESTCASE_AUTO(Test11025_CurrencyPadding);
  226   TESTCASE_AUTO(Test11648_ExpDecFormatMalPattern);
  227   TESTCASE_AUTO(Test11649_DecFmtCurrencies);
  228   TESTCASE_AUTO(Test13148_ParseGroupingSeparators);
  229   TESTCASE_AUTO(Test12753_PatternDecimalPoint);
  230   TESTCASE_AUTO(Test11647_PatternCurrencySymbols);
  231   TESTCASE_AUTO(Test11913_BigDecimal);
  232   TESTCASE_AUTO(Test11020_RoundingInScientificNotation);
  233   TESTCASE_AUTO(Test11640_TripleCurrencySymbol);
  234   TESTCASE_AUTO(Test13763_FieldPositionIteratorOffset);
  235   TESTCASE_AUTO(Test13777_ParseLongNameNonCurrencyMode);
  236   TESTCASE_AUTO(Test13804_EmptyStringsWhenParsing);
  237   TESTCASE_AUTO(Test20037_ScientificIntegerOverflow);
  238   TESTCASE_AUTO(Test13840_ParseLongStringCrash);
  239   TESTCASE_AUTO(Test13850_EmptyStringCurrency);
  240   TESTCASE_AUTO(Test20348_CurrencyPrefixOverride);
  241   TESTCASE_AUTO(Test20956_MonetarySymbolGetters);
  242   TESTCASE_AUTO(Test20358_GroupingInPattern);
  243   TESTCASE_AUTO(Test13731_DefaultCurrency);
  244   TESTCASE_AUTO(Test20499_CurrencyVisibleDigitsPlural);
  245   TESTCASE_AUTO(Test13735_GroupingSizeGetter);
  246   TESTCASE_AUTO(Test13734_StrictFlexibleWhitespace);
  247   TESTCASE_AUTO(Test20961_CurrencyPluralPattern);
  248   TESTCASE_AUTO_END;
  249 }
  250 
  251 // -------------------------------------
  252 
  253 // Test API (increase code coverage)
  254 void
  255 NumberFormatTest::TestAPI(void)
  256 {
  257   logln("Test API");
  258   UErrorCode status = U_ZERO_ERROR;
  259   NumberFormat *test = NumberFormat::createInstance("root", status);
  260   if(U_FAILURE(status)) {
  261     dataerrln("unable to create format object - %s", u_errorName(status));
  262   }
  263   if(test != NULL) {
  264     test->setMinimumIntegerDigits(10);
  265     test->setMaximumIntegerDigits(1);
  266 
  267     test->setMinimumFractionDigits(10);
  268     test->setMaximumFractionDigits(1);
  269 
  270     UnicodeString result;
  271     FieldPosition pos;
  272     Formattable bla("Paja Patak"); // Donald Duck for non Serbian speakers
  273     test->format(bla, result, pos, status);
  274     if(U_SUCCESS(status)) {
  275       errln("Yuck... Formatted a duck... As a number!");
  276     } else {
  277       status = U_ZERO_ERROR;
  278     }
  279 
  280     result.remove();
  281     int64_t ll = 12;
  282     test->format(ll, result);
  283     assertEquals("format int64_t error", u"2.0", result);
  284 
  285     test->setMinimumIntegerDigits(4);
  286     test->setMinimumFractionDigits(4);
  287 
  288     result.remove();
  289     test->format(ll, result);
  290     assertEquals("format int64_t error", u"0,012.0000", result);
  291 
  292     ParsePosition ppos;
  293     LocalPointer<CurrencyAmount> currAmt(test->parseCurrency("",ppos));
  294     // old test for (U_FAILURE(status)) was bogus here, method does not set status!
  295     if (ppos.getIndex()) {
  296         errln("Parsed empty string as currency");
  297     }
  298 
  299     delete test;
  300   }
  301 }
  302 
  303 class StubNumberFormat :public NumberFormat{
  304 public:
  305     StubNumberFormat(){}
  306     virtual UnicodeString& format(double ,UnicodeString& appendTo,FieldPosition& ) const {
  307         return appendTo;
  308     }
  309     virtual UnicodeString& format(int32_t ,UnicodeString& appendTo,FieldPosition& ) const {
  310         return appendTo.append((UChar)0x0033);
  311     }
  312     virtual UnicodeString& format(int64_t number,UnicodeString& appendTo,FieldPosition& pos) const {
  313         return NumberFormat::format(number, appendTo, pos);
  314     }
  315     virtual UnicodeString& format(const Formattable& , UnicodeString& appendTo, FieldPosition& , UErrorCode& ) const {
  316         return appendTo;
  317     }
  318     virtual void parse(const UnicodeString& ,
  319                     Formattable& ,
  320                     ParsePosition& ) const {}
  321     virtual void parse( const UnicodeString& ,
  322                         Formattable& ,
  323                         UErrorCode& ) const {}
  324     virtual UClassID getDynamicClassID(void) const {
  325         static char classID = 0;
  326         return (UClassID)&classID;
  327     }
  328     virtual StubNumberFormat* clone() const {return NULL;}
  329 };
  330 
  331 void
  332 NumberFormatTest::TestCoverage(void){
  333     StubNumberFormat stub;
  334     UnicodeString agent("agent");
  335     FieldPosition pos;
  336     int64_t num = 4;
  337     if (stub.format(num, agent, pos) != UnicodeString("agent3")){
  338         errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)");
  339     }
  340 }
  341 
  342 void NumberFormatTest::TestLocalizedPatternSymbolCoverage() {
  343     IcuTestErrorCode errorCode(*this, "TestLocalizedPatternSymbolCoverage");
  344     // Ticket #12961: DecimalFormat::toLocalizedPattern() is not working as designed.
  345     DecimalFormatSymbols dfs(errorCode);
  346     dfs.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, u'⁖');
  347     dfs.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u'⁘');
  348     dfs.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, u'⁙');
  349     dfs.setSymbol(DecimalFormatSymbols::kDigitSymbol, u'▰');
  350     dfs.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, u'໐');
  351     dfs.setSymbol(DecimalFormatSymbols::kSignificantDigitSymbol, u'⁕');
  352     dfs.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, u'†');
  353     dfs.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, u'‡');
  354     dfs.setSymbol(DecimalFormatSymbols::kPercentSymbol, u'⁜');
  355     dfs.setSymbol(DecimalFormatSymbols::kPerMillSymbol, u'‱');
  356     dfs.setSymbol(DecimalFormatSymbols::kExponentialSymbol, u"⁑⁑"); // tests multi-char sequence
  357     dfs.setSymbol(DecimalFormatSymbols::kPadEscapeSymbol, u'⁂');
  358 
  359     {
  360         UnicodeString standardPattern(u"#,##0.05+%;#,##0.05-%");
  361         UnicodeString localizedPattern(u"▰⁖▰▰໐⁘໐໕†⁜⁙▰⁖▰▰໐⁘໐໕‡⁜");
  362 
  363         DecimalFormat df1("#", new DecimalFormatSymbols(dfs), errorCode);
  364         df1.applyPattern(standardPattern, errorCode);
  365         DecimalFormat df2("#", new DecimalFormatSymbols(dfs), errorCode);
  366         df2.applyLocalizedPattern(localizedPattern, errorCode);
  367         assertTrue("DecimalFormat instances should be equal", df1 == df2);
  368         UnicodeString p2;
  369         assertEquals("toPattern should match on localizedPattern instance",
  370                 standardPattern, df2.toPattern(p2));
  371         UnicodeString lp1;
  372         assertEquals("toLocalizedPattern should match on standardPattern instance",
  373                 localizedPattern, df1.toLocalizedPattern(lp1));
  374     }
  375 
  376     {
  377         UnicodeString standardPattern(u"* @@@E0‰");
  378         UnicodeString localizedPattern(u"⁂ ⁕⁕⁕⁑⁑໐‱");
  379 
  380         DecimalFormat df1("#", new DecimalFormatSymbols(dfs), errorCode);
  381         df1.applyPattern(standardPattern, errorCode);
  382         DecimalFormat df2("#", new DecimalFormatSymbols(dfs), errorCode);
  383         df2.applyLocalizedPattern(localizedPattern, errorCode);
  384         assertTrue("DecimalFormat instances should be equal", df1 == df2);
  385         UnicodeString p2;
  386         assertEquals("toPattern should match on localizedPattern instance",
  387                 standardPattern, df2.toPattern(p2));
  388         UnicodeString lp1;
  389         assertEquals("toLocalizedPattern should match on standardPattern instance",
  390                 localizedPattern, df1.toLocalizedPattern(lp1));
  391     }
  392 }
  393 
  394 // Test various patterns
  395 void
  396 NumberFormatTest::TestPatterns(void)
  397 {
  398     UErrorCode status = U_ZERO_ERROR;
  399     DecimalFormatSymbols sym(Locale::getUS(), status);
  400     if (U_FAILURE(status)) { errcheckln(status, "FAIL: Could not construct DecimalFormatSymbols - %s", u_errorName(status)); return; }
  401 
  402     const char* pat[]    = { "#.#", "#.", ".#", "#" };
  403     int32_t pat_length = UPRV_LENGTHOF(pat);
  404     const char* newpat[] = { "0.#", "0.", "#.0", "0" };
  405     const char* num[]    = { "0",   "0.", ".0", "0" };
  406     for (int32_t i=0; i<pat_length; ++i)
  407     {
  408         status = U_ZERO_ERROR;
  409         DecimalFormat fmt(pat[i], sym, status);
  410         if (U_FAILURE(status)) { errln((UnicodeString)"FAIL: DecimalFormat constructor failed for " + pat[i]); continue; }
  411         UnicodeString newp; fmt.toPattern(newp);
  412         if (!(newp == newpat[i]))
  413             errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] +
  414                   "; " + newp + " seen instead");
  415 
  416         UnicodeString s; (*(NumberFormat*)&fmt).format((int32_t)0, s);
  417         if (!(s == num[i]))
  418         {
  419             errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should format zero as " + num[i] +
  420                   "; " + s + " seen instead");
  421             logln((UnicodeString)"Min integer digits = " + fmt.getMinimumIntegerDigits());
  422         }
  423     }
  424 }
  425 
  426 void NumberFormatTest::Test20186_SpacesAroundSemicolon() {
  427     IcuTestErrorCode status(*this, "Test20186_SpacesAroundSemicolon");
  428     DecimalFormat df(u"0.00 ; -0.00", {"en-us", status}, status);
  429     expect2(df, 1, u"1.00 ");
  430     expect2(df, -1, u" -1.00");
  431 
  432     df = DecimalFormat(u"0.00;", {"en-us", status}, status);
  433     expect2(df, 1, u"1.00");
  434     expect2(df, -1, u"-1.00");
  435 
  436     df = DecimalFormat(u"0.00;0.00", {"en-us", status}, status);
  437     expect2(df, 1, u"1.00");
  438     expect(df, -1, u"1.00");  // parses as 1, not -1
  439 
  440     df = DecimalFormat(u" 0.00 ; -0.00 ", {"en-us", status}, status);
  441     expect2(df, 1, u" 1.00 ");
  442     expect2(df, -1, u" -1.00 ");
  443 }
  444 
  445 /*
  446 icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
  447 icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
  448 icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
  449 */
  450 /*
  451 void
  452 NumberFormatTest::TestDigitList(void)
  453 {
  454   // API coverage for DigitList
  455   DigitList list1;
  456   list1.append('1');
  457   list1.fDecimalAt = 1;
  458   DigitList list2;
  459   list2.set((int32_t)1);
  460   if (list1 != list2) {
  461     errln("digitlist append, operator!= or set failed ");
  462   }
  463   if (!(list1 == list2)) {
  464     errln("digitlist append, operator== or set failed ");
  465   }
  466 }
  467 */
  468 
  469 // -------------------------------------
  470 
  471 // Test exponential pattern
  472 void
  473 NumberFormatTest::TestExponential(void)
  474 {
  475     UErrorCode status = U_ZERO_ERROR;
  476     DecimalFormatSymbols sym(Locale::getUS(), status);
  477     if (U_FAILURE(status)) { errcheckln(status, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status)); return; }
  478     const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]"  };
  479     int32_t pat_length = UPRV_LENGTHOF(pat);
  480 
  481 // The following #if statements allow this test to be built and run on
  482 // platforms that do not have standard IEEE numerics.  For example,
  483 // S/390 doubles have an exponent range of -78 to +75.  For the
  484 // following #if statements to work, float.h must define
  485 // DBL_MAX_10_EXP to be a compile-time constant.
  486 
  487 // This section may be expanded as needed.
  488 
  489 #if DBL_MAX_10_EXP > 300
  490     double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
  491     int32_t val_length = UPRV_LENGTHOF(val);
  492     const char* valFormat[] =
  493     {
  494         // 0.####E0
  495         "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
  496         // 00.000E00
  497         "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
  498         // ##0.######E000
  499         "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
  500         // 0.###E0;[0.###E0]
  501         "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
  502     };
  503     double valParse[] =
  504     {
  505         0.01234, 123460000, 1.23E300, -3.1416E-271,
  506         0.01234, 123460000, 1.23E300, -3.1416E-271,
  507         0.01234, 123456800, 1.23E300, -3.141593E-271,
  508         0.01234, 123500000, 1.23E300, -3.142E-271,
  509     };
  510 #elif DBL_MAX_10_EXP > 70
  511     double val[] = { 0.01234, 123456789, 1.23e70, -3.141592653e-71 };
  512     int32_t val_length = UPRV_LENGTHOF(val);
  513     char* valFormat[] =
  514     {
  515         // 0.####E0
  516         "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
  517         // 00.000E00
  518         "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
  519         // ##0.######E000
  520         "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
  521         // 0.###E0;[0.###E0]
  522         "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
  523     };
  524     double valParse[] =
  525     {
  526         0.01234, 123460000, 1.23E70, -3.1416E-71,
  527         0.01234, 123460000, 1.23E70, -3.1416E-71,
  528         0.01234, 123456800, 1.23E70, -3.141593E-71,
  529         0.01234, 123500000, 1.23E70, -3.142E-71,
  530     };
  531 #else
  532     // Don't test double conversion
  533     double* val = 0;
  534     int32_t val_length = 0;
  535     char** valFormat = 0;
  536     double* valParse = 0;
  537     logln("Warning: Skipping double conversion tests");
  538 #endif
  539 
  540     int32_t lval[] = { 0, -1, 1, 123456789 };
  541     int32_t lval_length = UPRV_LENGTHOF(lval);
  542     const char* lvalFormat[] =
  543     {
  544         // 0.####E0
  545         "0E0", "-1E0", "1E0", "1.2346E8",
  546         // 00.000E00
  547         "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
  548         // ##0.######E000
  549         "0E000", "-1E000", "1E000", "123.4568E006",
  550         // 0.###E0;[0.###E0]
  551         "0E0", "[1E0]", "1E0", "1.235E8"
  552     };
  553     int32_t lvalParse[] =
  554     {
  555         0, -1, 1, 123460000,
  556         0, -1, 1, 123460000,
  557         0, -1, 1, 123456800,
  558         0, -1, 1, 123500000,
  559     };
  560     int32_t ival = 0, ilval = 0;
  561     for (int32_t p=0; p<pat_length; ++p)
  562     {
  563         DecimalFormat fmt(pat[p], sym, status);
  564         if (U_FAILURE(status)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
  565         UnicodeString pattern;
  566         logln((UnicodeString)"Pattern \"" + pat[p] + "\" -toPattern-> \"" +
  567           fmt.toPattern(pattern) + "\"");
  568         int32_t v;
  569         for (v=0; v<val_length; ++v)
  570         {
  571             UnicodeString s; (*(NumberFormat*)&fmt).format(val[v], s);
  572             logln((UnicodeString)" " + val[v] + " -format-> " + s);
  573             if (s != valFormat[v+ival])
  574                 errln((UnicodeString)"FAIL: Expected " + valFormat[v+ival]);
  575 
  576             ParsePosition pos(0);
  577             Formattable af;
  578             fmt.parse(s, af, pos);
  579             double a;
  580             UBool useEpsilon = FALSE;
  581             if (af.getType() == Formattable::kLong)
  582                 a = af.getLong();
  583             else if (af.getType() == Formattable::kDouble) {
  584                 a = af.getDouble();
  585 #if U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400
  586                 // S/390 will show a failure like this:
  587                 //| -3.141592652999999e-271 -format-> -3.1416E-271
  588                 //|                          -parse-> -3.1416e-271
  589                 //| FAIL: Expected -3.141599999999999e-271
  590                 // To compensate, we use an epsilon-based equality
  591                 // test on S/390 only.  We don't want to do this in
  592                 // general because it's less exacting.
  593                 useEpsilon = TRUE;
  594 #endif
  595             }
  596             else {
  597                 errln(UnicodeString("FAIL: Non-numeric Formattable returned: ") + pattern + " " + s);
  598                 continue;
  599             }
  600             if (pos.getIndex() == s.length())
  601             {
  602                 logln((UnicodeString)"  -parse-> " + a);
  603                 // Use epsilon comparison as necessary
  604                 if ((useEpsilon &&
  605                     (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) ||
  606                     (!useEpsilon && a != valParse[v+ival]))
  607                 {
  608                     errln((UnicodeString)"FAIL: Expected " + valParse[v+ival] + " but got " + a
  609                         + " on input " + s);
  610                 }
  611             }
  612             else {
  613                 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
  614                 errln((UnicodeString)"  should be (" + s.length() + " chars) -> " + valParse[v+ival]);
  615             }
  616         }
  617         for (v=0; v<lval_length; ++v)
  618         {
  619             UnicodeString s;
  620             (*(NumberFormat*)&fmt).format(lval[v], s);
  621             logln((UnicodeString)" " + lval[v] + "L -format-> " + s);
  622             if (s != lvalFormat[v+ilval])
  623                 errln((UnicodeString)"ERROR: Expected " + lvalFormat[v+ilval] + " Got: " + s);
  624 
  625             ParsePosition pos(0);
  626             Formattable af;
  627             fmt.parse(s, af, pos);
  628             if (af.getType() == Formattable::kLong ||
  629                 af.getType() == Formattable::kInt64) {
  630                 UErrorCode status = U_ZERO_ERROR;
  631                 int32_t a = af.getLong(status);
  632                 if (pos.getIndex() == s.length())
  633                 {
  634                     logln((UnicodeString)"  -parse-> " + a);
  635                     if (a != lvalParse[v+ilval])
  636                         errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval] + " but got " + a);
  637                 }
  638                 else
  639                     errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
  640             }
  641             else
  642                 errln((UnicodeString)"FAIL: Non-long Formattable returned for " + s
  643                     + " Double: " + af.getDouble()
  644                     + ", Long: " + af.getLong());
  645         }
  646         ival += val_length;
  647         ilval += lval_length;
  648     }
  649 }
  650 
  651 void
  652 NumberFormatTest::TestScientific2() {
  653     // jb 2552
  654     UErrorCode status = U_ZERO_ERROR;
  655     DecimalFormat* fmt = (DecimalFormat*)NumberFormat::createCurrencyInstance("en_US", status);
  656     if (U_SUCCESS(status)) {
  657         double num = 12.34;
  658         expect(*fmt, num, "$12.34");
  659         fmt->setScientificNotation(TRUE);
  660         expect(*fmt, num, "$1.23E1");
  661         fmt->setScientificNotation(FALSE);
  662         expect(*fmt, num, "$12.34");
  663     }
  664     delete fmt;
  665 }
  666 
  667 void
  668 NumberFormatTest::TestScientificGrouping() {
  669     // jb 2552
  670     UErrorCode status = U_ZERO_ERROR;
  671     DecimalFormat fmt("##0.00E0",status);
  672     if (assertSuccess("", status, true, __FILE__, __LINE__)) {
  673         expect(fmt, .01234, "12.3E-3");
  674         expect(fmt, .1234, "123E-3");
  675         expect(fmt, 1.234, "1.23E0");
  676         expect(fmt, 12.34, "12.3E0");
  677         expect(fmt, 123.4, "123E0");
  678         expect(fmt, 1234., "1.23E3");
  679     }
  680 }
  681 
  682 /*static void setFromString(DigitList& dl, const char* str) {
  683     char c;
  684     UBool decimalSet = FALSE;
  685     dl.clear();
  686     while ((c = *str++)) {
  687         if (c == '-') {
  688             dl.fIsPositive = FALSE;
  689         } else if (c == '+') {
  690             dl.fIsPositive = TRUE;
  691         } else if (c == '.') {
  692             dl.fDecimalAt = dl.fCount;
  693             decimalSet = TRUE;
  694         } else {
  695             dl.append(c);
  696         }
  697     }
  698     if (!decimalSet) {
  699         dl.fDecimalAt = dl.fCount;
  700     }
  701 }*/
  702 
  703 void
  704 NumberFormatTest::TestInt64() {
  705     UErrorCode status = U_ZERO_ERROR;
  706     DecimalFormat fmt("#.#E0",status);
  707     if (U_FAILURE(status)) {
  708         dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
  709         return;
  710     }
  711     fmt.setMaximumFractionDigits(20);
  712     if (U_SUCCESS(status)) {
  713         expect(fmt, (Formattable)(int64_t)0, "0E0");
  714         expect(fmt, (Formattable)(int64_t)-1, "-1E0");
  715         expect(fmt, (Formattable)(int64_t)1, "1E0");
  716         expect(fmt, (Formattable)(int64_t)2147483647, "2.147483647E9");
  717         expect(fmt, (Formattable)((int64_t)-2147483647-1), "-2.147483648E9");
  718         expect(fmt, (Formattable)(int64_t)U_INT64_MAX, "9.223372036854775807E18");
  719         expect(fmt, (Formattable)(int64_t)U_INT64_MIN, "-9.223372036854775808E18");
  720     }
  721 
  722     // also test digitlist
  723 /*    int64_t int64max = U_INT64_MAX;
  724     int64_t int64min = U_INT64_MIN;
  725     const char* int64maxstr = "9223372036854775807";
  726     const char* int64minstr = "-9223372036854775808";
  727     UnicodeString fail("fail: ");
  728 
  729     // test max int64 value
  730     DigitList dl;
  731     setFromString(dl, int64maxstr);
  732     {
  733         if (!dl.fitsIntoInt64(FALSE)) {
  734             errln(fail + int64maxstr + " didn't fit");
  735         }
  736         int64_t int64Value = dl.getInt64();
  737         if (int64Value != int64max) {
  738             errln(fail + int64maxstr);
  739         }
  740         dl.set(int64Value);
  741         int64Value = dl.getInt64();
  742         if (int64Value != int64max) {
  743             errln(fail + int64maxstr);
  744         }
  745     }
  746     // test negative of max int64 value (1 shy of min int64 value)
  747     dl.fIsPositive = FALSE;
  748     {
  749         if (!dl.fitsIntoInt64(FALSE)) {
  750             errln(fail + "-" + int64maxstr + " didn't fit");
  751         }
  752         int64_t int64Value = dl.getInt64();
  753         if (int64Value != -int64max) {
  754             errln(fail + "-" + int64maxstr);
  755         }
  756         dl.set(int64Value);
  757         int64Value = dl.getInt64();
  758         if (int64Value != -int64max) {
  759             errln(fail + "-" + int64maxstr);
  760         }
  761     }
  762     // test min int64 value
  763     setFromString(dl, int64minstr);
  764     {
  765         if (!dl.fitsIntoInt64(FALSE)) {
  766             errln(fail + "-" + int64minstr + " didn't fit");
  767         }
  768         int64_t int64Value = dl.getInt64();
  769         if (int64Value != int64min) {
  770             errln(fail + int64minstr);
  771         }
  772         dl.set(int64Value);
  773         int64Value = dl.getInt64();
  774         if (int64Value != int64min) {
  775             errln(fail + int64minstr);
  776         }
  777     }
  778     // test negative of min int 64 value (1 more than max int64 value)
  779     dl.fIsPositive = TRUE; // won't fit
  780     {
  781         if (dl.fitsIntoInt64(FALSE)) {
  782             errln(fail + "-(" + int64minstr + ") didn't fit");
  783         }
  784     }*/
  785 }
  786 
  787 // -------------------------------------
  788 
  789 // Test the handling of quotes
  790 void
  791 NumberFormatTest::TestQuotes(void)
  792 {
  793     UErrorCode status = U_ZERO_ERROR;
  794     UnicodeString *pat;
  795     DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), status);
  796     if (U_FAILURE(status)) {
  797         errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
  798         delete sym;
  799         return;
  800     }
  801     pat = new UnicodeString("a'fo''o'b#");
  802     DecimalFormat *fmt = new DecimalFormat(*pat, *sym, status);
  803     UnicodeString s;
  804     ((NumberFormat*)fmt)->format((int32_t)123, s);
  805     logln((UnicodeString)"Pattern \"" + *pat + "\"");
  806     logln((UnicodeString)" Format 123 -> " + escape(s));
  807     if (!(s=="afo'ob123"))
  808         errln((UnicodeString)"FAIL: Expected afo'ob123");
  809 
  810     s.truncate(0);
  811     delete fmt;
  812     delete pat;
  813 
  814     pat = new UnicodeString("a''b#");
  815     fmt = new DecimalFormat(*pat, *sym, status);
  816     ((NumberFormat*)fmt)->format((int32_t)123, s);
  817     logln((UnicodeString)"Pattern \"" + *pat + "\"");
  818     logln((UnicodeString)" Format 123 -> " + escape(s));
  819     if (!(s=="a'b123"))
  820         errln((UnicodeString)"FAIL: Expected a'b123");
  821     delete fmt;
  822     delete pat;
  823     delete sym;
  824 }
  825 
  826 /**
  827  * Test the handling of the currency symbol in patterns.
  828  */
  829 void
  830 NumberFormatTest::TestCurrencySign(void)
  831 {
  832     UErrorCode status = U_ZERO_ERROR;
  833     DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale::getUS(), status);
  834     UnicodeString pat;
  835     UChar currency = 0x00A4;
  836     if (U_FAILURE(status)) {
  837         errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
  838         delete sym;
  839         return;
  840     }
  841     // "\xA4#,##0.00;-\xA4#,##0.00"
  842     pat.append(currency).append("#,##0.00;-").
  843         append(currency).append("#,##0.00");
  844     DecimalFormat *fmt = new DecimalFormat(pat, *sym, status);
  845     UnicodeString s; ((NumberFormat*)fmt)->format(1234.56, s);
  846     pat.truncate(0);
  847     logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
  848     logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
  849     if (s != "$1,234.56") dataerrln((UnicodeString)"FAIL: Expected $1,234.56");
  850     s.truncate(0);
  851     ((NumberFormat*)fmt)->format(- 1234.56, s);
  852     logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
  853     if (s != "-$1,234.56") dataerrln((UnicodeString)"FAIL: Expected -$1,234.56");
  854     delete fmt;
  855     pat.truncate(0);
  856     // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
  857     pat.append(currency).append(currency).
  858         append(" #,##0.00;").
  859         append(currency).append(currency).
  860         append(" -#,##0.00");
  861     fmt = new DecimalFormat(pat, *sym, status);
  862     s.truncate(0);
  863     ((NumberFormat*)fmt)->format(1234.56, s);
  864     logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
  865     logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
  866     if (s != "USD 1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD 1,234.56");
  867     s.truncate(0);
  868     ((NumberFormat*)fmt)->format(-1234.56, s);
  869     logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
  870     if (s != "USD -1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD -1,234.56");
  871     delete fmt;
  872     delete sym;
  873     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + u_errorName(status));
  874 }
  875 
  876 // -------------------------------------
  877 
  878 static UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
  879 
  880 UnicodeString&
  881 NumberFormatTest::escape(UnicodeString& s)
  882 {
  883     UnicodeString buf;
  884     for (int32_t i=0; i<s.length(); ++i)
  885     {
  886         UChar c = s[(int32_t)i];
  887         if (c <= (UChar)0x7F) buf += c;
  888         else {
  889             buf += (UChar)0x5c; buf += (UChar)0x55;
  890             buf += toHexString((c & 0xF000) >> 12);
  891             buf += toHexString((c & 0x0F00) >> 8);
  892             buf += toHexString((c & 0x00F0) >> 4);
  893             buf += toHexString(c & 0x000F);
  894         }
  895     }
  896     return (s = buf);
  897 }
  898 
  899 
  900 // -------------------------------------
  901 static const char* testCases[][2]= {
  902      /* locale ID */  /* expected */
  903     {"ca_ES@currency=ESP", "\\u20A7\\u00A01.150" },
  904     {"de_LU@currency=LUF", "1,150\\u00A0F" },
  905     {"el_GR@currency=GRD", "1.150,50\\u00A0\\u0394\\u03C1\\u03C7" },
  906     {"en_BE@currency=BEF", "1.150,50\\u00A0BEF" },
  907     {"es_ES@currency=ESP", "1.150\\u00A0\\u20A7" },
  908     {"eu_ES@currency=ESP", "\\u20A7\\u00A01.150" },
  909     {"gl_ES@currency=ESP", "1.150\\u00A0\\u20A7" },
  910     {"it_IT@currency=ITL", "ITL\\u00A01.150" },
  911     {"pt_PT@currency=PTE", "1,150$50\\u00A0\\u200B"}, // per cldrbug 7670
  912     {"en_US@currency=JPY", "\\u00A51,150"},
  913     {"en_US@currency=jpy", "\\u00A51,150"},
  914     {"en-US-u-cu-jpy", "\\u00A51,150"}
  915 };
  916 /**
  917  * Test localized currency patterns.
  918  */
  919 void
  920 NumberFormatTest::TestCurrency(void)
  921 {
  922     UErrorCode status = U_ZERO_ERROR;
  923     NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
  924     if (U_FAILURE(status)) {
  925         dataerrln("Error calling NumberFormat::createCurrencyInstance()");
  926         return;
  927     }
  928 
  929     UnicodeString s; currencyFmt->format(1.50, s);
  930     logln((UnicodeString)"Un pauvre ici a..........." + s);
  931     if (!(s==CharsToUnicodeString("1,50\\u00A0$")))
  932         errln((UnicodeString)"FAIL: Expected 1,50<nbsp>$ but got " + s);
  933     delete currencyFmt;
  934     s.truncate(0);
  935     char loc[256]={0};
  936     int len = uloc_canonicalize("de_DE@currency=DEM", loc, 256, &status);
  937     (void)len;  // Suppress unused variable warning.
  938     currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc),status);
  939     currencyFmt->format(1.50, s);
  940     logln((UnicodeString)"Un pauvre en Allemagne a.." + s);
  941     if (!(s==CharsToUnicodeString("1,50\\u00A0DM")))
  942         errln((UnicodeString)"FAIL: Expected 1,50<nbsp>DM but got " + s);
  943     delete currencyFmt;
  944     s.truncate(0);
  945     len = uloc_canonicalize("fr_FR@currency=FRF", loc, 256, &status);
  946     currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
  947     currencyFmt->format(1.50, s);
  948     logln((UnicodeString)"Un pauvre en France a....." + s);
  949     if (!(s==CharsToUnicodeString("1,50\\u00A0F")))
  950         errln((UnicodeString)"FAIL: Expected 1,50<nbsp>F");
  951     delete currencyFmt;
  952     if (U_FAILURE(status))
  953         errln((UnicodeString)"FAIL: Status " + (int32_t)status);
  954 
  955     for(int i=0; i < UPRV_LENGTHOF(testCases); i++){
  956         status = U_ZERO_ERROR;
  957         const char *localeID = testCases[i][0];
  958         UnicodeString expected(testCases[i][1], -1, US_INV);
  959         expected = expected.unescape();
  960         s.truncate(0);
  961         char loc[256]={0};
  962         uloc_canonicalize(localeID, loc, 256, &status);
  963         currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
  964         if(U_FAILURE(status)){
  965             errln("Could not create currency formatter for locale %s",localeID);
  966             continue;
  967         }
  968         currencyFmt->format(1150.50, s);
  969         if(s!=expected){
  970             errln(UnicodeString("FAIL: Expected: ")+expected
  971                     + UnicodeString(" Got: ") + s
  972                     + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
  973         }
  974         if (U_FAILURE(status)){
  975             errln((UnicodeString)"FAIL: Status " + (int32_t)status);
  976         }
  977         delete currencyFmt;
  978     }
  979 }
  980 
  981 // -------------------------------------
  982 
  983 /**
  984  * Test the Currency object handling, new as of ICU 2.2.
  985  */
  986 void NumberFormatTest::TestCurrencyObject() {
  987     UErrorCode ec = U_ZERO_ERROR;
  988     NumberFormat* fmt =
  989         NumberFormat::createCurrencyInstance(Locale::getUS(), ec);
  990 
  991     if (U_FAILURE(ec)) {
  992         dataerrln("FAIL: getCurrencyInstance(US) - %s", u_errorName(ec));
  993         delete fmt;
  994         return;
  995     }
  996 
  997     Locale null("", "", "");
  998 
  999     expectCurrency(*fmt, null, 1234.56, "$1,234.56");
 1000 
 1001     expectCurrency(*fmt, Locale::getFrance(),
 1002                    1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
 1003 
 1004     expectCurrency(*fmt, Locale::getJapan(),
 1005                    1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
 1006 
 1007     expectCurrency(*fmt, Locale("fr", "CH", ""),
 1008                    1234.56, "CHF 1,234.56"); // no more 0.05 rounding here, see cldrbug 5548
 1009 
 1010     expectCurrency(*fmt, Locale::getUS(),
 1011                    1234.56, "$1,234.56");
 1012 
 1013     delete fmt;
 1014     fmt = NumberFormat::createCurrencyInstance(Locale::getFrance(), ec);
 1015 
 1016     if (U_FAILURE(ec)) {
 1017         errln("FAIL: getCurrencyInstance(FRANCE)");
 1018         delete fmt;
 1019         return;
 1020     }
 1021 
 1022     expectCurrency(*fmt, null, 1234.56, CharsToUnicodeString("1\\u202F234,56 \\u20AC"));
 1023 
 1024     expectCurrency(*fmt, Locale::getJapan(),
 1025                    1234.56, CharsToUnicodeString("1\\u202F235 JPY")); // Yen
 1026 
 1027     expectCurrency(*fmt, Locale("fr", "CH", ""),
 1028                    1234.56, CharsToUnicodeString("1\\u202F234,56 CHF")); // no more 0.05 rounding here, see cldrbug 5548
 1029 
 1030     expectCurrency(*fmt, Locale::getUS(),
 1031                    1234.56, CharsToUnicodeString("1\\u202F234,56 $US"));
 1032 
 1033     expectCurrency(*fmt, Locale::getFrance(),
 1034                    1234.56, CharsToUnicodeString("1\\u202F234,56 \\u20AC")); // Euro
 1035 
 1036     delete fmt;
 1037 }
 1038 
 1039 // -------------------------------------
 1040 
 1041 /**
 1042  * Do rudimentary testing of parsing.
 1043  */
 1044 void
 1045 NumberFormatTest::TestParse(void)
 1046 {
 1047     UErrorCode status = U_ZERO_ERROR;
 1048     UnicodeString arg("0");
 1049     DecimalFormat* format = new DecimalFormat("00", status);
 1050     //try {
 1051         Formattable n; format->parse(arg, n, status);
 1052         logln((UnicodeString)"parse(" + arg + ") = " + n.getLong());
 1053         if (n.getType() != Formattable::kLong ||
 1054             n.getLong() != 0) errln((UnicodeString)"FAIL: Expected 0");
 1055     delete format;
 1056     if (U_FAILURE(status)) errcheckln(status, (UnicodeString)"FAIL: Status " + u_errorName(status));
 1057     //}
 1058     //catch(Exception e) {
 1059     //    errln((UnicodeString)"Exception caught: " + e);
 1060     //}
 1061 }
 1062 
 1063 // -------------------------------------
 1064 
 1065 static const char *lenientAffixTestCases[] = {
 1066         "(1)",
 1067         "( 1)",
 1068         "(1 )",
 1069         "( 1 )"
 1070 };
 1071 
 1072 static const char *lenientMinusTestCases[] = {
 1073     "-5",
 1074     "\\u22125",
 1075     "\\u27965"
 1076 };
 1077 
 1078 static const char *lenientCurrencyTestCases[] = {
 1079         "$1,000",
 1080         "$ 1,000",
 1081         "$1000",
 1082         "$ 1000",
 1083         "$1 000.00",
 1084         "$ 1 000.00",
 1085         "$ 1\\u00A0000.00",
 1086         "1000.00"
 1087 };
 1088 
 1089 // changed from () to - per cldrbug 5674
 1090 static const char *lenientNegativeCurrencyTestCases[] = {
 1091         "-$1,000",
 1092         "-$ 1,000",
 1093         "-$1000",
 1094         "-$ 1000",
 1095         "-$1 000.00",
 1096         "-$ 1 000.00",
 1097         "- $ 1,000.00 ",
 1098         "-$ 1\\u00A0000.00",
 1099         "-1000.00"
 1100 };
 1101 
 1102 static const char *lenientPercentTestCases[] = {
 1103         "25%",
 1104         " 25%",
 1105         " 25 %",
 1106         "25 %",
 1107         "25\\u00A0%",
 1108         "25"
 1109 };
 1110 
 1111 static const char *lenientNegativePercentTestCases[] = {
 1112         "-25%",
 1113         " -25%",
 1114         " - 25%",
 1115         "- 25 %",
 1116         " - 25 %",
 1117         "-25 %",
 1118         "-25\\u00A0%",
 1119         "-25",
 1120         "- 25"
 1121 };
 1122 
 1123 static const char *strictFailureTestCases[] = {
 1124         " 1000",
 1125         "10,00",
 1126         "1,000,.0"
 1127 };
 1128 
 1129 /**
 1130  * Test lenient parsing.
 1131  */
 1132 void
 1133 NumberFormatTest::TestLenientParse(void)
 1134 {
 1135     UErrorCode status = U_ZERO_ERROR;
 1136     DecimalFormat *format = new DecimalFormat("(#,##0)", status);
 1137     Formattable n;
 1138 
 1139     if (format == NULL || U_FAILURE(status)) {
 1140         dataerrln("Unable to create DecimalFormat (#,##0) - %s", u_errorName(status));
 1141     } else {
 1142         format->setLenient(TRUE);
 1143         for (int32_t t = 0; t < UPRV_LENGTHOF (lenientAffixTestCases); t += 1) {
 1144             UnicodeString testCase = ctou(lenientAffixTestCases[t]);
 1145 
 1146             format->parse(testCase, n, status);
 1147             logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
 1148 
 1149             if (U_FAILURE(status) || n.getType() != Formattable::kLong ||
 1150                 n.getLong() != 1) {
 1151                 dataerrln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientAffixTestCases[t]
 1152                       + (UnicodeString) "\"; error code = " + u_errorName(status));
 1153                 status = U_ZERO_ERROR;
 1154             }
 1155        }
 1156        delete format;
 1157     }
 1158 
 1159     Locale en_US("en_US");
 1160     Locale sv_SE("sv_SE");
 1161 
 1162     NumberFormat *mFormat = NumberFormat::createInstance(sv_SE, UNUM_DECIMAL, status);
 1163 
 1164     if (mFormat == NULL || U_FAILURE(status)) {
 1165         dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status));
 1166     } else {
 1167         mFormat->setLenient(TRUE);
 1168         for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) {
 1169             UnicodeString testCase = ctou(lenientMinusTestCases[t]);
 1170 
 1171             mFormat->parse(testCase, n, status);
 1172             logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
 1173 
 1174             if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
 1175                 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t]
 1176                       + (UnicodeString) "\"; error code = " + u_errorName(status));
 1177                 status = U_ZERO_ERROR;
 1178             }
 1179         }
 1180         delete mFormat;
 1181     }
 1182 
 1183     mFormat = NumberFormat::createInstance(en_US, UNUM_DECIMAL, status);
 1184 
 1185     if (mFormat == NULL || U_FAILURE(status)) {
 1186         dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status));
 1187     } else {
 1188         mFormat->setLenient(TRUE);
 1189         for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) {
 1190             UnicodeString testCase = ctou(lenientMinusTestCases[t]);
 1191 
 1192             mFormat->parse(testCase, n, status);
 1193             logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
 1194 
 1195             if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
 1196                 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t]
 1197                       + (UnicodeString) "\"; error code = " + u_errorName(status));
 1198                 status = U_ZERO_ERROR;
 1199             }
 1200         }
 1201         delete mFormat;
 1202     }
 1203 
 1204     NumberFormat *cFormat = NumberFormat::createInstance(en_US, UNUM_CURRENCY, status);
 1205 
 1206     if (cFormat == NULL || U_FAILURE(status)) {
 1207         dataerrln("Unable to create NumberFormat (en_US, UNUM_CURRENCY) - %s", u_errorName(status));
 1208     } else {
 1209         cFormat->setLenient(TRUE);
 1210         for (int32_t t = 0; t < UPRV_LENGTHOF (lenientCurrencyTestCases); t += 1) {
 1211             UnicodeString testCase = ctou(lenientCurrencyTestCases[t]);
 1212 
 1213             cFormat->parse(testCase, n, status);
 1214             logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
 1215 
 1216             if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
 1217                 n.getLong() != 1000) {
 1218                 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientCurrencyTestCases[t]
 1219                       + (UnicodeString) "\"; error code = " + u_errorName(status));
 1220                 status = U_ZERO_ERROR;
 1221             }
 1222         }
 1223 
 1224         for (int32_t t = 0; t < UPRV_LENGTHOF (lenientNegativeCurrencyTestCases); t += 1) {
 1225             UnicodeString testCase = ctou(lenientNegativeCurrencyTestCases[t]);
 1226 
 1227             cFormat->parse(testCase, n, status);
 1228             logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
 1229 
 1230             if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
 1231                 n.getLong() != -1000) {
 1232                 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativeCurrencyTestCases[t]
 1233                       + (UnicodeString) "\"; error code = " + u_errorName(status));
 1234                 status = U_ZERO_ERROR;
 1235             }
 1236         }
 1237 
 1238         delete cFormat;
 1239     }
 1240 
 1241     NumberFormat *pFormat = NumberFormat::createPercentInstance(en_US, status);
 1242 
 1243     if (pFormat == NULL || U_FAILURE(status)) {
 1244         dataerrln("Unable to create NumberFormat::createPercentInstance (en_US) - %s", u_errorName(status));
 1245     } else {
 1246         pFormat->setLenient(TRUE);
 1247         for (int32_t t = 0; t < UPRV_LENGTHOF (lenientPercentTestCases); t += 1) {
 1248             UnicodeString testCase = ctou(lenientPercentTestCases[t]);
 1249 
 1250             pFormat->parse(testCase, n, status);
 1251             logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
 1252 
 1253             if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
 1254                 n.getDouble() != 0.25) {
 1255                 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientPercentTestCases[t]
 1256                       + (UnicodeString) "\"; error code = " + u_errorName(status)
 1257                       + "; got: " + n.getDouble(status));
 1258                 status = U_ZERO_ERROR;
 1259             }
 1260         }
 1261 
 1262         for (int32_t t = 0; t < UPRV_LENGTHOF (lenientNegativePercentTestCases); t += 1) {
 1263             UnicodeString testCase = ctou(lenientNegativePercentTestCases[t]);
 1264 
 1265             pFormat->parse(testCase, n, status);
 1266             logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
 1267 
 1268             if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
 1269                 n.getDouble() != -0.25) {
 1270                 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativePercentTestCases[t]
 1271                       + (UnicodeString) "\"; error code = " + u_errorName(status)
 1272                       + "; got: " + n.getDouble(status));
 1273                 status = U_ZERO_ERROR;
 1274             }
 1275         }
 1276 
 1277         delete pFormat;
 1278     }
 1279 
 1280    // Test cases that should fail with a strict parse and pass with a
 1281    // lenient parse.
 1282    NumberFormat *nFormat = NumberFormat::createInstance(en_US, status);
 1283 
 1284    if (nFormat == NULL || U_FAILURE(status)) {
 1285        dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status));
 1286    } else {
 1287        // first, make sure that they fail with a strict parse
 1288        for (int32_t t = 0; t < UPRV_LENGTHOF(strictFailureTestCases); t += 1) {
 1289            UnicodeString testCase = ctou(strictFailureTestCases[t]);
 1290 
 1291            nFormat->parse(testCase, n, status);
 1292            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
 1293 
 1294            if (! U_FAILURE(status)) {
 1295                errln((UnicodeString)"Strict Parse succeeded for \"" + (UnicodeString) strictFailureTestCases[t]
 1296                      + (UnicodeString) "\"; error code = " + u_errorName(status));
 1297            }
 1298 
 1299            status = U_ZERO_ERROR;
 1300        }
 1301 
 1302        // then, make sure that they pass with a lenient parse
 1303        nFormat->setLenient(TRUE);
 1304        for (int32_t t = 0; t < UPRV_LENGTHOF(strictFailureTestCases); t += 1) {
 1305            UnicodeString testCase = ctou(strictFailureTestCases[t]);
 1306 
 1307            nFormat->parse(testCase, n, status);
 1308            logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
 1309 
 1310            if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
 1311                     n.getLong() != 1000) {
 1312                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) strictFailureTestCases[t]
 1313                      + (UnicodeString) "\"; error code = " + u_errorName(status));
 1314                status = U_ZERO_ERROR;
 1315            }
 1316        }
 1317 
 1318        delete nFormat;
 1319    }
 1320 }
 1321 
 1322 // -------------------------------------
 1323 
 1324 /**
 1325  * Test proper rounding by the format method.
 1326  */
 1327 void
 1328 NumberFormatTest::TestRounding487(void)
 1329 {
 1330     UErrorCode status = U_ZERO_ERROR;
 1331     NumberFormat *nf = NumberFormat::createInstance(status);
 1332     if (U_FAILURE(status)) {
 1333         dataerrln("Error calling NumberFormat::createInstance()");
 1334         return;
 1335     }
 1336 
 1337     roundingTest(*nf, 0.00159999, 4, "0.0016");
 1338     roundingTest(*nf, 0.00995, 4, "0.01");
 1339 
 1340     roundingTest(*nf, 12.3995, 3, "12.4");
 1341 
 1342     roundingTest(*nf, 12.4999, 0, "12");
 1343     roundingTest(*nf, - 19.5, 0, "-20");
 1344     delete nf;
 1345     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status);
 1346 }
 1347 
 1348 /**
 1349  * Test the functioning of the secondary grouping value.
 1350  */
 1351 void NumberFormatTest::TestSecondaryGrouping(void) {
 1352     UErrorCode status = U_ZERO_ERROR;
 1353     DecimalFormatSymbols US(Locale::getUS(), status);
 1354     CHECK(status, "DecimalFormatSymbols ct");
 1355 
 1356     DecimalFormat f("#,##,###", US, status);
 1357     CHECK(status, "DecimalFormat ct");
 1358 
 1359     expect2(f, (int32_t)123456789L, "12,34,56,789");
 1360     expectPat(f, "#,##,##0");
 1361     f.applyPattern("#,###", status);
 1362     CHECK(status, "applyPattern");
 1363 
 1364     f.setSecondaryGroupingSize(4);
 1365     expect2(f, (int32_t)123456789L, "12,3456,789");
 1366     expectPat(f, "#,####,##0");
 1367     NumberFormat *g = NumberFormat::createInstance(Locale("hi", "IN"), status);
 1368     CHECK_DATA(status, "createInstance(hi_IN)");
 1369 
 1370     UnicodeString out;
 1371     int32_t l = (int32_t)1876543210L;
 1372     g->format(l, out);
 1373     delete g;
 1374     // expect "1,87,65,43,210", but with Hindi digits
 1375     //         01234567890123
 1376     UBool ok = TRUE;
 1377     if (out.length() != 14) {
 1378         ok = FALSE;
 1379     } else {
 1380         for (int32_t i=0; i<out.length(); ++i) {
 1381             UBool expectGroup = FALSE;
 1382             switch (i) {
 1383             case 1:
 1384             case 4:
 1385             case 7:
 1386             case 10:
 1387                 expectGroup = TRUE;
 1388                 break;
 1389             }
 1390             // Later -- fix this to get the actual grouping
 1391             // character from the resource bundle.
 1392             UBool isGroup = (out.charAt(i) == 0x002C);
 1393             if (isGroup != expectGroup) {
 1394                 ok = FALSE;
 1395                 break;
 1396             }
 1397         }
 1398     }
 1399     if (!ok) {
 1400         errln((UnicodeString)"FAIL  Expected " + l +
 1401               " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
 1402               escape(out) + "\"");
 1403     } else {
 1404         logln((UnicodeString)"Ok    " + l +
 1405               " x hi_IN -> \"" +
 1406               escape(out) + "\"");
 1407     }
 1408 }
 1409 
 1410 void NumberFormatTest::TestWhiteSpaceParsing(void) {
 1411     UErrorCode ec = U_ZERO_ERROR;
 1412     DecimalFormatSymbols US(Locale::getUS(), ec);
 1413     DecimalFormat fmt("a  b#0c  ", US, ec);
 1414     if (U_FAILURE(ec)) {
 1415         errcheckln(ec, "FAIL: Constructor - %s", u_errorName(ec));
 1416         return;
 1417     }
 1418     // From ICU 62, flexible whitespace needs lenient mode
 1419     fmt.setLenient(TRUE);
 1420     int32_t n = 1234;
 1421     expect(fmt, "a b1234c ", n);
 1422     expect(fmt, "a   b1234c   ", n);
 1423 }
 1424 
 1425 /**
 1426  * Test currencies whose display name is a ChoiceFormat.
 1427  */
 1428 void NumberFormatTest::TestComplexCurrency() {
 1429 
 1430 //    UErrorCode ec = U_ZERO_ERROR;
 1431 //    Locale loc("kn", "IN", "");
 1432 //    NumberFormat* fmt = NumberFormat::createCurrencyInstance(loc, ec);
 1433 //    if (U_SUCCESS(ec)) {
 1434 //        expect2(*fmt, 1.0, CharsToUnicodeString("Re.\\u00A01.00"));
 1435 //        Use .00392625 because that's 2^-8.  Any value less than 0.005 is fine.
 1436 //        expect(*fmt, 1.00390625, CharsToUnicodeString("Re.\\u00A01.00")); // tricky
 1437 //        expect2(*fmt, 12345678.0, CharsToUnicodeString("Rs.\\u00A01,23,45,678.00"));
 1438 //        expect2(*fmt, 0.5, CharsToUnicodeString("Rs.\\u00A00.50"));
 1439 //        expect2(*fmt, -1.0, CharsToUnicodeString("-Re.\\u00A01.00"));
 1440 //        expect2(*fmt, -10.0, CharsToUnicodeString("-Rs.\\u00A010.00"));
 1441 //    } else {
 1442 //        errln("FAIL: getCurrencyInstance(kn_IN)");
 1443 //    }
 1444 //    delete fmt;
 1445 
 1446 }
 1447 
 1448 // -------------------------------------
 1449 
 1450 void
 1451 NumberFormatTest::roundingTest(NumberFormat& nf, double x, int32_t maxFractionDigits, const char* expected)
 1452 {
 1453     nf.setMaximumFractionDigits(maxFractionDigits);
 1454     UnicodeString out; nf.format(x, out);
 1455     logln((UnicodeString)"" + x + " formats with " + maxFractionDigits + " fractional digits to " + out);
 1456     if (!(out==expected)) errln((UnicodeString)"FAIL: Expected " + expected);
 1457 }
 1458 
 1459 /**
 1460  * Upgrade to alphaWorks
 1461  */
 1462 void NumberFormatTest::TestExponent(void) {
 1463     UErrorCode status = U_ZERO_ERROR;
 1464     DecimalFormatSymbols US(Locale::getUS(), status);
 1465     CHECK(status, "DecimalFormatSymbols constructor");
 1466     DecimalFormat fmt1(UnicodeString("0.###E0"), US, status);
 1467     CHECK(status, "DecimalFormat(0.###E0)");
 1468     DecimalFormat fmt2(UnicodeString("0.###E+0"), US, status);
 1469     CHECK(status, "DecimalFormat(0.###E+0)");
 1470     int32_t n = 1234;
 1471     expect2(fmt1, n, "1.234E3");
 1472     expect2(fmt2, n, "1.234E+3");
 1473     expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"
 1474 }
 1475 
 1476 /**
 1477  * Upgrade to alphaWorks
 1478  */
 1479 void NumberFormatTest::TestScientific(void) {
 1480     UErrorCode status = U_ZERO_ERROR;
 1481     DecimalFormatSymbols US(Locale::getUS(), status);
 1482     CHECK(status, "DecimalFormatSymbols constructor");
 1483 
 1484     // Test pattern round-trip
 1485     const char* PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
 1486                           "0.###E0;[0.###E0]" };
 1487     int32_t PAT_length = UPRV_LENGTHOF(PAT);
 1488     int32_t DIGITS[] = {
 1489         // min int, max int, min frac, max frac
 1490         1, 1, 0, 0, // "#E0"
 1491         1, 1, 0, 4, // "0.####E0"
 1492         2, 2, 3, 3, // "00.000E00"
 1493         1, 3, 0, 4, // "##0.####E000"
 1494         1, 1, 0, 3, // "0.###E0;[0.###E0]"
 1495     };
 1496     for (int32_t i=0; i<PAT_length; ++i) {
 1497         UnicodeString pat(PAT[i]);
 1498         DecimalFormat df(pat, US, status);
 1499         CHECK(status, "DecimalFormat constructor");
 1500         UnicodeString pat2;
 1501         df.toPattern(pat2);
 1502         if (pat == pat2) {
 1503             logln(UnicodeString("Ok   Pattern rt \"") +
 1504                   pat + "\" -> \"" +
 1505                   pat2 + "\"");
 1506         } else {
 1507             errln(UnicodeString("FAIL Pattern rt \"") +
 1508                   pat + "\" -> \"" +
 1509                   pat2 + "\"");
 1510         }
 1511         // Make sure digit counts match what we expect
 1512         if (df.getMinimumIntegerDigits() != DIGITS[4*i] ||
 1513             df.getMaximumIntegerDigits() != DIGITS[4*i+1] ||
 1514             df.getMinimumFractionDigits() != DIGITS[4*i+2] ||
 1515             df.getMaximumFractionDigits() != DIGITS[4*i+3]) {
 1516             errln(UnicodeString("FAIL \"" + pat +
 1517                                 "\" min/max int; min/max frac = ") +
 1518                   df.getMinimumIntegerDigits() + "/" +
 1519                   df.getMaximumIntegerDigits() + ";" +
 1520                   df.getMinimumFractionDigits() + "/" +
 1521                   df.getMaximumFractionDigits() + ", expect " +
 1522                   DIGITS[4*i] + "/" +
 1523                   DIGITS[4*i+1] + ";" +
 1524                   DIGITS[4*i+2] + "/" +
 1525                   DIGITS[4*i+3]);
 1526         }
 1527     }
 1528 
 1529 
 1530     // Test the constructor for default locale. We have to
 1531     // manually set the default locale, as there is no
 1532     // guarantee that the default locale has the same
 1533     // scientific format.
 1534     Locale def = Locale::getDefault();
 1535     Locale::setDefault(Locale::getUS(), status);
 1536     expect2(NumberFormat::createScientificInstance(status),
 1537            12345.678901,
 1538            "1.2345678901E4", status);
 1539     Locale::setDefault(def, status);
 1540 
 1541     expect2(new DecimalFormat("#E0", US, status),
 1542            12345.0,
 1543            "1.2345E4", status);
 1544     expect(new DecimalFormat("0E0", US, status),
 1545            12345.0,
 1546            "1E4", status);
 1547     expect2(NumberFormat::createScientificInstance(Locale::getUS(), status),
 1548            12345.678901,
 1549            "1.2345678901E4", status);
 1550     expect(new DecimalFormat("##0.###E0", US, status),
 1551            12345.0,
 1552            "12.34E3", status);
 1553     expect(new DecimalFormat("##0.###E0", US, status),
 1554            12345.00001,
 1555            "12.35E3", status);
 1556     expect2(new DecimalFormat("##0.####E0", US, status),
 1557            (int32_t) 12345,
 1558            "12.345E3", status);
 1559     expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status),
 1560            12345.678901,
 1561            "1,2345678901E4", status);
 1562     expect(new DecimalFormat("##0.####E0", US, status),
 1563            789.12345e-9,
 1564            "789.12E-9", status);
 1565     expect2(new DecimalFormat("##0.####E0", US, status),
 1566            780.e-9,
 1567            "780E-9", status);
 1568     expect(new DecimalFormat(".###E0", US, status),
 1569            45678.0,
 1570            ".457E5", status);
 1571     expect2(new DecimalFormat(".###E0", US, status),
 1572            (int32_t) 0,
 1573            ".0E0", status);
 1574     /*
 1575     expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
 1576                                  new DecimalFormat("##E0", US),
 1577                                  new DecimalFormat("####E0", US),
 1578                                  new DecimalFormat("0E0", US),
 1579                                  new DecimalFormat("00E0", US),
 1580                                  new DecimalFormat("000E0", US),
 1581                                },
 1582            new Long(45678000),
 1583            new String[] { "4.5678E7",
 1584                           "45.678E6",
 1585                           "4567.8E4",
 1586                           "5E7",
 1587                           "46E6",
 1588                           "457E5",
 1589                         }
 1590            );
 1591     !
 1592     ! Unroll this test into individual tests below...
 1593     !
 1594     */
 1595     expect2(new DecimalFormat("#E0", US, status),
 1596            (int32_t) 45678000, "4.5678E7", status);
 1597     expect2(new DecimalFormat("##E0", US, status),
 1598            (int32_t) 45678000, "45.678E6", status);
 1599     expect2(new DecimalFormat("####E0", US, status),
 1600            (int32_t) 45678000, "4567.8E4", status);
 1601     expect(new DecimalFormat("0E0", US, status),
 1602            (int32_t) 45678000, "5E7", status);
 1603     expect(new DecimalFormat("00E0", US, status),
 1604            (int32_t) 45678000, "46E6", status);
 1605     expect(new DecimalFormat("000E0", US, status),
 1606            (int32_t) 45678000, "457E5", status);
 1607     /*
 1608     expect(new DecimalFormat("###E0", US, status),
 1609            new Object[] { new Double(0.0000123), "12.3E-6",
 1610                           new Double(0.000123), "123E-6",
 1611                           new Double(0.00123), "1.23E-3",
 1612                           new Double(0.0123), "12.3E-3",
 1613                           new Double(0.123), "123E-3",
 1614                           new Double(1.23), "1.23E0",
 1615                           new Double(12.3), "12.3E0",
 1616                           new Double(123), "123E0",
 1617                           new Double(1230), "1.23E3",
 1618                          });
 1619     !
 1620     ! Unroll this test into individual tests below...
 1621     !
 1622     */
 1623     expect2(new DecimalFormat("###E0", US, status),
 1624            0.0000123, "12.3E-6", status);
 1625     expect2(new DecimalFormat("###E0", US, status),
 1626            0.000123, "123E-6", status);
 1627     expect2(new DecimalFormat("###E0", US, status),
 1628            0.00123, "1.23E-3", status);
 1629     expect2(new DecimalFormat("###E0", US, status),
 1630            0.0123, "12.3E-3", status);
 1631     expect2(new DecimalFormat("###E0", US, status),
 1632            0.123, "123E-3", status);
 1633     expect2(new DecimalFormat("###E0", US, status),
 1634            1.23, "1.23E0", status);
 1635     expect2(new DecimalFormat("###E0", US, status),
 1636            12.3, "12.3E0", status);
 1637     expect2(new DecimalFormat("###E0", US, status),
 1638            123.0, "123E0", status);
 1639     expect2(new DecimalFormat("###E0", US, status),
 1640            1230.0, "1.23E3", status);
 1641     /*
 1642     expect(new DecimalFormat("0.#E+00", US, status),
 1643            new Object[] { new Double(0.00012), "1.2E-04",
 1644                           new Long(12000),     "1.2E+04",
 1645                          });
 1646     !
 1647     ! Unroll this test into individual tests below...
 1648     !
 1649     */
 1650     expect2(new DecimalFormat("0.#E+00", US, status),
 1651            0.00012, "1.2E-04", status);
 1652     expect2(new DecimalFormat("0.#E+00", US, status),
 1653            (int32_t) 12000, "1.2E+04", status);
 1654 }
 1655 
 1656 /**
 1657  * Upgrade to alphaWorks
 1658  */
 1659 void NumberFormatTest::TestPad(void) {
 1660     UErrorCode status = U_ZERO_ERROR;
 1661     DecimalFormatSymbols US(Locale::getUS(), status);
 1662     CHECK(status, "DecimalFormatSymbols constructor");
 1663 
 1664     expect2(new DecimalFormat("*^##.##", US, status),
 1665            int32_t(0), "^^^^0", status);
 1666     expect2(new DecimalFormat("*^##.##", US, status),
 1667            -1.3, "^-1.3", status);
 1668     expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
 1669            int32_t(0), "0.0E0______ g-m/s^2", status);
 1670     expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
 1671            1.0/3, "333.333E-3_ g-m/s^2", status);
 1672     expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
 1673            int32_t(0), "0.0______ g-m/s^2", status);
 1674     expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
 1675            1.0/3, "0.33333__ g-m/s^2", status);
 1676 
 1677     // Test padding before a sign
 1678     const char *formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
 1679     expect2(new DecimalFormat(formatStr, US, status),
 1680            int32_t(-10),  "xxxxxxxxxx(10.0)", status);
 1681     expect2(new DecimalFormat(formatStr, US, status),
 1682            int32_t(-1000),"xxxxxxx(1,000.0)", status);
 1683     expect2(new DecimalFormat(formatStr, US, status),
 1684            int32_t(-1000000),"xxx(1,000,000.0)", status);
 1685     expect2(new DecimalFormat(formatStr, US, status),
 1686            -100.37,       "xxxxxxxx(100.37)", status);
 1687     expect2(new DecimalFormat(formatStr, US, status),
 1688            -10456.37,     "xxxxx(10,456.37)", status);
 1689     expect2(new DecimalFormat(formatStr, US, status),
 1690            -1120456.37,   "xx(1,120,456.37)", status);
 1691     expect2(new DecimalFormat(formatStr, US, status),
 1692            -112045600.37, "(112,045,600.37)", status);
 1693     expect2(new DecimalFormat(formatStr, US, status),
 1694            -1252045600.37,"(1,252,045,600.37)", status);
 1695 
 1696     expect2(new DecimalFormat(formatStr, US, status),
 1697            int32_t(10),  "xxxxxxxxxxxx10.0", status);
 1698     expect2(new DecimalFormat(formatStr, US, status),
 1699            int32_t(1000),"xxxxxxxxx1,000.0", status);
 1700     expect2(new DecimalFormat(formatStr, US, status),
 1701            int32_t(1000000),"xxxxx1,000,000.0", status);
 1702     expect2(new DecimalFormat(formatStr, US, status),
 1703            100.37,       "xxxxxxxxxx100.37", status);
 1704     expect2(new DecimalFormat(formatStr, US, status),
 1705            10456.37,     "xxxxxxx10,456.37", status);
 1706     expect2(new DecimalFormat(formatStr, US, status),
 1707            1120456.37,   "xxxx1,120,456.37", status);
 1708     expect2(new DecimalFormat(formatStr, US, status),
 1709            112045600.37, "xx112,045,600.37", status);
 1710     expect2(new DecimalFormat(formatStr, US, status),
 1711            10252045600.37,"10,252,045,600.37", status);
 1712 
 1713 
 1714     // Test padding between a sign and a number
 1715     const char *formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
 1716     expect2(new DecimalFormat(formatStr2, US, status),
 1717            int32_t(-10),  "(10.0xxxxxxxxxx)", status);
 1718     expect2(new DecimalFormat(formatStr2, US, status),
 1719            int32_t(-1000),"(1,000.0xxxxxxx)", status);
 1720     expect2(new DecimalFormat(formatStr2, US, status),
 1721            int32_t(-1000000),"(1,000,000.0xxx)", status);
 1722     expect2(new DecimalFormat(formatStr2, US, status),
 1723            -100.37,       "(100.37xxxxxxxx)", status);
 1724     expect2(new DecimalFormat(formatStr2, US, status),
 1725            -10456.37,     "(10,456.37xxxxx)", status);
 1726     expect2(new DecimalFormat(formatStr2, US, status),
 1727            -1120456.37,   "(1,120,456.37xx)", status);
 1728     expect2(new DecimalFormat(formatStr2, US, status),
 1729            -112045600.37, "(112,045,600.37)", status);
 1730     expect2(new DecimalFormat(formatStr2, US, status),
 1731            -1252045600.37,"(1,252,045,600.37)", status);
 1732 
 1733     expect2(new DecimalFormat(formatStr2, US, status),
 1734            int32_t(10),  "10.0xxxxxxxxxxxx", status);
 1735     expect2(new DecimalFormat(formatStr2, US, status),
 1736            int32_t(1000),"1,000.0xxxxxxxxx", status);
 1737     expect2(new DecimalFormat(formatStr2, US, status),
 1738            int32_t(1000000),"1,000,000.0xxxxx", status);
 1739     expect2(new DecimalFormat(formatStr2, US, status),
 1740            100.37,       "100.37xxxxxxxxxx", status);
 1741     expect2(new DecimalFormat(formatStr2, US, status),
 1742            10456.37,     "10,456.37xxxxxxx", status);
 1743     expect2(new DecimalFormat(formatStr2, US, status),
 1744            1120456.37,   "1,120,456.37xxxx", status);
 1745     expect2(new DecimalFormat(formatStr2, US, status),
 1746            112045600.37, "112,045,600.37xx", status);
 1747     expect2(new DecimalFormat(formatStr2, US, status),
 1748            10252045600.37,"10,252,045,600.37", status);
 1749 
 1750     //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
 1751     DecimalFormat fmt("#", US, status);
 1752     CHECK(status, "DecimalFormat constructor");
 1753     UnicodeString padString("P");
 1754     fmt.setPadCharacter(padString);
 1755     expectPad(fmt, "*P##.##", DecimalFormat::kPadBeforePrefix, 5, padString);
 1756     fmt.setPadCharacter((UnicodeString)"^");
 1757     expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, (UnicodeString)"^");
 1758     //commented untill implementation is complete
 1759   /*  fmt.setPadCharacter((UnicodeString)"^^^");
 1760     expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
 1761     padString.remove();
 1762     padString.append((UChar)0x0061);
 1763     padString.append((UChar)0x0302);
 1764     fmt.setPadCharacter(padString);
 1765     UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
 1766     UnicodeString pattern(patternChars);
 1767     expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
 1768  */
 1769 
 1770 }
 1771 
 1772 /**
 1773  * Upgrade to alphaWorks
 1774  */
 1775 void NumberFormatTest::TestPatterns2(void) {
 1776     UErrorCode status = U_ZERO_ERROR;
 1777     DecimalFormatSymbols US(Locale::getUS(), status);
 1778     CHECK(status, "DecimalFormatSymbols constructor");
 1779 
 1780     DecimalFormat fmt("#", US, status);
 1781     CHECK(status, "DecimalFormat constructor");
 1782 
 1783     UChar hat = 0x005E; /*^*/
 1784 
 1785     expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, hat);
 1786     expectPad(fmt, "$*^#", DecimalFormat::kPadAfterPrefix, 2, hat);
 1787     expectPad(fmt, "#*^", DecimalFormat::kPadBeforeSuffix, 1, hat);
 1788     expectPad(fmt, "#$*^", DecimalFormat::kPadAfterSuffix, 2, hat);
 1789     expectPad(fmt, "$*^$#", ILLEGAL);
 1790     expectPad(fmt, "#$*^$", ILLEGAL);
 1791     expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix,
 1792               12, (UChar)0x0078 /*x*/);
 1793     expectPad(fmt, "''#0*x", DecimalFormat::kPadBeforeSuffix,
 1794               3, (UChar)0x0078 /*x*/);
 1795     expectPad(fmt, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix,
 1796               10, (UChar)0x0061 /*a*/);
 1797 
 1798     fmt.applyPattern("AA#,##0.00ZZ", status);
 1799     CHECK(status, "applyPattern");
 1800     fmt.setPadCharacter(hat);
 1801 
 1802     fmt.setFormatWidth(10);
 1803 
 1804     fmt.setPadPosition(DecimalFormat::kPadBeforePrefix);
 1805     expectPat(fmt, "*^AA#,##0.00ZZ");
 1806 
 1807     fmt.setPadPosition(DecimalFormat::kPadBeforeSuffix);
 1808     expectPat(fmt, "AA#,##0.00*^ZZ");
 1809 
 1810     fmt.setPadPosition(DecimalFormat::kPadAfterSuffix);
 1811     expectPat(fmt, "AA#,##0.00ZZ*^");
 1812 
 1813     //            12  3456789012
 1814     UnicodeString exp("AA*^#,##0.00ZZ", "");
 1815     fmt.setFormatWidth(12);
 1816     fmt.setPadPosition(DecimalFormat::kPadAfterPrefix);
 1817     expectPat(fmt, exp);
 1818 
 1819     fmt.setFormatWidth(13);
 1820     //              12  34567890123
 1821     expectPat(fmt, "AA*^##,##0.00ZZ");
 1822 
 1823     fmt.setFormatWidth(14);
 1824     //              12  345678901234
 1825     expectPat(fmt, "AA*^###,##0.00ZZ");
 1826 
 1827     fmt.setFormatWidth(15);
 1828     //              12  3456789012345
 1829     expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
 1830 
 1831     fmt.setFormatWidth(16);
 1832     //              12  34567890123456
 1833     expectPat(fmt, "AA*^#####,##0.00ZZ");
 1834 }
 1835 
 1836 void NumberFormatTest::TestSurrogateSupport(void) {
 1837     UErrorCode status = U_ZERO_ERROR;
 1838     DecimalFormatSymbols custom(Locale::getUS(), status);
 1839     CHECK(status, "DecimalFormatSymbols constructor");
 1840 
 1841     custom.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, "decimal");
 1842     custom.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, "plus");
 1843     custom.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, " minus ");
 1844     custom.setSymbol(DecimalFormatSymbols::kExponentialSymbol, "exponent");
 1845 
 1846     UnicodeString patternStr("*\\U00010000##.##", "");
 1847     patternStr = patternStr.unescape();
 1848     UnicodeString expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
 1849     expStr = expStr.unescape();
 1850     expect2(new DecimalFormat(patternStr, custom, status),
 1851            int32_t(0), expStr, status);
 1852 
 1853     status = U_ZERO_ERROR;
 1854     expect2(new DecimalFormat("*^##.##", custom, status),
 1855            int32_t(0), "^^^^0", status);
 1856     status = U_ZERO_ERROR;
 1857     expect2(new DecimalFormat("##.##", custom, status),
 1858            -1.3, " minus 1decimal3", status);
 1859     status = U_ZERO_ERROR;
 1860     expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
 1861            int32_t(0), "0decimal0exponent0 g-m/s^2", status);
 1862     status = U_ZERO_ERROR;
 1863     expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
 1864            1.0/3, "333decimal333exponent minus 3 g-m/s^2", status);
 1865     status = U_ZERO_ERROR;
 1866     expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
 1867            int32_t(0), "0decimal0 g-m/s^2", status);
 1868     status = U_ZERO_ERROR;
 1869     expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
 1870            1.0/3, "0decimal33333 g-m/s^2", status);
 1871 
 1872     UnicodeString zero((UChar32)0x10000);
 1873     UnicodeString one((UChar32)0x10001);
 1874     UnicodeString two((UChar32)0x10002);
 1875     UnicodeString five((UChar32)0x10005);
 1876     custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero);
 1877     custom.setSymbol(DecimalFormatSymbols::kOneDigitSymbol, one);
 1878     custom.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol, two);
 1879     custom.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol, five);
 1880     expStr = UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
 1881     expStr = expStr.unescape();
 1882     status = U_ZERO_ERROR;
 1883     expect2(new DecimalFormat("##0.000", custom, status),
 1884            1.25, expStr, status);
 1885 
 1886     custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, (UChar)0x30);
 1887     custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "units of money");
 1888     custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, "money separator");
 1889     patternStr = UNICODE_STRING_SIMPLE("0.00 \\u00A4' in your bank account'");
 1890     patternStr = patternStr.unescape();
 1891     expStr = UnicodeString(" minus 20money separator00 units of money in your bank account", "");
 1892     status = U_ZERO_ERROR;
 1893     expect2(new DecimalFormat(patternStr, custom, status),
 1894            int32_t(-20), expStr, status);
 1895 
 1896     custom.setSymbol(DecimalFormatSymbols::kPercentSymbol, "percent");
 1897     patternStr = "'You''ve lost ' -0.00 %' of your money today'";
 1898     patternStr = patternStr.unescape();
 1899     expStr = UnicodeString(" minus You've lost   minus 2000decimal00 percent of your money today", "");
 1900     status = U_ZERO_ERROR;
 1901     expect2(new DecimalFormat(patternStr, custom, status),
 1902            int32_t(-20), expStr, status);
 1903 }
 1904 
 1905 void NumberFormatTest::TestCurrencyPatterns(void) {
 1906     int32_t i, locCount;
 1907     const Locale* locs = NumberFormat::getAvailableLocales(locCount);
 1908     for (i=0; i<locCount; ++i) {
 1909         UErrorCode ec = U_ZERO_ERROR;
 1910         NumberFormat* nf = NumberFormat::createCurrencyInstance(locs[i], ec);
 1911         if (U_FAILURE(ec)) {
 1912             errln("FAIL: Can't create NumberFormat(%s) - %s", locs[i].getName(), u_errorName(ec));
 1913         } else {
 1914             // Make sure currency formats do not have a variable number
 1915             // of fraction digits
 1916             int32_t min = nf->getMinimumFractionDigits();
 1917             int32_t max = nf->getMaximumFractionDigits();
 1918             if (min != max) {
 1919                 UnicodeString a, b;
 1920                 nf->format(1.0, a);
 1921                 nf->format(1.125, b);
 1922                 errln((UnicodeString)"FAIL: " + locs[i].getName() +
 1923                       " min fraction digits != max fraction digits; "
 1924                       "x 1.0 => " + escape(a) +
 1925                       "; x 1.125 => " + escape(b));
 1926             }
 1927 
 1928             // Make sure EURO currency formats have exactly 2 fraction digits
 1929             DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
 1930             if (df != NULL) {
 1931                 if (u_strcmp(EUR, df->getCurrency()) == 0) {
 1932                     if (min != 2 || max != 2) {
 1933                         UnicodeString a;
 1934                         nf->format(1.0, a);
 1935                         errln((UnicodeString)"FAIL: " + locs[i].getName() +
 1936                               " is a EURO format but it does not have 2 fraction digits; "
 1937                               "x 1.0 => " +
 1938                               escape(a));
 1939                     }
 1940                 }
 1941             }
 1942         }
 1943         delete nf;
 1944     }
 1945 }
 1946 
 1947 void NumberFormatTest::TestRegCurrency(void) {
 1948 #if !UCONFIG_NO_SERVICE
 1949     UErrorCode status = U_ZERO_ERROR;
 1950     UChar USD[4];
 1951     ucurr_forLocale("en_US", USD, 4, &status);
 1952     UChar YEN[4];
 1953     ucurr_forLocale("ja_JP", YEN, 4, &status);
 1954     UChar TMP[4];
 1955 
 1956     if(U_FAILURE(status)) {
 1957         errcheckln(status, "Unable to get currency for locale, error %s", u_errorName(status));
 1958         return;
 1959     }
 1960 
 1961     UCurrRegistryKey enkey = ucurr_register(YEN, "en_US", &status);
 1962 
 1963     ucurr_forLocale("en_US", TMP, 4, &status);
 1964     if (u_strcmp(YEN, TMP) != 0) {
 1965         errln("FAIL: didn't return YEN registered for en_US");
 1966     }
 1967 
 1968     int32_t fallbackLen = ucurr_forLocale("en_XX_BAR", TMP, 4, &status);
 1969     if (fallbackLen) {
 1970         errln("FAIL: tried to fallback en_XX_BAR");
 1971     }
 1972     status = U_ZERO_ERROR; // reset
 1973 
 1974     if (!ucurr_unregister(enkey, &status)) {
 1975         errln("FAIL: couldn't unregister enkey");
 1976     }
 1977 
 1978     ucurr_forLocale("en_US", TMP, 4, &status);
 1979     if (u_strcmp(USD, TMP) != 0) {
 1980         errln("FAIL: didn't return USD for en_US after unregister of en_US");
 1981     }
 1982     status = U_ZERO_ERROR; // reset
 1983 
 1984     ucurr_forLocale("en_US_BLAH", TMP, 4, &status);
 1985     if (u_strcmp(USD, TMP) != 0) {
 1986         errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
 1987     }
 1988     status = U_ZERO_ERROR; // reset
 1989 #endif
 1990 }
 1991 
 1992 void NumberFormatTest::TestCurrencyNames(void) {
 1993     // Do a basic check of getName()
 1994     // USD { "US$", "US Dollar"            } // 04/04/1792-
 1995     UErrorCode ec = U_ZERO_ERROR;
 1996     static const UChar USD[] = {0x55, 0x53, 0x44, 0}; /*USD*/
 1997     static const UChar USX[] = {0x55, 0x53, 0x58, 0}; /*USX*/
 1998     static const UChar CAD[] = {0x43, 0x41, 0x44, 0}; /*CAD*/
 1999     static const UChar ITL[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/
 2000     UBool isChoiceFormat;
 2001     int32_t len;
 2002     const UBool possibleDataError = TRUE;
 2003     // Warning: HARD-CODED LOCALE DATA in this test.  If it fails, CHECK
 2004     // THE LOCALE DATA before diving into the code.
 2005     assertEquals("USD.getName(SYMBOL_NAME, en)",
 2006                  UnicodeString("$"),
 2007                  UnicodeString(ucurr_getName(USD, "en",
 2008                                              UCURR_SYMBOL_NAME,
 2009                                              &isChoiceFormat, &len, &ec)),
 2010                                              possibleDataError);
 2011     assertEquals("USD.getName(NARROW_SYMBOL_NAME, en)",
 2012                  UnicodeString("$"),
 2013                  UnicodeString(ucurr_getName(USD, "en",
 2014                                              UCURR_NARROW_SYMBOL_NAME,
 2015                                              &isChoiceFormat, &len, &ec)),
 2016                                              possibleDataError);
 2017     assertEquals("USD.getName(LONG_NAME, en)",
 2018                  UnicodeString("US Dollar"),
 2019                  UnicodeString(ucurr_getName(USD, "en",
 2020                                              UCURR_LONG_NAME,
 2021                                              &isChoiceFormat, &len, &ec)),
 2022                                              possibleDataError);
 2023     assertEquals("CAD.getName(SYMBOL_NAME, en)",
 2024                  UnicodeString("CA$"),
 2025                  UnicodeString(ucurr_getName(CAD, "en",
 2026                                              UCURR_SYMBOL_NAME,
 2027                                              &isChoiceFormat, &len, &ec)),
 2028                                              possibleDataError);
 2029     assertEquals("CAD.getName(NARROW_SYMBOL_NAME, en)",
 2030                  UnicodeString("$"),
 2031                  UnicodeString(ucurr_getName(CAD, "en",
 2032                                              UCURR_NARROW_SYMBOL_NAME,
 2033                                              &isChoiceFormat, &len, &ec)),
 2034                                              possibleDataError);
 2035     assertEquals("CAD.getName(SYMBOL_NAME, en_CA)",
 2036                  UnicodeString("$"),
 2037                  UnicodeString(ucurr_getName(CAD, "en_CA",
 2038                                              UCURR_SYMBOL_NAME,
 2039                                              &isChoiceFormat, &len, &ec)),
 2040                                              possibleDataError);
 2041     assertEquals("USD.getName(SYMBOL_NAME, en_CA)",
 2042                  UnicodeString("US$"),
 2043                  UnicodeString(ucurr_getName(USD, "en_CA",
 2044                                              UCURR_SYMBOL_NAME,
 2045                                              &isChoiceFormat, &len, &ec)),
 2046                                              possibleDataError);
 2047     assertEquals("USD.getName(NARROW_SYMBOL_NAME, en_CA)",
 2048                  UnicodeString("$"),
 2049                  UnicodeString(ucurr_getName(USD, "en_CA",
 2050                                              UCURR_NARROW_SYMBOL_NAME,
 2051                                              &isChoiceFormat, &len, &ec)),
 2052                                              possibleDataError);
 2053     assertEquals("USD.getName(SYMBOL_NAME) in en_NZ",
 2054                  UnicodeString("US$"),
 2055                  UnicodeString(ucurr_getName(USD, "en_NZ",
 2056                                              UCURR_SYMBOL_NAME,
 2057                                              &isChoiceFormat, &len, &ec)),
 2058                                              possibleDataError);
 2059     assertEquals("CAD.getName(SYMBOL_NAME)",
 2060                  UnicodeString("CA$"),
 2061                  UnicodeString(ucurr_getName(CAD, "en_NZ",
 2062                                              UCURR_SYMBOL_NAME,
 2063                                              &isChoiceFormat, &len, &ec)),
 2064                                              possibleDataError);
 2065     assertEquals("USX.getName(SYMBOL_NAME)",
 2066                  UnicodeString("USX"),
 2067                  UnicodeString(ucurr_getName(USX, "en_US",
 2068                                              UCURR_SYMBOL_NAME,
 2069                                              &isChoiceFormat, &len, &ec)),
 2070                                              possibleDataError);
 2071     assertEquals("USX.getName(NARROW_SYMBOL_NAME)",
 2072                  UnicodeString("USX"),
 2073                  UnicodeString(ucurr_getName(USX, "en_US",
 2074                                              UCURR_NARROW_SYMBOL_NAME,
 2075                                              &isChoiceFormat, &len, &ec)),
 2076                                              possibleDataError);
 2077     assertEquals("USX.getName(LONG_NAME)",
 2078                  UnicodeString("USX"),
 2079                  UnicodeString(ucurr_getName(USX, "en_US",
 2080                                              UCURR_LONG_NAME,
 2081                                              &isChoiceFormat, &len, &ec)),
 2082                                              possibleDataError);
 2083     assertSuccess("ucurr_getName", ec);
 2084 
 2085     ec = U_ZERO_ERROR;
 2086 
 2087     // Test that a default or fallback warning is being returned. JB 4239.
 2088     ucurr_getName(CAD, "es_ES", UCURR_LONG_NAME, &isChoiceFormat,
 2089                             &len, &ec);
 2090     assertTrue("ucurr_getName (es_ES fallback)",
 2091                     U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
 2092 
 2093     ucurr_getName(CAD, "zh_TW", UCURR_LONG_NAME, &isChoiceFormat,
 2094                             &len, &ec);
 2095     assertTrue("ucurr_getName (zh_TW fallback)",
 2096                     U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
 2097 
 2098     ucurr_getName(CAD, "en_US", UCURR_LONG_NAME, &isChoiceFormat,
 2099                             &len, &ec);
 2100     assertTrue("ucurr_getName (en_US default)",
 2101                     U_USING_DEFAULT_WARNING == ec || U_USING_FALLBACK_WARNING == ec, TRUE);
 2102 
 2103     ucurr_getName(CAD, "ti", UCURR_LONG_NAME, &isChoiceFormat,
 2104                             &len, &ec);
 2105     assertTrue("ucurr_getName (ti default)",
 2106                     U_USING_DEFAULT_WARNING == ec, TRUE);
 2107 
 2108     // Test that a default warning is being returned when falling back to root. JB 4536.
 2109     ucurr_getName(ITL, "cy", UCURR_LONG_NAME, &isChoiceFormat,
 2110                             &len, &ec);
 2111     assertTrue("ucurr_getName (cy default to root)",
 2112                     U_USING_DEFAULT_WARNING == ec, TRUE);
 2113 
 2114     // TODO add more tests later
 2115 }
 2116 
 2117 void NumberFormatTest::Test20484_NarrowSymbolFallback(){
 2118     IcuTestErrorCode status(*this, "Test20484_NarrowSymbolFallback");
 2119 
 2120     struct TestCase {
 2121         const char* locale;
 2122         const char16_t* isoCode;
 2123         const char16_t* expectedShort;
 2124         const char16_t* expectedNarrow;
 2125         UErrorCode expectedNarrowError;
 2126     } cases[] = {
 2127         {"en-US", u"CAD", u"CA$", u"$", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
 2128         {"en-US", u"CDF", u"CDF", u"CDF", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
 2129         {"sw-CD", u"CDF", u"FC", u"FC", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
 2130         {"en-US", u"GEL", u"GEL", u"₾", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
 2131         {"ka-GE", u"GEL", u"₾", u"₾", U_USING_FALLBACK_WARNING}, // narrow: fallback to ka
 2132         {"ka", u"GEL", u"₾", u"₾", U_ZERO_ERROR}, // no fallback on narrow
 2133     };
 2134     for (const auto& cas : cases) {
 2135         status.setScope(cas.isoCode);
 2136         UBool choiceFormatIgnored;
 2137         int32_t lengthIgnored;
 2138         const UChar* actualShort = ucurr_getName(
 2139             cas.isoCode,
 2140             cas.locale,
 2141             UCURR_SYMBOL_NAME,
 2142             &choiceFormatIgnored,
 2143             &lengthIgnored,
 2144             status);
 2145         status.errIfFailureAndReset();
 2146         const UChar* actualNarrow = ucurr_getName(
 2147             cas.isoCode,
 2148             cas.locale,
 2149             UCURR_NARROW_SYMBOL_NAME,
 2150             &choiceFormatIgnored,
 2151             &lengthIgnored,
 2152             status);
 2153         status.expectErrorAndReset(cas.expectedNarrowError);
 2154         assertEquals(UnicodeString("Short symbol: ") + cas.locale + u": " + cas.isoCode,
 2155                 cas.expectedShort, actualShort);
 2156         assertEquals(UnicodeString("Narrow symbol: ") + cas.locale + ": " + cas.isoCode,
 2157                 cas.expectedNarrow, actualNarrow);
 2158     }
 2159 }
 2160 
 2161 void NumberFormatTest::TestCurrencyUnit(void){
 2162     UErrorCode ec = U_ZERO_ERROR;
 2163     static const UChar USD[]  = u"USD";
 2164     static const char USD8[]  =  "USD";
 2165     static const UChar BAD[]  = u"???";
 2166     static const UChar BAD2[] = u"??A";
 2167     static const UChar XXX[]  = u"XXX";
 2168     static const char XXX8[]  =  "XXX";
 2169     static const UChar XYZ[]  = u"XYZ";
 2170     static const char XYZ8[]  =  "XYZ";
 2171     static const UChar INV[]  = u"{$%";
 2172     static const char INV8[]  =  "{$%";
 2173     static const UChar ZZZ[]  = u"zz";
 2174     static const char ZZZ8[]  = "zz";
 2175     static const UChar JPY[]  = u"JPY";
 2176     static const char JPY8[]  =  "JPY";
 2177     static const UChar jpy[]  = u"jpy";
 2178     static const char jpy8[]  =  "jpy";
 2179 
 2180     UChar* EUR = (UChar*) malloc(6);
 2181     EUR[0] = u'E';
 2182     EUR[1] = u'U';
 2183     EUR[2] = u'R';
 2184     char* EUR8 = (char*) malloc(3);
 2185     EUR8[0] = 'E';
 2186     EUR8[1] = 'U';
 2187     EUR8[2] = 'R';
 2188 
 2189     CurrencyUnit cu(USD, ec);
 2190     assertSuccess("CurrencyUnit", ec);
 2191     assertEquals("getISOCurrency()", USD, cu.getISOCurrency());
 2192     assertEquals("getSubtype()", USD8, cu.getSubtype());
 2193 
 2194     // Test XYZ, a valid but non-standard currency.
 2195     // Note: Country code XY is private-use, so XYZ should remain unallocated.
 2196     CurrencyUnit extended(XYZ, ec);
 2197     assertSuccess("non-standard", ec);
 2198     assertEquals("non-standard", XYZ, extended.getISOCurrency());
 2199     assertEquals("non-standard", XYZ8, extended.getSubtype());
 2200 
 2201     CurrencyUnit inv(INV, ec);
 2202     assertEquals("non-invariant", U_INVARIANT_CONVERSION_ERROR, ec);
 2203     assertEquals("non-invariant", XXX, inv.getISOCurrency());
 2204     ec = U_ZERO_ERROR;
 2205 
 2206     CurrencyUnit zzz(ZZZ, ec);
 2207     assertEquals("too short", U_ILLEGAL_ARGUMENT_ERROR, ec);
 2208     assertEquals("too short", XXX, zzz.getISOCurrency());
 2209     ec = U_ZERO_ERROR;
 2210 
 2211     CurrencyUnit eur(EUR, ec);
 2212     assertEquals("non-nul-terminated", u"EUR", eur.getISOCurrency());
 2213     assertEquals("non-nul-terminated", "EUR", eur.getSubtype());
 2214 
 2215     // Test StringPiece constructor
 2216     CurrencyUnit cu8(USD8, ec);
 2217     assertEquals("StringPiece constructor", USD, cu8.getISOCurrency());
 2218 
 2219     CurrencyUnit inv8(INV8, ec);
 2220     assertEquals("non-invariant 8", U_INVARIANT_CONVERSION_ERROR, ec);
 2221     assertEquals("non-invariant 8", XXX, inv8.getISOCurrency());
 2222     ec = U_ZERO_ERROR;
 2223 
 2224     CurrencyUnit zzz8(ZZZ8, ec);
 2225     assertEquals("too short 8", U_ILLEGAL_ARGUMENT_ERROR, ec);
 2226     assertEquals("too short 8", XXX, zzz8.getISOCurrency());
 2227     ec = U_ZERO_ERROR;
 2228 
 2229     CurrencyUnit zzz8b({ZZZ8, 3}, ec);
 2230     assertEquals("too short 8b", U_ILLEGAL_ARGUMENT_ERROR, ec);
 2231     assertEquals("too short 8b", XXX, zzz8b.getISOCurrency());
 2232     ec = U_ZERO_ERROR;
 2233 
 2234     CurrencyUnit eur8({EUR8, 3}, ec);
 2235     assertEquals("non-nul-terminated 8", u"EUR", eur8.getISOCurrency());
 2236     assertEquals("non-nul-terminated 8", "EUR", eur8.getSubtype());
 2237 
 2238     CurrencyUnit cu2(cu);
 2239     if (!(cu2 == cu)){
 2240         errln("CurrencyUnit copy constructed object should be same");
 2241     }
 2242 
 2243     CurrencyUnit * cu3 = cu.clone();
 2244     if (!(*cu3 == cu)){
 2245         errln("CurrencyUnit cloned object should be same");
 2246     }
 2247     CurrencyUnit bad(BAD, ec);
 2248     assertSuccess("CurrencyUnit", ec);
 2249     if (cu.getIndex() == bad.getIndex()) {
 2250         errln("Indexes of different currencies should differ.");
 2251     }
 2252     CurrencyUnit bad2(BAD2, ec);
 2253     assertSuccess("CurrencyUnit", ec);
 2254     if (bad2.getIndex() != bad.getIndex()) {
 2255         errln("Indexes of unrecognized currencies should be the same.");
 2256     }
 2257     if (bad == bad2) {
 2258         errln("Different unrecognized currencies should not be equal.");
 2259     }
 2260     bad = bad2;
 2261     if (bad != bad2) {
 2262         errln("Currency unit assignment should be the same.");
 2263     }
 2264     delete cu3;
 2265 
 2266     // Test default constructor
 2267     CurrencyUnit def;
 2268     assertEquals("Default currency", XXX, def.getISOCurrency());
 2269     assertEquals("Default currency as subtype", XXX8, def.getSubtype());
 2270 
 2271     // Test slicing
 2272     MeasureUnit sliced1 = cu;
 2273     MeasureUnit sliced2 = cu;
 2274     MeasureUnit sliced3 = extended;
 2275     assertEquals("Subtype after slicing 1", USD8, sliced1.getSubtype());
 2276     assertEquals("Subtype after slicing 2", USD8, sliced2.getSubtype());
 2277     assertEquals("Subtype after slicing 3", XYZ8, sliced3.getSubtype());
 2278     CurrencyUnit restored1(sliced1, ec);
 2279     CurrencyUnit restored2(sliced2, ec);
 2280     CurrencyUnit restored3(sliced3, ec);
 2281     assertSuccess("Restoring from MeasureUnit", ec);
 2282     assertEquals("Subtype after restoring 1", USD8, restored1.getSubtype());
 2283     assertEquals("Subtype after restoring 2", USD8, restored2.getSubtype());
 2284     assertEquals("Subtype after restoring 3", XYZ8, restored3.getSubtype());
 2285     assertEquals("ISO Code after restoring 1", USD, restored1.getISOCurrency());
 2286     assertEquals("ISO Code after restoring 2", USD, restored2.getISOCurrency());
 2287     assertEquals("ISO Code after restoring 3", XYZ, restored3.getISOCurrency());
 2288 
 2289     // Test copy constructor failure
 2290     LocalPointer<MeasureUnit> meter(MeasureUnit::createMeter(ec));
 2291     assertSuccess("Creating meter", ec);
 2292     CurrencyUnit failure(*meter, ec);
 2293     assertEquals("Copying from meter should fail", ec, U_ILLEGAL_ARGUMENT_ERROR);
 2294     assertEquals("Copying should not give uninitialized ISO code", u"", failure.getISOCurrency());
 2295 
 2296     // Test equality
 2297     ec = U_ZERO_ERROR;
 2298     assertFalse("FAIL: USD == JPY", CurrencyUnit(USD, ec) == CurrencyUnit(JPY, ec));
 2299     assertTrue("FAIL: USD != USD",  CurrencyUnit(USD, ec) == CurrencyUnit(USD, ec));
 2300     assertTrue("FAIL: JPY != jpy",  CurrencyUnit(JPY, ec) == CurrencyUnit(jpy, ec));
 2301     assertTrue("FAIL: jpy != JPY",  CurrencyUnit(jpy, ec) == CurrencyUnit(JPY, ec));
 2302 
 2303     // Test equality with system charset instances
 2304     assertFalse("FAIL: USD8 == JPY8", CurrencyUnit(USD8, ec) == CurrencyUnit(JPY8, ec));
 2305     assertTrue("FAIL: USD8 != USD8",  CurrencyUnit(USD8, ec) == CurrencyUnit(USD8, ec));
 2306     assertTrue("FAIL: JPY8 != jpy8",  CurrencyUnit(JPY8, ec) == CurrencyUnit(jpy8, ec));
 2307     assertTrue("FAIL: jpy8 != JPY8",  CurrencyUnit(jpy8, ec) == CurrencyUnit(JPY8, ec));
 2308 
 2309     // Test equality between UTF-16 and system charset instances
 2310     assertTrue("FAIL: USD != USD8",  CurrencyUnit(USD, ec) == CurrencyUnit(USD8, ec));
 2311     assertTrue("FAIL: USD8 != USD",  CurrencyUnit(USD8, ec) == CurrencyUnit(USD, ec));
 2312     assertTrue("FAIL: JPY != jpy8",  CurrencyUnit(JPY, ec) == CurrencyUnit(jpy8, ec));
 2313     assertTrue("FAIL: JPY8 != jpy",  CurrencyUnit(JPY8, ec) == CurrencyUnit(jpy, ec));
 2314     assertTrue("FAIL: jpy != JPY8",  CurrencyUnit(jpy, ec) == CurrencyUnit(JPY8, ec));
 2315     assertTrue("FAIL: jpy8 != JPY",  CurrencyUnit(jpy8, ec) == CurrencyUnit(JPY, ec));
 2316 
 2317     free(EUR);
 2318     free(EUR8);
 2319 }
 2320 
 2321 void NumberFormatTest::TestCurrencyAmount(void){
 2322     UErrorCode ec = U_ZERO_ERROR;
 2323     static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
 2324     CurrencyAmount ca(9, USD, ec);
 2325     assertSuccess("CurrencyAmount", ec);
 2326 
 2327     CurrencyAmount ca2(ca);
 2328     if (!(ca2 == ca)){
 2329         errln("CurrencyAmount copy constructed object should be same");
 2330     }
 2331 
 2332     ca2=ca;
 2333     if (!(ca2 == ca)){
 2334         errln("CurrencyAmount assigned object should be same");
 2335     }
 2336 
 2337     CurrencyAmount *ca3 = ca.clone();
 2338     if (!(*ca3 == ca)){
 2339         errln("CurrencyAmount cloned object should be same");
 2340     }
 2341     delete ca3;
 2342 }
 2343 
 2344 void NumberFormatTest::TestSymbolsWithBadLocale(void) {
 2345     Locale locDefault;
 2346     static const char *badLocales[] = {
 2347         // length < ULOC_FULLNAME_CAPACITY
 2348         "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME",
 2349 
 2350         // length > ULOC_FULLNAME_CAPACITY
 2351         "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"
 2352     }; // expect U_USING_DEFAULT_WARNING for both
 2353 
 2354     unsigned int i;
 2355     for (i = 0; i < UPRV_LENGTHOF(badLocales); i++) {
 2356         const char *localeName = badLocales[i];
 2357         Locale locBad(localeName);
 2358         assertTrue(WHERE, !locBad.isBogus());
 2359         UErrorCode status = U_ZERO_ERROR;
 2360         UnicodeString intlCurrencySymbol((UChar)0xa4);
 2361 
 2362         intlCurrencySymbol.append((UChar)0xa4);
 2363 
 2364         logln("Current locale is %s", Locale::getDefault().getName());
 2365         Locale::setDefault(locBad, status);
 2366         logln("Current locale is %s", Locale::getDefault().getName());
 2367         DecimalFormatSymbols mySymbols(status);
 2368         if (status != U_USING_DEFAULT_WARNING) {
 2369             errln("DecimalFormatSymbols should return U_USING_DEFAULT_WARNING.");
 2370         }
 2371         if (strcmp(mySymbols.getLocale().getName(), locBad.getName()) != 0) {
 2372             errln("DecimalFormatSymbols does not have the right locale.", locBad.getName());
 2373         }
 2374         int symbolEnum = (int)DecimalFormatSymbols::kDecimalSeparatorSymbol;
 2375         for (; symbolEnum < (int)DecimalFormatSymbols::kFormatSymbolCount; symbolEnum++) {
 2376             UnicodeString symbolString = mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum);
 2377             logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum + UnicodeString("] = ") + prettify(symbolString));
 2378             if (symbolString.length() == 0
 2379                 && symbolEnum != (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
 2380                 && symbolEnum != (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol)
 2381             {
 2382                 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum);
 2383             }
 2384         }
 2385 
 2386         status = U_ZERO_ERROR;
 2387         Locale::setDefault(locDefault, status);
 2388         logln("Current locale is %s", Locale::getDefault().getName());
 2389     }
 2390 }
 2391 
 2392 /**
 2393  * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
 2394  * behave the same, except for memory ownership semantics. (No
 2395  * version of this test on Java, since Java has only one method.)
 2396  */
 2397 void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
 2398     UErrorCode ec = U_ZERO_ERROR;
 2399     DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), ec);
 2400     if (U_FAILURE(ec)) {
 2401         errcheckln(ec, "Fail: DecimalFormatSymbols constructor - %s", u_errorName(ec));
 2402         delete sym;
 2403         return;
 2404     }
 2405     UnicodeString pat(" #,##0.00");
 2406     pat.insert(0, (UChar)0x00A4);
 2407     DecimalFormat fmt(pat, sym, ec);
 2408     if (U_FAILURE(ec)) {
 2409         errln("Fail: DecimalFormat constructor");
 2410         return;
 2411     }
 2412 
 2413     UnicodeString str;
 2414     fmt.format(2350.75, str);
 2415     if (str == "$ 2,350.75") {
 2416         logln(str);
 2417     } else {
 2418         dataerrln("Fail: " + str + ", expected $ 2,350.75");
 2419     }
 2420 
 2421     sym = new DecimalFormatSymbols(Locale::getUS(), ec);
 2422     if (U_FAILURE(ec)) {
 2423         errln("Fail: DecimalFormatSymbols constructor");
 2424         delete sym;
 2425         return;
 2426     }
 2427     sym->setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
 2428     fmt.adoptDecimalFormatSymbols(sym);
 2429 
 2430     str.truncate(0);
 2431     fmt.format(2350.75, str);
 2432     if (str == "Q 2,350.75") {
 2433         logln(str);
 2434     } else {
 2435         dataerrln("Fail: adoptDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
 2436     }
 2437 
 2438     sym = new DecimalFormatSymbols(Locale::getUS(), ec);
 2439     if (U_FAILURE(ec)) {
 2440         errln("Fail: DecimalFormatSymbols constructor");
 2441         delete sym;
 2442         return;
 2443     }
 2444     DecimalFormat fmt2(pat, sym, ec);
 2445     if (U_FAILURE(ec)) {
 2446         errln("Fail: DecimalFormat constructor");
 2447         return;
 2448     }
 2449 
 2450     DecimalFormatSymbols sym2(Locale::getUS(), ec);
 2451     if (U_FAILURE(ec)) {
 2452         errln("Fail: DecimalFormatSymbols constructor");
 2453         return;
 2454     }
 2455     sym2.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
 2456     fmt2.setDecimalFormatSymbols(sym2);
 2457 
 2458     str.truncate(0);
 2459     fmt2.format(2350.75, str);
 2460     if (str == "Q 2,350.75") {
 2461         logln(str);
 2462     } else {
 2463         dataerrln("Fail: setDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
 2464     }
 2465 }
 2466 
 2467 void NumberFormatTest::TestPerMill() {
 2468     UErrorCode ec = U_ZERO_ERROR;
 2469     UnicodeString str;
 2470     DecimalFormat fmt(ctou("###.###\\u2030"), ec);
 2471     if (!assertSuccess("DecimalFormat ct", ec)) return;
 2472     assertEquals("0.4857 x ###.###\\u2030",
 2473                  ctou("485.7\\u2030"), fmt.format(0.4857, str), true);
 2474 
 2475     DecimalFormatSymbols sym(Locale::getUS(), ec);
 2476     if (!assertSuccess("", ec, true, __FILE__, __LINE__)) {
 2477         return;
 2478     }
 2479     sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, ctou("m"));
 2480     DecimalFormat fmt2("", sym, ec);
 2481     if (!assertSuccess("", ec, true, __FILE__, __LINE__)) {
 2482         return;
 2483     }
 2484     fmt2.applyLocalizedPattern("###.###m", ec);
 2485     if (!assertSuccess("setup", ec)) return;
 2486     str.truncate(0);
 2487     assertEquals("0.4857 x ###.###m",
 2488                  "485.7m", fmt2.format(0.4857, str));
 2489 }
 2490 
 2491 /**
 2492  * Generic test for patterns that should be legal/illegal.
 2493  */
 2494 void NumberFormatTest::TestIllegalPatterns() {
 2495     // Test cases:
 2496     // Prefix with "-:" for illegal patterns
 2497     // Prefix with "+:" for legal patterns
 2498     const char* DATA[] = {
 2499         // Unquoted special characters in the suffix are illegal
 2500         "-:000.000|###",
 2501         "+:000.000'|###'",
 2502         0
 2503     };
 2504     for (int32_t i=0; DATA[i]; ++i) {
 2505         const char* pat=DATA[i];
 2506         UBool valid = (*pat) == '+';
 2507         pat += 2;
 2508         UErrorCode ec = U_ZERO_ERROR;
 2509         DecimalFormat fmt(pat, ec); // locale doesn't matter here
 2510         if (U_SUCCESS(ec) == valid) {
 2511             logln("Ok: pattern \"%s\": %s",
 2512                   pat, u_errorName(ec));
 2513         } else {
 2514             errcheckln(ec, "FAIL: pattern \"%s\" should have %s; got %s",
 2515                   pat, (valid?"succeeded":"failed"),
 2516                   u_errorName(ec));
 2517         }
 2518     }
 2519 }
 2520 
 2521 //----------------------------------------------------------------------
 2522 
 2523 static const char* KEYWORDS[] = {
 2524     /*0*/ "ref=", // <reference pattern to parse numbers>
 2525     /*1*/ "loc=", // <locale for formats>
 2526     /*2*/ "f:",   // <pattern or '-'> <number> <exp. string>
 2527     /*3*/ "fp:",  // <pattern or '-'> <number> <exp. string> <exp. number>
 2528     /*4*/ "rt:",  // <pattern or '-'> <(exp.) number> <(exp.) string>
 2529     /*5*/ "p:",   // <pattern or '-'> <string> <exp. number>
 2530     /*6*/ "perr:", // <pattern or '-'> <invalid string>
 2531     /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
 2532     /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt>
 2533     0
 2534 };
 2535 
 2536 /**
 2537  * Return an integer representing the next token from this
 2538  * iterator.  The integer will be an index into the given list, or
 2539  * -1 if there are no more tokens, or -2 if the token is not on
 2540  * the list.
 2541  */
 2542 static int32_t keywordIndex(const UnicodeString& tok) {
 2543     for (int32_t i=0; KEYWORDS[i]!=0; ++i) {
 2544         if (tok==KEYWORDS[i]) {
 2545             return i;
 2546         }
 2547     }
 2548     return -1;
 2549 }
 2550 
 2551 /**
 2552  * Parse a CurrencyAmount using the given NumberFormat, with
 2553  * the 'delim' character separating the number and the currency.
 2554  */
 2555 static void parseCurrencyAmount(const UnicodeString& str,
 2556                                 const NumberFormat& fmt,
 2557                                 UChar delim,
 2558                                 Formattable& result,
 2559                                 UErrorCode& ec) {
 2560     UnicodeString num, cur;
 2561     int32_t i = str.indexOf(delim);
 2562     str.extractBetween(0, i, num);
 2563     str.extractBetween(i+1, INT32_MAX, cur);
 2564     Formattable n;
 2565     fmt.parse(num, n, ec);
 2566     result.adoptObject(new CurrencyAmount(n, cur.getTerminatedBuffer(), ec));
 2567 }
 2568 
 2569 void NumberFormatTest::TestCases() {
 2570     UErrorCode ec = U_ZERO_ERROR;
 2571     TextFile reader("NumberFormatTestCases.txt", "UTF8", ec);
 2572     if (U_FAILURE(ec)) {
 2573         dataerrln("Couldn't open NumberFormatTestCases.txt");
 2574         return;
 2575     }
 2576     TokenIterator tokens(&reader);
 2577 
 2578     Locale loc("en", "US", "");
 2579     DecimalFormat *ref = 0, *fmt = 0;
 2580     MeasureFormat *mfmt = 0;
 2581     UnicodeString pat, tok, mloc, str, out, where, currAmt;
 2582     Formattable n;
 2583 
 2584     for (;;) {
 2585         ec = U_ZERO_ERROR;
 2586         if (!tokens.next(tok, ec)) {
 2587             break;
 2588         }
 2589         where = UnicodeString("(") + tokens.getLineNumber() + ") ";
 2590         int32_t cmd = keywordIndex(tok);
 2591         switch (cmd) {
 2592         case 0:
 2593             // ref= <reference pattern>
 2594             if (!tokens.next(tok, ec)) goto error;
 2595             delete ref;
 2596             ref = new DecimalFormat(tok,
 2597                       new DecimalFormatSymbols(Locale::getUS(), ec), ec);
 2598             if (U_FAILURE(ec)) {
 2599                 dataerrln("Error constructing DecimalFormat");
 2600                 goto error;
 2601             }
 2602             break;
 2603         case 1:
 2604             // loc= <locale>
 2605             if (!tokens.next(tok, ec)) goto error;
 2606             loc = Locale::createFromName(CharString().appendInvariantChars(tok, ec).data());
 2607             break;
 2608         case 2: // f:
 2609         case 3: // fp:
 2610         case 4: // rt:
 2611         case 5: // p:
 2612             if (!tokens.next(tok, ec)) goto error;
 2613             if (tok != "-") {
 2614                 pat = tok;
 2615                 delete fmt;
 2616                 fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc, ec), ec);
 2617                 if (U_FAILURE(ec)) {
 2618                     errln("FAIL: " + where + "Pattern \"" + pat + "\": " + u_errorName(ec));
 2619                     ec = U_ZERO_ERROR;
 2620                     if (!tokens.next(tok, ec)) goto error;
 2621                     if (!tokens.next(tok, ec)) goto error;
 2622                     if (cmd == 3) {
 2623                         if (!tokens.next(tok, ec)) goto error;
 2624                     }
 2625                     continue;
 2626                 }
 2627             }
 2628             if (cmd == 2 || cmd == 3 || cmd == 4) {
 2629                 // f: <pattern or '-'> <number> <exp. string>
 2630                 // fp: <pattern or '-'> <number> <exp. string> <exp. number>
 2631                 // rt: <pattern or '-'> <number> <string>
 2632                 UnicodeString num;
 2633                 if (!tokens.next(num, ec)) goto error;
 2634                 if (!tokens.next(str, ec)) goto error;
 2635                 ref->parse(num, n, ec);
 2636                 assertSuccess("parse", ec);
 2637                 assertEquals(where + "\"" + pat + "\".format(" + num + ")",
 2638                              str, fmt->format(n, out.remove(), ec));
 2639                 assertSuccess("format", ec);
 2640                 if (cmd == 3) { // fp:
 2641                     if (!tokens.next(num, ec)) goto error;
 2642                     ref->parse(num, n, ec);
 2643                     assertSuccess("parse", ec);
 2644                 }
 2645                 if (cmd != 2) { // != f:
 2646                     Formattable m;
 2647                     fmt->parse(str, m, ec);
 2648                     assertSuccess("parse", ec);
 2649                     assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
 2650                                  n, m);
 2651                 }
 2652             }
 2653             // p: <pattern or '-'> <string to parse> <exp. number>
 2654             else {
 2655                 UnicodeString expstr;
 2656                 if (!tokens.next(str, ec)) goto error;
 2657                 if (!tokens.next(expstr, ec)) goto error;
 2658                 Formattable exp, n;
 2659                 ref->parse(expstr, exp, ec);
 2660                 assertSuccess("parse", ec);
 2661                 fmt->parse(str, n, ec);
 2662                 assertSuccess("parse", ec);
 2663                 assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
 2664                              exp, n);
 2665             }
 2666             break;
 2667         case 8: // fpc:
 2668             if (!tokens.next(tok, ec)) goto error;
 2669             if (tok != "-") {
 2670                 mloc = tok;
 2671                 delete mfmt;
 2672                 mfmt = MeasureFormat::createCurrencyFormat(
 2673                     Locale::createFromName(
 2674                         CharString().appendInvariantChars(mloc, ec).data()), ec);
 2675                 if (U_FAILURE(ec)) {
 2676                     errln("FAIL: " + where + "Loc \"" + mloc + "\": " + u_errorName(ec));
 2677                     ec = U_ZERO_ERROR;
 2678                     if (!tokens.next(tok, ec)) goto error;
 2679                     if (!tokens.next(tok, ec)) goto error;
 2680                     if (!tokens.next(tok, ec)) goto error;
 2681                     continue;
 2682                 }
 2683             } else if (mfmt == NULL) {
 2684                 errln("FAIL: " + where + "Loc \"" + mloc + "\": skip case using previous locale, no valid MeasureFormat");
 2685                 if (!tokens.next(tok, ec)) goto error;
 2686                 if (!tokens.next(tok, ec)) goto error;
 2687                 if (!tokens.next(tok, ec)) goto error;
 2688                 continue;
 2689             }
 2690             // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
 2691             if (!tokens.next(currAmt, ec)) goto error;
 2692             if (!tokens.next(str, ec)) goto error;
 2693             parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
 2694             if (assertSuccess("parseCurrencyAmount", ec)) {
 2695                 assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")",
 2696                              str, mfmt->format(n, out.remove(), ec));
 2697                 assertSuccess("format", ec);
 2698             }
 2699             if (!tokens.next(currAmt, ec)) goto error;
 2700             parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
 2701             if (assertSuccess("parseCurrencyAmount", ec)) {
 2702                 Formattable m;
 2703 
 2704                 mfmt->parseObject(str, m, ec);
 2705                 if (assertSuccess("parseCurrency", ec)) {
 2706                     assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",
 2707                                  n, m);
 2708                 } else {
 2709                     errln("FAIL: source " + str);
 2710                 }
 2711             }
 2712             break;
 2713         case 6:
 2714             // perr: <pattern or '-'> <invalid string>
 2715             errln("FAIL: Under construction");
 2716             goto done;
 2717         case 7: {
 2718             // pat: <pattern> <exp. toPattern, or '-' or 'err'>
 2719             UnicodeString testpat;
 2720             UnicodeString exppat;
 2721             if (!tokens.next(testpat, ec)) goto error;
 2722             if (!tokens.next(exppat, ec)) goto error;
 2723             UBool err = exppat == "err";
 2724             UBool existingPat = FALSE;
 2725             if (testpat == "-") {
 2726                 if (err) {
 2727                     errln("FAIL: " + where + "Invalid command \"pat: - err\"");
 2728                     continue;
 2729                 }
 2730                 existingPat = TRUE;
 2731                 testpat = pat;
 2732             }
 2733             if (exppat == "-") exppat = testpat;
 2734             DecimalFormat* f = 0;
 2735             UErrorCode ec2 = U_ZERO_ERROR;
 2736             if (existingPat) {
 2737                 f = fmt;
 2738             } else {
 2739                 f = new DecimalFormat(testpat, ec2);
 2740             }
 2741             if (U_SUCCESS(ec2)) {
 2742                 if (err) {
 2743                     errln("FAIL: " + where + "Invalid pattern \"" + testpat +
 2744                           "\" was accepted");
 2745                 } else {
 2746                     UnicodeString pat2;
 2747                     assertEquals(where + "\"" + testpat + "\".toPattern()",
 2748                                  exppat, f->toPattern(pat2));
 2749                 }
 2750             } else {
 2751                 if (err) {
 2752                     logln("Ok: " + where + "Invalid pattern \"" + testpat +
 2753                           "\" failed: " + u_errorName(ec2));
 2754                 } else {
 2755                     errln("FAIL: " + where + "Valid pattern \"" + testpat +
 2756                           "\" failed: " + u_errorName(ec2));
 2757                 }
 2758             }
 2759             if (!existingPat) delete f;
 2760             } break;
 2761         case -1:
 2762             errln("FAIL: " + where + "Unknown command \"" + tok + "\"");
 2763             goto done;
 2764         }
 2765     }
 2766     goto done;
 2767 
 2768  error:
 2769     if (U_SUCCESS(ec)) {
 2770         errln("FAIL: Unexpected EOF");
 2771     } else {
 2772         errcheckln(ec, "FAIL: " + where + "Unexpected " + u_errorName(ec));
 2773     }
 2774 
 2775  done:
 2776     delete mfmt;
 2777     delete fmt;
 2778     delete ref;
 2779 }
 2780 
 2781 
 2782 //----------------------------------------------------------------------
 2783 // Support methods
 2784 //----------------------------------------------------------------------
 2785 
 2786 UBool NumberFormatTest::equalValue(const Formattable& a, const Formattable& b) {
 2787     if (a.getType() == b.getType()) {
 2788         return a == b;
 2789     }
 2790 
 2791     if (a.getType() == Formattable::kLong) {
 2792         if (b.getType() == Formattable::kInt64) {
 2793             return a.getLong() == b.getLong();
 2794         } else if (b.getType() == Formattable::kDouble) {
 2795             return (double) a.getLong() == b.getDouble(); // TODO check use of double instead of long
 2796         }
 2797     } else if (a.getType() == Formattable::kDouble) {
 2798         if (b.getType() == Formattable::kLong) {
 2799             return a.getDouble() == (double) b.getLong();
 2800         } else if (b.getType() == Formattable::kInt64) {
 2801             return a.getDouble() == (double)b.getInt64();
 2802         }
 2803     } else if (a.getType() == Formattable::kInt64) {
 2804         if (b.getType() == Formattable::kLong) {
 2805                 return a.getInt64() == (int64_t)b.getLong();
 2806         } else if (b.getType() == Formattable::kDouble) {
 2807             return a.getInt64() == (int64_t)b.getDouble();
 2808         }
 2809     }
 2810     return FALSE;
 2811 }
 2812 
 2813 void NumberFormatTest::expect3(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
 2814     // Don't round-trip format test, since we explicitly do it
 2815     expect_rbnf(fmt, n, str, FALSE);
 2816     expect_rbnf(fmt, str, n);
 2817 }
 2818 
 2819 void NumberFormatTest::expect2(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
 2820     // Don't round-trip format test, since we explicitly do it
 2821     expect(fmt, n, str, FALSE);
 2822     expect(fmt, str, n);
 2823 }
 2824 
 2825 void NumberFormatTest::expect2(NumberFormat* fmt, const Formattable& n,
 2826                                const UnicodeString& exp,
 2827                                UErrorCode status) {
 2828     if (fmt == NULL || U_FAILURE(status)) {
 2829         dataerrln("FAIL: NumberFormat constructor");
 2830     } else {
 2831         expect2(*fmt, n, exp);
 2832     }
 2833     delete fmt;
 2834 }
 2835 
 2836 void NumberFormatTest::expect(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
 2837     UErrorCode status = U_ZERO_ERROR;
 2838     Formattable num;
 2839     fmt.parse(str, num, status);
 2840     if (U_FAILURE(status)) {
 2841         dataerrln(UnicodeString("FAIL: Parse failed for \"") + str + "\" - " + u_errorName(status));
 2842         return;
 2843     }
 2844     UnicodeString pat;
 2845     ((DecimalFormat*) &fmt)->toPattern(pat);
 2846     if (equalValue(num, n)) {
 2847         logln(UnicodeString("Ok   \"") + str + "\" x " +
 2848               pat + " = " +
 2849               toString(num));
 2850     } else {
 2851         dataerrln(UnicodeString("FAIL \"") + str + "\" x " +
 2852               pat + " = " +
 2853               toString(num) + ", expected " + toString(n));
 2854     }
 2855 }
 2856 
 2857 void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
 2858     UErrorCode status = U_ZERO_ERROR;
 2859     Formattable num;
 2860     fmt.parse(str, num, status);
 2861     if (U_FAILURE(status)) {
 2862         errln(UnicodeString("FAIL: Parse failed for \"") + str + "\"");
 2863         return;
 2864     }
 2865     if (equalValue(num, n)) {
 2866         logln(UnicodeString("Ok   \"") + str + " = " +
 2867               toString(num));
 2868     } else {
 2869         errln(UnicodeString("FAIL \"") + str + " = " +
 2870               toString(num) + ", expected " + toString(n));
 2871     }
 2872 }
 2873 
 2874 void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const Formattable& n,
 2875                               const UnicodeString& exp, UBool rt) {
 2876     UnicodeString saw;
 2877     FieldPosition pos;
 2878     UErrorCode status = U_ZERO_ERROR;
 2879     fmt.format(n, saw, pos, status);
 2880     CHECK(status, "NumberFormat::format");
 2881     if (saw == exp) {
 2882         logln(UnicodeString("Ok   ") + toString(n) +
 2883               " = \"" +
 2884               escape(saw) + "\"");
 2885         // We should be able to round-trip the formatted string =>
 2886         // number => string (but not the other way around: number
 2887         // => string => number2, might have number2 != number):
 2888         if (rt) {
 2889             Formattable n2;
 2890             fmt.parse(exp, n2, status);
 2891             if (U_FAILURE(status)) {
 2892                 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\"");
 2893                 return;
 2894             }
 2895             UnicodeString saw2;
 2896             fmt.format(n2, saw2, pos, status);
 2897             CHECK(status, "NumberFormat::format");
 2898             if (saw2 != exp) {
 2899                 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
 2900                       " => \"" + saw2 + "\"");
 2901             }
 2902         }
 2903     } else {
 2904         errln(UnicodeString("FAIL ") + toString(n) +
 2905               " = \"" +
 2906               escape(saw) + "\", expected \"" + exp + "\"");
 2907     }
 2908 }
 2909 
 2910 void NumberFormatTest::expect(NumberFormat& fmt, const Formattable& n,
 2911                               const UnicodeString& exp, UBool rt) {
 2912     UnicodeString saw;
 2913     FieldPosition pos;
 2914     UErrorCode status = U_ZERO_ERROR;
 2915     fmt.format(n, saw, pos, status);
 2916     CHECK(status, "NumberFormat::format");
 2917     UnicodeString pat;
 2918     ((DecimalFormat*) &fmt)->toPattern(pat);
 2919     if (saw == exp) {
 2920         logln(UnicodeString("Ok   ") + toString(n) + " x " +
 2921               escape(pat) + " = \"" +
 2922               escape(saw) + "\"");
 2923         // We should be able to round-trip the formatted string =>
 2924         // number => string (but not the other way around: number
 2925         // => string => number2, might have number2 != number):
 2926         if (rt) {
 2927             Formattable n2;
 2928             fmt.parse(exp, n2, status);
 2929             if (U_FAILURE(status)) {
 2930                 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\" - " + u_errorName(status));
 2931                 return;
 2932             }
 2933             UnicodeString saw2;
 2934             fmt.format(n2, saw2, pos, status);
 2935             CHECK(status, "NumberFormat::format");
 2936             if (saw2 != exp) {
 2937                 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
 2938                       " => \"" + saw2 + "\"");
 2939             }
 2940         }
 2941     } else {
 2942         dataerrln(UnicodeString("FAIL ") + toString(n) + " x " +
 2943               escape(pat) + " = \"" +
 2944               escape(saw) + "\", expected \"" + exp + "\"");
 2945     }
 2946 }
 2947 
 2948 void NumberFormatTest::expect(NumberFormat* fmt, const Formattable& n,
 2949                               const UnicodeString& exp, UBool rt,
 2950                               UErrorCode status) {
 2951     if (fmt == NULL || U_FAILURE(status)) {
 2952         dataerrln("FAIL: NumberFormat constructor");
 2953     } else {
 2954         expect(*fmt, n, exp, rt);
 2955     }
 2956     delete fmt;
 2957 }
 2958 
 2959 void NumberFormatTest::expectCurrency(NumberFormat& nf, const Locale& locale,
 2960                                       double value, const UnicodeString& string) {
 2961     UErrorCode ec = U_ZERO_ERROR;
 2962     DecimalFormat& fmt = * (DecimalFormat*) &nf;
 2963     const UChar DEFAULT_CURR[] = {45/*-*/,0};
 2964     UChar curr[4];
 2965     u_strcpy(curr, DEFAULT_CURR);
 2966     if (*locale.getLanguage() != 0) {
 2967         ucurr_forLocale(locale.getName(), curr, 4, &ec);
 2968         assertSuccess("ucurr_forLocale", ec);
 2969         fmt.setCurrency(curr, ec);
 2970         assertSuccess("DecimalFormat::setCurrency", ec);
 2971         fmt.setCurrency(curr); //Deprecated variant, for coverage only
 2972     }
 2973     UnicodeString s;
 2974     fmt.format(value, s);
 2975     s.findAndReplace((UChar32)0x00A0, (UChar32)0x0020);
 2976 
 2977     // Default display of the number yields "1234.5599999999999"
 2978     // instead of "1234.56".  Use a formatter to fix this.
 2979     NumberFormat* f =
 2980         NumberFormat::createInstance(Locale::getUS(), ec);
 2981     UnicodeString v;
 2982     if (U_FAILURE(ec)) {
 2983         // Oops; bad formatter.  Use default op+= display.
 2984         v = (UnicodeString)"" + value;
 2985     } else {
 2986         f->setMaximumFractionDigits(4);
 2987         f->setGroupingUsed(FALSE);
 2988         f->format(value, v);
 2989     }
 2990     delete f;
 2991 
 2992     if (s == string) {
 2993         logln((UnicodeString)"Ok: " + v + " x " + curr + " => " + prettify(s));
 2994     } else {
 2995         errln((UnicodeString)"FAIL: " + v + " x " + curr + " => " + prettify(s) +
 2996               ", expected " + prettify(string));
 2997     }
 2998 }
 2999 
 3000 void NumberFormatTest::expectPat(DecimalFormat& fmt, const UnicodeString& exp) {
 3001     UnicodeString pat;
 3002     fmt.toPattern(pat);
 3003     if (pat == exp) {
 3004         logln(UnicodeString("Ok   \"") + pat + "\"");
 3005     } else {
 3006         errln(UnicodeString("FAIL \"") + pat + "\", expected \"" + exp + "\"");
 3007     }
 3008 }
 3009 
 3010 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
 3011                                  int32_t pos) {
 3012     expectPad(fmt, pat, pos, 0, (UnicodeString)"");
 3013 }
 3014 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
 3015                                  int32_t pos, int32_t width, UChar pad) {
 3016     expectPad(fmt, pat, pos, width, UnicodeString(pad));
 3017 }
 3018 void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
 3019                                  int32_t pos, int32_t width, const UnicodeString& pad) {
 3020     int32_t apos = 0, awidth = 0;
 3021     UnicodeString apadStr;
 3022     UErrorCode status = U_ZERO_ERROR;
 3023     fmt.applyPattern(pat, status);
 3024     if (U_SUCCESS(status)) {
 3025         apos = fmt.getPadPosition();
 3026         awidth = fmt.getFormatWidth();
 3027         apadStr=fmt.getPadCharacterString();
 3028     } else {
 3029         apos = -1;
 3030         awidth = width;
 3031         apadStr = pad;
 3032     }
 3033     if (apos == pos && awidth == width && apadStr == pad) {
 3034         UnicodeString infoStr;
 3035         if (pos == ILLEGAL) {
 3036             infoStr = UnicodeString(" width=", "") + awidth + UnicodeString(" pad=", "") + apadStr;
 3037         }
 3038         logln(UnicodeString("Ok   \"") + pat + "\" pos=" + apos + infoStr);
 3039     } else {
 3040         errln(UnicodeString("FAIL \"") + pat + "\" pos=" + apos +
 3041               " width=" + awidth + " pad=" + apadStr +
 3042               ", expected " + pos + " " + width + " " + pad);
 3043     }
 3044 }
 3045 
 3046 // This test is flaky b/c the symbols for CNY and JPY are equivalent in this locale  - FIXME
 3047 void NumberFormatTest::TestCompatibleCurrencies() {
 3048 /*
 3049     static const UChar JPY[] = {0x4A, 0x50, 0x59, 0};
 3050     static const UChar CNY[] = {0x43, 0x4E, 0x59, 0};
 3051     UErrorCode status = U_ZERO_ERROR;
 3052     LocalPointer<NumberFormat> fmt(
 3053         NumberFormat::createCurrencyInstance(Locale::getUS(), status));
 3054     if (U_FAILURE(status)) {
 3055         errln("Could not create number format instance.");
 3056         return;
 3057     }
 3058     logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
 3059     expectParseCurrency(*fmt, JPY, 1235,  "\\u00A51,235");
 3060     logln("%s:%d - testing parse of fullwidth yen sign\n", __FILE__, __LINE__);
 3061     expectParseCurrency(*fmt, JPY, 1235,  "\\uFFE51,235");
 3062     logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
 3063     expectParseCurrency(*fmt, CNY, 1235,  "CN\\u00A51,235");
 3064 
 3065     LocalPointer<NumberFormat> fmtTW(
 3066         NumberFormat::createCurrencyInstance(Locale::getTaiwan(), status));
 3067 
 3068     logln("%s:%d - testing parse of halfwidth yen sign in TW\n", __FILE__, __LINE__);
 3069     expectParseCurrency(*fmtTW, CNY, 1235,  "\\u00A51,235");
 3070     logln("%s:%d - testing parse of fullwidth yen sign in TW\n", __FILE__, __LINE__);
 3071     expectParseCurrency(*fmtTW, CNY, 1235,  "\\uFFE51,235");
 3072 
 3073     LocalPointer<NumberFormat> fmtJP(
 3074         NumberFormat::createCurrencyInstance(Locale::getJapan(), status));
 3075 
 3076     logln("%s:%d - testing parse of halfwidth yen sign in JP\n", __FILE__, __LINE__);
 3077     expectParseCurrency(*fmtJP, JPY, 1235,  "\\u00A51,235");
 3078     logln("%s:%d - testing parse of fullwidth yen sign in JP\n", __FILE__, __LINE__);
 3079     expectParseCurrency(*fmtJP, JPY, 1235,  "\\uFFE51,235");
 3080 
 3081     // more..
 3082 */
 3083 }
 3084 
 3085 void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar* currency, double amount, const char *text) {
 3086     ParsePosition ppos;
 3087     UnicodeString utext = ctou(text);
 3088     LocalPointer<CurrencyAmount> currencyAmount(fmt.parseCurrency(utext, ppos));
 3089     if (!ppos.getIndex()) {
 3090         errln(UnicodeString("Parse of ") + utext + " should have succeeded.");
 3091         return;
 3092     }
 3093     UErrorCode status = U_ZERO_ERROR;
 3094 
 3095     char theInfo[100];
 3096     sprintf(theInfo, "For locale %s, string \"%s\", currency ",
 3097             fmt.getLocale(ULOC_ACTUAL_LOCALE, status).getBaseName(),
 3098             text);
 3099     u_austrcpy(theInfo+uprv_strlen(theInfo), currency);
 3100 
 3101     char theOperation[100];
 3102 
 3103     uprv_strcpy(theOperation, theInfo);
 3104     uprv_strcat(theOperation, ", check amount:");
 3105     assertTrue(theOperation, amount ==  currencyAmount->getNumber().getDouble(status));
 3106 
 3107     uprv_strcpy(theOperation, theInfo);
 3108     uprv_strcat(theOperation, ", check currency:");
 3109     assertEquals(theOperation, currency, currencyAmount->getISOCurrency());
 3110 }
 3111 
 3112 
 3113 void NumberFormatTest::TestJB3832(){
 3114     const char* localeID = "pt_PT@currency=PTE";
 3115     Locale loc(localeID);
 3116     UErrorCode status = U_ZERO_ERROR;
 3117     UnicodeString expected(CharsToUnicodeString("1,150$50\\u00A0\\u200B")); // per cldrbug 7670
 3118     UnicodeString s;
 3119     NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(loc, status);
 3120     if(U_FAILURE(status)){
 3121         dataerrln("Could not create currency formatter for locale %s - %s", localeID, u_errorName(status));
 3122         return;
 3123     }
 3124     currencyFmt->format(1150.50, s);
 3125     if(s!=expected){
 3126         errln(UnicodeString("FAIL: Expected: ")+expected
 3127                 + UnicodeString(" Got: ") + s
 3128                 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
 3129     }
 3130     if (U_FAILURE(status)){
 3131         errln("FAIL: Status %s", u_errorName(status));
 3132     }
 3133     delete currencyFmt;
 3134 }
 3135 
 3136 void NumberFormatTest::TestHost()
 3137 {
 3138 #if U_PLATFORM_USES_ONLY_WIN32_API
 3139     Win32NumberTest::testLocales(this);
 3140 #endif
 3141     Locale loc("en_US@compat=host");
 3142     for (UNumberFormatStyle k = UNUM_DECIMAL;
 3143          k < UNUM_FORMAT_STYLE_COUNT; k = (UNumberFormatStyle)(k+1)) {
 3144         UErrorCode status = U_ZERO_ERROR;
 3145         LocalPointer<NumberFormat> full(NumberFormat::createInstance(loc, k, status));
 3146         if (!NumberFormat::isStyleSupported(k)) {
 3147             if (status != U_UNSUPPORTED_ERROR) {
 3148                 errln("FAIL: expected style %d to be unsupported - %s",
 3149                       k, u_errorName(status));
 3150             }
 3151             continue;
 3152         }
 3153         if (full.isNull() || U_FAILURE(status)) {
 3154             dataerrln("FAIL: Can't create number instance of style %d for host - %s",
 3155                       k, u_errorName(status));
 3156             return;
 3157         }
 3158         UnicodeString result1;
 3159         Formattable number(10.00);
 3160         full->format(number, result1, status);
 3161         if (U_FAILURE(status)) {
 3162             errln("FAIL: Can't format for host");
 3163             return;
 3164         }
 3165         Formattable formattable;
 3166         full->parse(result1, formattable, status);
 3167         if (U_FAILURE(status)) {
 3168             errln("FAIL: Can't parse for host");
 3169             return;
 3170         }
 3171     }
 3172 }
 3173 
 3174 void NumberFormatTest::TestHostClone()
 3175 {
 3176     /*
 3177     Verify that a cloned formatter gives the same results
 3178     and is useable after the original has been deleted.
 3179     */
 3180     // This is mainly important on Windows.
 3181     UErrorCode status = U_ZERO_ERROR;
 3182     Locale loc("en_US@compat=host");
 3183     UDate now = Calendar::getNow();
 3184     NumberFormat *full = NumberFormat::createInstance(loc, status);
 3185     if (full == NULL || U_FAILURE(status)) {
 3186         dataerrln("FAIL: Can't create NumberFormat date instance - %s", u_errorName(status));
 3187         return;
 3188     }
 3189     UnicodeString result1;
 3190     full->format(now, result1, status);
 3191     Format *fullClone = full->clone();
 3192     delete full;
 3193     full = NULL;
 3194 
 3195     UnicodeString result2;
 3196     fullClone->format(now, result2, status);
 3197     if (U_FAILURE(status)) {
 3198         errln("FAIL: format failure.");
 3199     }
 3200     if (result1 != result2) {
 3201         errln("FAIL: Clone returned different result from non-clone.");
 3202     }
 3203     delete fullClone;
 3204 }
 3205 
 3206 void NumberFormatTest::TestCurrencyFormat()
 3207 {
 3208     // This test is here to increase code coverage.
 3209     UErrorCode status = U_ZERO_ERROR;
 3210     MeasureFormat *cloneObj;
 3211     UnicodeString str;
 3212     Formattable toFormat, result;
 3213     static const UChar ISO_CODE[4] = {0x0047, 0x0042, 0x0050, 0};
 3214 
 3215     Locale  saveDefaultLocale = Locale::getDefault();
 3216     Locale::setDefault( Locale::getUK(), status );
 3217     if (U_FAILURE(status)) {
 3218         errln("couldn't set default Locale!");
 3219         return;
 3220     }
 3221 
 3222     MeasureFormat *measureObj = MeasureFormat::createCurrencyFormat(status);
 3223     Locale::setDefault( saveDefaultLocale, status );
 3224     if (U_FAILURE(status)){
 3225         dataerrln("FAIL: Status %s", u_errorName(status));
 3226         return;
 3227     }
 3228     cloneObj = measureObj->clone();
 3229     if (cloneObj == NULL) {
 3230         errln("Clone doesn't work");
 3231         return;
 3232     }
 3233     toFormat.adoptObject(new CurrencyAmount(1234.56, ISO_CODE, status));
 3234     measureObj->format(toFormat, str, status);
 3235     measureObj->parseObject(str, result, status);
 3236     if (U_FAILURE(status)){
 3237         errln("FAIL: Status %s", u_errorName(status));
 3238     }
 3239     if (result != toFormat) {
 3240         errln("measureObj does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
 3241     }
 3242     status = U_ZERO_ERROR;
 3243     str.truncate(0);
 3244     cloneObj->format(toFormat, str, status);
 3245     cloneObj->parseObject(str, result, status);
 3246     if (U_FAILURE(status)){
 3247         errln("FAIL: Status %s", u_errorName(status));
 3248     }
 3249     if (result != toFormat) {
 3250         errln("Clone does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
 3251     }
 3252     if (*measureObj != *cloneObj) {
 3253         errln("Cloned object is not equal to the original object");
 3254     }
 3255     delete measureObj;
 3256     delete cloneObj;
 3257 
 3258     status = U_USELESS_COLLATOR_ERROR;
 3259     if (MeasureFormat::createCurrencyFormat(status) != NULL) {
 3260         errln("createCurrencyFormat should have returned NULL.");
 3261     }
 3262 }
 3263 
 3264 /* Port of ICU4J rounding test. */
 3265 void NumberFormatTest::TestRounding() {
 3266     UErrorCode status = U_ZERO_ERROR;
 3267     DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
 3268 
 3269     if (U_FAILURE(status)) {
 3270         dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
 3271         return;
 3272     }
 3273 
 3274     int roundingIncrements[]={1, 2, 5, 20, 50, 100};
 3275     int testValues[]={0, 300};
 3276 
 3277     for (int j=0; j<2; j++) {
 3278         for (int mode=DecimalFormat::kRoundUp;mode<DecimalFormat::kRoundHalfEven;mode++) {
 3279             df->setRoundingMode((DecimalFormat::ERoundingMode)mode);
 3280             for (int increment=0; increment<6; increment++) {
 3281                 double base=testValues[j];
 3282                 double rInc=roundingIncrements[increment];
 3283                 checkRounding(df, base, 20, rInc);
 3284                 rInc=1.000000000/rInc;
 3285                 checkRounding(df, base, 20, rInc);
 3286             }
 3287         }
 3288     }
 3289     delete df;
 3290 }
 3291 
 3292 void NumberFormatTest::TestRoundingPattern() {
 3293     UErrorCode status = U_ZERO_ERROR;
 3294     struct {
 3295         UnicodeString  pattern;
 3296         double        testCase;
 3297         UnicodeString expected;
 3298     } tests[] = {
 3299             { (UnicodeString)"##0.65", 1.234, (UnicodeString)"1.30" },
 3300             { (UnicodeString)"#50",    1230,  (UnicodeString)"1250" }
 3301     };
 3302     int32_t numOfTests = UPRV_LENGTHOF(tests);
 3303     UnicodeString result;
 3304 
 3305     DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
 3306     if (U_FAILURE(status)) {
 3307         dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
 3308         return;
 3309     }
 3310 
 3311     for (int32_t i = 0; i < numOfTests; i++) {
 3312         result.remove();
 3313 
 3314         df->applyPattern(tests[i].pattern, status);
 3315         if (U_FAILURE(status)) {
 3316             errln("Unable to apply pattern to decimal formatter. - %s", u_errorName(status));
 3317         }
 3318 
 3319         df->format(tests[i].testCase, result);
 3320 
 3321         if (result != tests[i].expected) {
 3322             errln("String Pattern Rounding Test Failed: Pattern: \"" + tests[i].pattern + "\" Number: " + tests[i].testCase + " - Got: " + result + " Expected: " + tests[i].expected);
 3323         }
 3324     }
 3325 
 3326     delete df;
 3327 }
 3328 
 3329 void NumberFormatTest::checkRounding(DecimalFormat* df, double base, int iterations, double increment) {
 3330     df->setRoundingIncrement(increment);
 3331     double lastParsed=INT32_MIN; //Intger.MIN_VALUE
 3332     for (int i=-iterations; i<=iterations;i++) {
 3333         double iValue=base+(increment*(i*0.1));
 3334         double smallIncrement=0.00000001;
 3335         if (iValue!=0) {
 3336             smallIncrement*=iValue;
 3337         }
 3338         //we not only test the value, but some values in a small range around it
 3339         lastParsed=checkRound(df, iValue-smallIncrement, lastParsed);
 3340         lastParsed=checkRound(df, iValue, lastParsed);
 3341         lastParsed=checkRound(df, iValue+smallIncrement, lastParsed);
 3342     }
 3343 }
 3344 
 3345 double NumberFormatTest::checkRound(DecimalFormat* df, double iValue, double lastParsed) {
 3346     UErrorCode status=U_ZERO_ERROR;
 3347     UnicodeString formattedDecimal;
 3348     double parsed;
 3349     Formattable result;
 3350     df->format(iValue, formattedDecimal, status);
 3351 
 3352     if (U_FAILURE(status)) {
 3353         errln("Error formatting number.");
 3354     }
 3355 
 3356     df->parse(formattedDecimal, result, status);
 3357 
 3358     if (U_FAILURE(status)) {
 3359         errln("Error parsing number.");
 3360     }
 3361 
 3362     parsed=result.getDouble();
 3363 
 3364     if (lastParsed>parsed) {
 3365         errln("Rounding wrong direction! %d > %d", lastParsed, parsed);
 3366     }
 3367 
 3368     return lastParsed;
 3369 }
 3370 
 3371 void NumberFormatTest::TestNonpositiveMultiplier() {
 3372     UErrorCode status = U_ZERO_ERROR;
 3373     DecimalFormatSymbols US(Locale::getUS(), status);
 3374     CHECK(status, "DecimalFormatSymbols constructor");
 3375     DecimalFormat df(UnicodeString("0"), US, status);
 3376     CHECK(status, "DecimalFormat(0)");
 3377 
 3378     // test zero multiplier
 3379 
 3380     int32_t mult = df.getMultiplier();
 3381     df.setMultiplier(0);
 3382     if (df.getMultiplier() != mult) {
 3383         errln("DecimalFormat.setMultiplier(0) did not ignore its zero input");
 3384     }
 3385 
 3386     // test negative multiplier
 3387 
 3388     df.setMultiplier(-1);
 3389     if (df.getMultiplier() != -1) {
 3390         errln("DecimalFormat.setMultiplier(-1) ignored its negative input");
 3391         return;
 3392     }
 3393 
 3394     expect(df, "1122.123", -1122.123);
 3395     expect(df, "-1122.123", 1122.123);
 3396     expect(df, "1.2", -1.2);
 3397     expect(df, "-1.2", 1.2);
 3398 
 3399     // Note:  the tests with the final parameter of FALSE will not round trip.
 3400     //        The initial numeric value will format correctly, after the multiplier.
 3401     //        Parsing the formatted text will be out-of-range for an int64, however.
 3402     //        The expect() function could be modified to detect this and fall back
 3403     //        to looking at the decimal parsed value, but it doesn't.
 3404     expect(df, U_INT64_MIN,    "9223372036854775808", FALSE);
 3405     expect(df, U_INT64_MIN+1,  "9223372036854775807");
 3406     expect(df, (int64_t)-123,                  "123");
 3407     expect(df, (int64_t)123,                  "-123");
 3408     expect(df, U_INT64_MAX-1, "-9223372036854775806");
 3409     expect(df, U_INT64_MAX,   "-9223372036854775807");
 3410 
 3411     df.setMultiplier(-2);
 3412     expect(df, -(U_INT64_MIN/2)-1, "-9223372036854775806");
 3413     expect(df, -(U_INT64_MIN/2),   "-9223372036854775808");
 3414     expect(df, -(U_INT64_MIN/2)+1, "-9223372036854775810", FALSE);
 3415 
 3416     df.setMultiplier(-7);
 3417     expect(df, -(U_INT64_MAX/7)-1, "9223372036854775814", FALSE);
 3418     expect(df, -(U_INT64_MAX/7),   "9223372036854775807");
 3419     expect(df, -(U_INT64_MAX/7)+1, "9223372036854775800");
 3420 
 3421     // TODO: uncomment (and fix up) all the following int64_t tests once BigInteger is ported
 3422     // (right now the big numbers get turned into doubles and lose tons of accuracy)
 3423     //expect2(df, U_INT64_MAX, Int64ToUnicodeString(-U_INT64_MAX));
 3424     //expect2(df, U_INT64_MIN, UnicodeString(Int64ToUnicodeString(U_INT64_MIN), 1));
 3425     //expect2(df, U_INT64_MAX / 2, Int64ToUnicodeString(-(U_INT64_MAX / 2)));
 3426     //expect2(df, U_INT64_MIN / 2, Int64ToUnicodeString(-(U_INT64_MIN / 2)));
 3427 
 3428     // TODO: uncomment (and fix up) once BigDecimal is ported and DecimalFormat can handle it
 3429     //expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
 3430     //expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
 3431     //expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
 3432     //expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
 3433 }
 3434 
 3435 typedef struct {
 3436     const char * stringToParse;
 3437     int          parsedPos;
 3438     int          errorIndex;
 3439     UBool        lenient;
 3440 } TestSpaceParsingItem;
 3441 
 3442 void
 3443 NumberFormatTest::TestSpaceParsing() {
 3444     // the data are:
 3445     // the string to be parsed, parsed position, parsed error index
 3446     const TestSpaceParsingItem DATA[] = {
 3447         {"$124",           4, -1, FALSE},
 3448         {"$124 $124",      4, -1, FALSE},
 3449         {"$124 ",          4, -1, FALSE},
 3450         {"$ 124 ",         0,  1, FALSE},
 3451         {"$\\u00A0124 ",   5, -1, FALSE},
 3452         {" $ 124 ",        0,  0, FALSE},
 3453         {"124$",           0,  4, FALSE},
 3454         {"124 $",          0,  3, FALSE},
 3455         {"$124",           4, -1, TRUE},
 3456         {"$124 $124",      4, -1, TRUE},
 3457         {"$124 ",          4, -1, TRUE},
 3458         {"$ 124 ",         5, -1, TRUE},
 3459         {"$\\u00A0124 ",   5, -1, TRUE},
 3460         {" $ 124 ",        6, -1, TRUE},
 3461         {"124$",           4, -1, TRUE},
 3462         {"124$",           4, -1, TRUE},
 3463         {"124 $",          5, -1, TRUE},
 3464         {"124 $",          5, -1, TRUE},
 3465     };
 3466     UErrorCode status = U_ZERO_ERROR;
 3467     Locale locale("en_US");
 3468     NumberFormat* foo = NumberFormat::createCurrencyInstance(locale, status);
 3469 
 3470     if (U_FAILURE(status)) {
 3471         delete foo;
 3472         return;
 3473     }
 3474     for (uint32_t i = 0; i < UPRV_LENGTHOF(DATA); ++i) {
 3475         ParsePosition parsePosition(0);
 3476         UnicodeString stringToBeParsed = ctou(DATA[i].stringToParse);
 3477         int parsedPosition = DATA[i].parsedPos;
 3478         int errorIndex = DATA[i].errorIndex;
 3479         foo->setLenient(DATA[i].lenient);
 3480         Formattable result;
 3481         foo->parse(stringToBeParsed, result, parsePosition);
 3482         logln("Parsing: " + stringToBeParsed);
 3483         if (parsePosition.getIndex() != parsedPosition ||
 3484             parsePosition.getErrorIndex() != errorIndex) {
 3485             errln("FAILED parse " + stringToBeParsed + "; lenient: " + DATA[i].lenient + "; wrong position, expected: (" + parsedPosition + ", " + errorIndex + "); got (" + parsePosition.getIndex() + ", " + parsePosition.getErrorIndex() + ")");
 3486         }
 3487         if (parsePosition.getErrorIndex() == -1 &&
 3488             result.getType() == Formattable::kLong &&
 3489             result.getLong() != 124) {
 3490             errln("FAILED parse " + stringToBeParsed + "; wrong number, expect: 124, got " + result.getLong());
 3491         }
 3492     }
 3493     delete foo;
 3494 }
 3495 
 3496 /**
 3497  * Test using various numbering systems and numbering system keyword.
 3498  */
 3499 typedef struct {
 3500     const char *localeName;
 3501     double      value;
 3502     UBool        isRBNF;
 3503     const char *expectedResult;
 3504 } TestNumberingSystemItem;
 3505 
 3506 void NumberFormatTest::TestNumberingSystems() {
 3507 
 3508     const TestNumberingSystemItem DATA[] = {
 3509         { "en_US@numbers=thai", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" },
 3510         { "en_US@numbers=hebr", 5678.0, TRUE, "\\u05D4\\u05F3\\u05EA\\u05E8\\u05E2\\u05F4\\u05D7" },
 3511         { "en_US@numbers=arabext", 1234.567, FALSE, "\\u06F1\\u066c\\u06F2\\u06F3\\u06F4\\u066b\\u06F5\\u06F6\\u06F7" },
 3512         { "ar_EG", 1234.567, FALSE, "\\u0661\\u066C\\u0662\\u0663\\u0664\\u066b\\u0665\\u0666\\u0667" },
 3513         { "th_TH@numbers=traditional", 1234.567, FALSE, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" }, // fall back to native per TR35
 3514         { "ar_MA", 1234.567, FALSE, "1.234,567" },
 3515         { "en_US@numbers=hanidec", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
 3516         { "ta_IN@numbers=native", 1234.567, FALSE, "\\u0BE7,\\u0BE8\\u0BE9\\u0BEA.\\u0BEB\\u0BEC\\u0BED" },
 3517         { "ta_IN@numbers=traditional", 1235.0, TRUE, "\\u0BF2\\u0BE8\\u0BF1\\u0BE9\\u0BF0\\u0BEB" },
 3518         { "ta_IN@numbers=finance", 1234.567, FALSE, "1,234.567" }, // fall back to default per TR35
 3519         { "zh_TW@numbers=native", 1234.567, FALSE, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
 3520         { "zh_TW@numbers=traditional", 1234.567, TRUE, "\\u4E00\\u5343\\u4E8C\\u767E\\u4E09\\u5341\\u56DB\\u9EDE\\u4E94\\u516D\\u4E03" },
 3521         { "zh_TW@numbers=finance", 1234.567, TRUE, "\\u58F9\\u4EDF\\u8CB3\\u4F70\\u53C3\\u62FE\\u8086\\u9EDE\\u4F0D\\u9678\\u67D2" },
 3522         { NULL, 0, FALSE, NULL }
 3523     };
 3524 
 3525     UErrorCode ec;
 3526 
 3527     const TestNumberingSystemItem *item;
 3528     for (item = DATA; item->localeName != NULL; item++) {
 3529         ec = U_ZERO_ERROR;
 3530         Locale loc = Locale::createFromName(item->localeName);
 3531 
 3532         NumberFormat *origFmt = NumberFormat::createInstance(loc,ec);
 3533         if (U_FAILURE(ec)) {
 3534             dataerrln("FAIL: getInstance(%s) - %s", item->localeName, u_errorName(ec));
 3535             continue;
 3536         }
 3537         // Clone to test ticket #10682
 3538         NumberFormat *fmt = origFmt->clone();
 3539         delete origFmt;
 3540 
 3541 
 3542         if (item->isRBNF) {
 3543             expect3(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
 3544         } else {
 3545             expect2(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
 3546         }
 3547         delete fmt;
 3548     }
 3549 
 3550 
 3551     // Test bogus keyword value
 3552     ec = U_ZERO_ERROR;
 3553     Locale loc4 = Locale::createFromName("en_US@numbers=foobar");
 3554     NumberFormat* fmt4= NumberFormat::createInstance(loc4, ec);
 3555     if ( ec != U_UNSUPPORTED_ERROR ) {
 3556         errln("FAIL: getInstance(en_US@numbers=foobar) should have returned U_UNSUPPORTED_ERROR");
 3557         delete fmt4;
 3558     }
 3559 
 3560     ec = U_ZERO_ERROR;
 3561     NumberingSystem *ns = NumberingSystem::createInstance(ec);
 3562     if (U_FAILURE(ec)) {
 3563         dataerrln("FAIL: NumberingSystem::createInstance(ec); - %s", u_errorName(ec));
 3564     }
 3565 
 3566     if ( ns != NULL ) {
 3567         ns->getDynamicClassID();
 3568         ns->getStaticClassID();
 3569     } else {
 3570         errln("FAIL: getInstance() returned NULL.");
 3571     }
 3572 
 3573     NumberingSystem *ns1 = new NumberingSystem(*ns);
 3574     if (ns1 == NULL) {
 3575         errln("FAIL: NumberSystem copy constructor returned NULL.");
 3576     }
 3577 
 3578     delete ns1;
 3579     delete ns;
 3580 
 3581 }
 3582 
 3583 
 3584 void
 3585 NumberFormatTest::TestMultiCurrencySign() {
 3586     const char* DATA[][6] = {
 3587         // the fields in the following test are:
 3588         // locale,
 3589         // currency pattern (with negative pattern),
 3590         // currency number to be formatted,
 3591         // currency format using currency symbol name, such as "$" for USD,
 3592         // currency format using currency ISO name, such as "USD",
 3593         // currency format using plural name, such as "US dollars".
 3594         // for US locale
 3595         {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1234.56", "$1,234.56", "USD\\u00A01,234.56", "US dollars\\u00A01,234.56"},
 3596         {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD\\u00A01,234.56", "-US dollars\\u00A01,234.56"},
 3597         {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1", "$1.00", "USD\\u00A01.00", "US dollars\\u00A01.00"},
 3598         // for CHINA locale
 3599         {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1234.56", "\\u00A51,234.56", "CNY\\u00A01,234.56", "\\u4EBA\\u6C11\\u5E01\\u00A01,234.56"},
 3600         {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "-1234.56", "(\\u00A51,234.56)", "(CNY\\u00A01,234.56)", "(\\u4EBA\\u6C11\\u5E01\\u00A01,234.56)"},
 3601         {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1", "\\u00A51.00", "CNY\\u00A01.00", "\\u4EBA\\u6C11\\u5E01\\u00A01.00"}
 3602     };
 3603 
 3604     const UChar doubleCurrencySign[] = {0xA4, 0xA4, 0};
 3605     UnicodeString doubleCurrencyStr(doubleCurrencySign);
 3606     const UChar tripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
 3607     UnicodeString tripleCurrencyStr(tripleCurrencySign);
 3608 
 3609     for (uint32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
 3610         const char* locale = DATA[i][0];
 3611         UnicodeString pat = ctou(DATA[i][1]);
 3612         double numberToBeFormat = atof(DATA[i][2]);
 3613         UErrorCode status = U_ZERO_ERROR;
 3614         DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale(locale), status);
 3615         if (U_FAILURE(status)) {
 3616             delete sym;
 3617             continue;
 3618         }
 3619         for (int j=1; j<=3; ++j) {
 3620             // j represents the number of currency sign in the pattern.
 3621             if (j == 2) {
 3622                 pat = pat.findAndReplace(ctou("\\u00A4"), doubleCurrencyStr);
 3623             } else if (j == 3) {
 3624                 pat = pat.findAndReplace(ctou("\\u00A4\\u00A4"), tripleCurrencyStr);
 3625             }
 3626 
 3627             DecimalFormat* fmt = new DecimalFormat(pat, new DecimalFormatSymbols(*sym), status);
 3628             if (U_FAILURE(status)) {
 3629                 errln("FAILED init DecimalFormat ");
 3630                 delete fmt;
 3631                 continue;
 3632             }
 3633             UnicodeString s;
 3634             ((NumberFormat*) fmt)->format(numberToBeFormat, s);
 3635             // DATA[i][3] is the currency format result using a
 3636             // single currency sign.
 3637             // DATA[i][4] is the currency format result using
 3638             // double currency sign.
 3639             // DATA[i][5] is the currency format result using
 3640             // triple currency sign.
 3641             // DATA[i][j+2] is the currency format result using
 3642             // 'j' number of currency sign.
 3643             UnicodeString currencyFormatResult = ctou(DATA[i][2+j]);
 3644             if (s.compare(currencyFormatResult)) {
 3645                 errln("FAIL format: Expected " + currencyFormatResult + "; Got " + s);
 3646             }
 3647             // mix style parsing
 3648             for (int k=3; k<=5; ++k) {
 3649               // DATA[i][3] is the currency format result using a
 3650               // single currency sign.
 3651               // DATA[i][4] is the currency format result using
 3652               // double currency sign.
 3653               // DATA[i][5] is the currency format result using
 3654               // triple currency sign.
 3655               UnicodeString oneCurrencyFormat = ctou(DATA[i][k]);
 3656               UErrorCode status = U_ZERO_ERROR;
 3657               Formattable parseRes;
 3658               fmt->parse(oneCurrencyFormat, parseRes, status);
 3659               if (U_FAILURE(status) ||
 3660                   (parseRes.getType() == Formattable::kDouble &&
 3661                    parseRes.getDouble() != numberToBeFormat) ||
 3662                   (parseRes.getType() == Formattable::kLong &&
 3663                    parseRes.getLong() != numberToBeFormat)) {
 3664                   errln("FAILED parse " + oneCurrencyFormat + "; (i, j, k): " +
 3665                         i + ", " + j + ", " + k);
 3666               }
 3667             }
 3668             delete fmt;
 3669         }
 3670         delete sym;
 3671     }
 3672 }
 3673 
 3674 
 3675 void
 3676 NumberFormatTest::TestCurrencyFormatForMixParsing() {
 3677     UErrorCode status = U_ZERO_ERROR;
 3678     MeasureFormat* curFmt = MeasureFormat::createCurrencyFormat(Locale("en_US"), status);
 3679     if (U_FAILURE(status)) {
 3680         delete curFmt;
 3681         return;
 3682     }
 3683     const char* formats[] = {
 3684         "$1,234.56",  // string to be parsed
 3685         "USD1,234.56",
 3686         "US dollars1,234.56",
 3687         // "1,234.56 US dollars" // Fails in 62 because currency format is not compatible with pattern.
 3688     };
 3689     const CurrencyAmount* curramt = NULL;
 3690     for (uint32_t i = 0; i < UPRV_LENGTHOF(formats); ++i) {
 3691         UnicodeString stringToBeParsed = ctou(formats[i]);
 3692         logln(UnicodeString("stringToBeParsed: ") + stringToBeParsed);
 3693         Formattable result;
 3694         UErrorCode status = U_ZERO_ERROR;
 3695         curFmt->parseObject(stringToBeParsed, result, status);
 3696         if (U_FAILURE(status)) {
 3697           errln("FAIL: measure format parsing: '%s' ec: %s", formats[i], u_errorName(status));
 3698         } else if (result.getType() != Formattable::kObject ||
 3699             (curramt = dynamic_cast<const CurrencyAmount*>(result.getObject())) == NULL ||
 3700             curramt->getNumber().getDouble() != 1234.56 ||
 3701             UnicodeString(curramt->getISOCurrency()).compare(ISO_CURRENCY_USD)
 3702         ) {
 3703             errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number ");
 3704             if (curramt->getNumber().getDouble() != 1234.56) {
 3705                 errln((UnicodeString)"wong number, expect: 1234.56" + ", got: " + curramt->getNumber().getDouble());
 3706             }
 3707             if (curramt->getISOCurrency() != ISO_CURRENCY_USD) {
 3708                 errln((UnicodeString)"wong currency, expect: USD" + ", got: " + curramt->getISOCurrency());
 3709             }
 3710         }
 3711     }
 3712     delete curFmt;
 3713 }
 3714 
 3715 
 3716 /** Starting in ICU 62, strict mode is actually strict with currency formats. */
 3717 void NumberFormatTest::TestMismatchedCurrencyFormatFail() {
 3718     IcuTestErrorCode status(*this, "TestMismatchedCurrencyFormatFail");
 3719     LocalPointer<DecimalFormat> df(
 3720             dynamic_cast<DecimalFormat*>(DecimalFormat::createCurrencyInstance("en", status)), status);
 3721     if (!assertSuccess("createCurrencyInstance() failed.", status, true, __FILE__, __LINE__)) {return;}
 3722     UnicodeString pattern;
 3723     assertEquals("Test assumes that currency sign is at the beginning",
 3724             u"\u00A4#,##0.00",
 3725             df->toPattern(pattern));
 3726     // Should round-trip on the correct currency format:
 3727     expect2(*df, 1.23, u"\u00A41.23");
 3728     df->setCurrency(u"EUR", status);
 3729     expect2(*df, 1.23, u"\u20AC1.23");
 3730     // Should parse with currency in the wrong place in lenient mode
 3731     df->setLenient(TRUE);
 3732     expect(*df, u"1.23\u20AC", 1.23);
 3733     expectParseCurrency(*df, u"EUR", 1.23, "1.23\\u20AC");
 3734     // Should NOT parse with currency in the wrong place in STRICT mode
 3735     df->setLenient(FALSE);
 3736     {
 3737         Formattable result;
 3738         ErrorCode failStatus;
 3739         df->parse(u"1.23\u20AC", result, failStatus);
 3740         assertEquals("Should fail to parse", U_INVALID_FORMAT_ERROR, failStatus);
 3741     }
 3742     {
 3743         ParsePosition ppos;
 3744         df->parseCurrency(u"1.23\u20AC", ppos);
 3745         assertEquals("Should fail to parse currency", 0, ppos.getIndex());
 3746     }
 3747 }
 3748 
 3749 
 3750 void
 3751 NumberFormatTest::TestDecimalFormatCurrencyParse() {
 3752     // Locale.US
 3753     UErrorCode status = U_ZERO_ERROR;
 3754     DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale("en_US"), status);
 3755     if (U_FAILURE(status)) {
 3756         delete sym;
 3757         return;
 3758     }
 3759     UnicodeString pat;
 3760     UChar currency = 0x00A4;
 3761     // "\xA4#,##0.00;-\xA4#,##0.00"
 3762     pat.append(currency).append(currency).append(currency).append("#,##0.00;-").append(currency).append(currency).append(currency).append("#,##0.00");
 3763     DecimalFormat* fmt = new DecimalFormat(pat, sym, status);
 3764     if (U_FAILURE(status)) {
 3765         delete fmt;
 3766         errln("failed to new DecimalFormat in TestDecimalFormatCurrencyParse");
 3767         return;
 3768     }
 3769     const char* DATA[][2] = {
 3770         // the data are:
 3771         // string to be parsed, the parsed result (number)
 3772         {"$1.00", "1"},
 3773         {"USD1.00", "1"},
 3774         {"1.00 US dollar", "1"},
 3775         {"$1,234.56", "1234.56"},
 3776         {"USD1,234.56", "1234.56"},
 3777         {"1,234.56 US dollar", "1234.56"},
 3778     };
 3779     // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
 3780     fmt->setLenient(TRUE);
 3781     for (uint32_t i = 0; i < UPRV_LENGTHOF(DATA); ++i) {
 3782         UnicodeString stringToBeParsed = ctou(DATA[i][0]);
 3783         double parsedResult = atof(DATA[i][1]);
 3784         UErrorCode status = U_ZERO_ERROR;
 3785         Formattable result;
 3786         fmt->parse(stringToBeParsed, result, status);
 3787         logln((UnicodeString)"Input: " + stringToBeParsed + "; output: " + result.getDouble(status));
 3788         if (U_FAILURE(status) ||
 3789             (result.getType() == Formattable::kDouble &&
 3790             result.getDouble() != parsedResult) ||
 3791             (result.getType() == Formattable::kLong &&
 3792             result.getLong() != parsedResult)) {
 3793             errln((UnicodeString)"FAIL parse: Expected " + parsedResult);
 3794         }
 3795     }
 3796     delete fmt;
 3797 }
 3798 
 3799 
 3800 void
 3801 NumberFormatTest::TestCurrencyIsoPluralFormat() {
 3802     static const char* DATA[][6] = {
 3803         // the data are:
 3804         // locale,
 3805         // currency amount to be formatted,
 3806         // currency ISO code to be formatted,
 3807         // format result using CURRENCYSTYLE,
 3808         // format result using ISOCURRENCYSTYLE,
 3809         // format result using PLURALCURRENCYSTYLE,
 3810 
 3811         {"en_US", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00 US dollars"},
 3812         {"en_US", "1234.56", "USD", "$1,234.56", "USD\\u00A01,234.56", "1,234.56 US dollars"},
 3813         {"en_US", "-1234.56", "USD", "-$1,234.56", "-USD\\u00A01,234.56", "-1,234.56 US dollars"},
 3814         {"zh_CN", "1", "USD", "US$1.00", "USD\\u00A01.00", "1.00\\u00A0\\u7F8E\\u5143"},
 3815         {"zh_CN", "1234.56", "USD", "US$1,234.56", "USD\\u00A01,234.56", "1,234.56\\u00A0\\u7F8E\\u5143"},
 3816         {"zh_CN", "1", "CNY", "\\u00A51.00", "CNY\\u00A01.00", "1.00\\u00A0\\u4EBA\\u6C11\\u5E01"},
 3817         {"zh_CN", "1234.56", "CNY", "\\u00A51,234.56", "CNY\\u00A01,234.56", "1,234.56\\u00A0\\u4EBA\\u6C11\\u5E01"},
 3818         {"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"},
 3819         {"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"},
 3820         {"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"},
 3821         // test locale without currency information
 3822         {"root", "-1.23", "USD", "-US$\\u00A01.23", "-USD\\u00A01.23", "-1.23 USD"},
 3823         // test choice format
 3824         {"es_AR", "1", "INR", "INR\\u00A01,00", "INR\\u00A01,00", "1,00 rupia india"},
 3825     };
 3826     static const UNumberFormatStyle currencyStyles[] = {
 3827         UNUM_CURRENCY,
 3828         UNUM_CURRENCY_ISO,
 3829         UNUM_CURRENCY_PLURAL
 3830     };
 3831 
 3832     for (int32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
 3833       const char* localeString = DATA[i][0];
 3834       double numberToBeFormat = atof(DATA[i][1]);
 3835       const char* currencyISOCode = DATA[i][2];
 3836       logln(UnicodeString(u"Locale: ") + localeString + "; amount: " + numberToBeFormat);
 3837       Locale locale(localeString);
 3838       for (int32_t kIndex = 0; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) {
 3839         UNumberFormatStyle k = currencyStyles[kIndex];
 3840         logln(UnicodeString(u"UNumberFormatStyle: ") + k);
 3841         UErrorCode status = U_ZERO_ERROR;
 3842         NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
 3843         if (U_FAILURE(status)) {
 3844             delete numFmt;
 3845             dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
 3846             continue;
 3847         }
 3848         UChar currencyCode[4];
 3849         u_charsToUChars(currencyISOCode, currencyCode, 4);
 3850         numFmt->setCurrency(currencyCode, status);
 3851         if (U_FAILURE(status)) {
 3852             delete numFmt;
 3853             errln((UnicodeString)"can not set currency:" + currencyISOCode);
 3854             continue;
 3855         }
 3856 
 3857         UnicodeString strBuf;
 3858         numFmt->format(numberToBeFormat, strBuf);
 3859         int resultDataIndex = 3 + kIndex;
 3860         // DATA[i][resultDataIndex] is the currency format result
 3861         // using 'k' currency style.
 3862         UnicodeString formatResult = ctou(DATA[i][resultDataIndex]);
 3863         if (strBuf.compare(formatResult)) {
 3864             errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
 3865         }
 3866         // test parsing, and test parsing for all currency formats.
 3867         // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
 3868         numFmt->setLenient(TRUE);
 3869         for (int j = 3; j < 6; ++j) {
 3870             // DATA[i][3] is the currency format result using
 3871             // CURRENCYSTYLE formatter.
 3872             // DATA[i][4] is the currency format result using
 3873             // ISOCURRENCYSTYLE formatter.
 3874             // DATA[i][5] is the currency format result using
 3875             // PLURALCURRENCYSTYLE formatter.
 3876             UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]);
 3877             UErrorCode status = U_ZERO_ERROR;
 3878             Formattable parseResult;
 3879             numFmt->parse(oneCurrencyFormatResult, parseResult, status);
 3880             if (U_FAILURE(status) ||
 3881                 (parseResult.getType() == Formattable::kDouble &&
 3882                  parseResult.getDouble() != numberToBeFormat) ||
 3883                 (parseResult.getType() == Formattable::kLong &&
 3884                  parseResult.getLong() != numberToBeFormat)) {
 3885                 errln((UnicodeString)"FAIL: getCurrencyFormat of locale " +
 3886                       localeString + " failed roundtripping the number");
 3887                 if (parseResult.getType() == Formattable::kDouble) {
 3888                     errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getDouble());
 3889                 } else {
 3890                     errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getLong());
 3891                 }
 3892             }
 3893         }
 3894         delete numFmt;
 3895       }
 3896     }
 3897 }
 3898 
 3899 void
 3900 NumberFormatTest::TestCurrencyParsing() {
 3901     static const char* DATA[][6] = {
 3902         // the data are:
 3903         // locale,
 3904         // currency amount to be formatted,
 3905         // currency ISO code to be formatted,
 3906         // format result using CURRENCYSTYLE,
 3907         // format result using ISOCURRENCYSTYLE,
 3908         // format result using PLURALCURRENCYSTYLE,
 3909         {"en_US", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00 US dollars"},
 3910         {"pa_IN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\u0a2f\\u0a42.\\u0a10\\u0a38. \\u0a21\\u0a3e\\u0a32\\u0a30"},
 3911         {"es_AR", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 d\\u00f3lar estadounidense"},
 3912         {"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"},
 3913         {"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"},
 3914         {"he_IL", "1", "USD", "\\u200f1.00\\u00a0$", "\\u200f1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"},
 3915         {"hr_HR", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 ameri\\u010Dkih dolara"},
 3916         {"id_ID", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 Dolar Amerika Serikat"},
 3917         {"it_IT", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 dollari statunitensi"},
 3918         {"ko_KR", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"},
 3919         {"ja_JP", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00\\u00A0\\u7c73\\u30c9\\u30eb"},
 3920         {"zh_CN", "1", "CNY", "\\u00A51.00", "CNY\\u00A001.00", "1.00\\u00A0\\u4EBA\\u6C11\\u5E01"},
 3921         {"zh_TW", "1", "CNY", "CN\\u00A51.00", "CNY\\u00A01.00", "1.00 \\u4eba\\u6c11\\u5e63"},
 3922         {"zh_Hant", "1", "CNY", "CN\\u00A51.00", "CNY\\u00A01.00", "1.00 \\u4eba\\u6c11\\u5e63"},
 3923         {"zh_Hant", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1 \\u65E5\\u5713"},
 3924         {"ja_JP", "1", "JPY", "\\uFFE51.00", "JPY\\u00A01.00", "1\\u00A0\\u5186"},
 3925         // ICU 62 requires #parseCurrency() to recognize variants when parsing
 3926         // {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1\\u00A0\\u5186"},
 3927         {"ru_RU", "1", "RUB", "1,00\\u00A0\\u00A0\\u20BD", "1,00\\u00A0\\u00A0RUB", "1,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"}
 3928     };
 3929     static const UNumberFormatStyle currencyStyles[] = {
 3930         UNUM_CURRENCY,
 3931         UNUM_CURRENCY_ISO,
 3932         UNUM_CURRENCY_PLURAL
 3933     };
 3934     static const char* currencyStyleNames[] = {
 3935       "UNUM_CURRENCY",
 3936       "UNUM_CURRENCY_ISO",
 3937       "UNUM_CURRENCY_PLURAL"
 3938     };
 3939 
 3940 #ifdef NUMFMTST_CACHE_DEBUG
 3941 int deadloop = 0;
 3942 for (;;) {
 3943     printf("loop: %d\n", deadloop++);
 3944 #endif
 3945     for (uint32_t i=0; i< UPRV_LENGTHOF(DATA); ++i) {  /* i = test case #  - should be i=0*/
 3946       for (int32_t kIndex = 2; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) {
 3947         UNumberFormatStyle k = currencyStyles[kIndex]; /* k = style */
 3948         const char* localeString = DATA[i][0];
 3949         double numberToBeFormat = atof(DATA[i][1]);
 3950         const char* currencyISOCode = DATA[i][2];
 3951         Locale locale(localeString);
 3952         UErrorCode status = U_ZERO_ERROR;
 3953         NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
 3954         logln("#%d NumberFormat(%s, %s) Currency=%s\n",
 3955               i, localeString, currencyStyleNames[kIndex],
 3956               currencyISOCode);
 3957 
 3958         if (U_FAILURE(status)) {
 3959             delete numFmt;
 3960             dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
 3961             continue;
 3962         }
 3963         UChar currencyCode[4];
 3964         u_charsToUChars(currencyISOCode, currencyCode, 4);
 3965         numFmt->setCurrency(currencyCode, status);
 3966         if (U_FAILURE(status)) {
 3967             delete numFmt;
 3968             errln((UnicodeString)"can not set currency:" + currencyISOCode);
 3969             continue;
 3970         }
 3971 
 3972         UnicodeString strBuf;
 3973         numFmt->format(numberToBeFormat, strBuf);
 3974         int resultDataIndex = 3 + kIndex;
 3975         // DATA[i][resultDataIndex] is the currency format result
 3976         // using 'k' currency style.
 3977         UnicodeString formatResult = ctou(DATA[i][resultDataIndex]);
 3978         if (strBuf.compare(formatResult)) {
 3979             errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
 3980         }
 3981         // test parsing, and test parsing for all currency formats.
 3982         // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
 3983         numFmt->setLenient(TRUE);
 3984         for (int j = 3; j < 6; ++j) {
 3985             // DATA[i][3] is the currency format result using
 3986             // CURRENCYSTYLE formatter.
 3987             // DATA[i][4] is the currency format result using
 3988             // ISOCURRENCYSTYLE formatter.
 3989             // DATA[i][5] is the currency format result using
 3990             // PLURALCURRENCYSTYLE formatter.
 3991             UnicodeString oneCurrencyFormatResult = ctou(DATA[i][j]);
 3992             UErrorCode status = U_ZERO_ERROR;
 3993             Formattable parseResult;
 3994             logln("parse(%s)", DATA[i][j]);
 3995             numFmt->parse(oneCurrencyFormatResult, parseResult, status);
 3996             if (U_FAILURE(status) ||
 3997                 (parseResult.getType() == Formattable::kDouble &&
 3998                  parseResult.getDouble() != numberToBeFormat) ||
 3999                 (parseResult.getType() == Formattable::kLong &&
 4000                  parseResult.getLong() != numberToBeFormat)) {
 4001                 errln((UnicodeString)"FAIL: NumberFormat(" + localeString +", " + currencyStyleNames[kIndex] +
 4002                       "), Currency="+currencyISOCode+", parse("+DATA[i][j]+") returned error " + (UnicodeString)u_errorName(status)+".  Testcase: data[" + i + "][" + currencyStyleNames[j-3] +"="+j+"]");
 4003                 if (parseResult.getType() == Formattable::kDouble) {
 4004                     errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (double): " +parseResult.getDouble());
 4005                 } else {
 4006                     errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (long): " +parseResult.getLong());
 4007                 }
 4008                 errln((UnicodeString)" round-trip would be: " + strBuf);
 4009             }
 4010         }
 4011         delete numFmt;
 4012       }
 4013     }
 4014 #ifdef NUMFMTST_CACHE_DEBUG
 4015 }
 4016 #endif
 4017 }
 4018 
 4019 
 4020 void
 4021 NumberFormatTest::TestParseCurrencyInUCurr() {
 4022     const char* DATA[] = {
 4023         "1.00 US DOLLAR",  // case in-sensitive
 4024         "$1.00",
 4025         "USD1.00",
 4026         "usd1.00", // case in-sensitive: #13696
 4027         "US dollar1.00",
 4028         "US dollars1.00",
 4029         "$1.00",
 4030         "A$1.00",
 4031         "ADP1.00",
 4032         "ADP1.00",
 4033         "AED1.00",
 4034         "AED1.00",
 4035         "AFA1.00",
 4036         "AFA1.00",
 4037         "AFN1.00",
 4038         "ALL1.00",
 4039         "AMD1.00",
 4040         "ANG1.00",
 4041         "AOA1.00",
 4042         "AOK1.00",
 4043         "AOK1.00",
 4044         "AON1.00",
 4045         "AON1.00",
 4046         "AOR1.00",
 4047         "AOR1.00",
 4048         "ARS1.00",
 4049         "ARA1.00",
 4050         "ARA1.00",
 4051         "ARP1.00",
 4052         "ARP1.00",
 4053         "ARS1.00",
 4054         "ATS1.00",
 4055         "ATS1.00",
 4056         "AUD1.00",
 4057         "AWG1.00",
 4058         "AZM1.00",
 4059         "AZM1.00",
 4060         "AZN1.00",
 4061         "Afghan Afghani (1927\\u20132002)1.00",
 4062         "Afghan afghani (1927\\u20132002)1.00",
 4063         "Afghan Afghani1.00",
 4064         "Afghan Afghanis1.00",
 4065         "Albanian Lek1.00",
 4066         "Albanian lek1.00",
 4067         "Albanian lek\\u00eb1.00",
 4068         "Algerian Dinar1.00",
 4069         "Algerian dinar1.00",
 4070         "Algerian dinars1.00",
 4071         "Andorran Peseta1.00",
 4072         "Andorran peseta1.00",
 4073         "Andorran pesetas1.00",
 4074         "Angolan Kwanza (1977\\u20131991)1.00",
 4075         "Angolan Readjusted Kwanza (1995\\u20131999)1.00",
 4076         "Angolan Kwanza1.00",
 4077         "Angolan New Kwanza (1990\\u20132000)1.00",
 4078         "Angolan kwanza (1977\\u20131991)1.00",
 4079         "Angolan readjusted kwanza (1995\\u20131999)1.00",
 4080         "Angolan kwanza1.00",
 4081         "Angolan kwanzas (1977\\u20131991)1.00",
 4082         "Angolan readjusted kwanzas (1995\\u20131999)1.00",
 4083         "Angolan kwanzas1.00",
 4084         "Angolan new kwanza (1990\\u20132000)1.00",
 4085         "Angolan new kwanzas (1990\\u20132000)1.00",
 4086         "Argentine Austral1.00",
 4087         "Argentine Peso (1983\\u20131985)1.00",
 4088         "Argentine Peso1.00",
 4089         "Argentine austral1.00",
 4090         "Argentine australs1.00",
 4091         "Argentine peso (1983\\u20131985)1.00",
 4092         "Argentine peso1.00",
 4093         "Argentine pesos (1983\\u20131985)1.00",
 4094         "Argentine pesos1.00",
 4095         "Armenian Dram1.00",
 4096         "Armenian dram1.00",
 4097         "Armenian drams1.00",
 4098         "Aruban Florin1.00",
 4099         "Aruban florin1.00",
 4100         "Australian Dollar1.00",
 4101         "Australian dollar1.00",
 4102         "Australian dollars1.00",
 4103         "Austrian Schilling1.00",
 4104         "Austrian schilling1.00",
 4105         "Austrian schillings1.00",
 4106         "Azerbaijani Manat (1993\\u20132006)1.00",
 4107         "Azerbaijani Manat1.00",
 4108         "Azerbaijani manat (1993\\u20132006)1.00",
 4109         "Azerbaijani manat1.00",
 4110         "Azerbaijani manats (1993\\u20132006)1.00",
 4111         "Azerbaijani manats1.00",
 4112         "BAD1.00",
 4113         "BAD1.00",
 4114         "BAM1.00",
 4115         "BBD1.00",
 4116         "BDT1.00",
 4117         "BEC1.00",
 4118         "BEC1.00",
 4119         "BEF1.00",
 4120         "BEL1.00",
 4121         "BEL1.00",
 4122         "BGL1.00",
 4123         "BGN1.00",
 4124         "BGN1.00",
 4125         "BHD1.00",
 4126         "BIF1.00",
 4127         "BMD1.00",
 4128         "BND1.00",
 4129         "BOB1.00",
 4130         "BOP1.00",
 4131         "BOP1.00",
 4132         "BOV1.00",
 4133         "BOV1.00",
 4134         "BRB1.00",
 4135         "BRB1.00",
 4136         "BRC1.00",
 4137         "BRC1.00",
 4138         "BRE1.00",
 4139         "BRE1.00",
 4140         "BRL1.00",
 4141         "BRN1.00",
 4142         "BRN1.00",
 4143         "BRR1.00",
 4144         "BRR1.00",
 4145         "BSD1.00",
 4146         "BSD1.00",
 4147         "BTN1.00",
 4148         "BUK1.00",
 4149         "BUK1.00",
 4150         "BWP1.00",
 4151         "BYB1.00",
 4152         "BYB1.00",
 4153         "BYR1.00",
 4154         "BZD1.00",
 4155         "Bahamian Dollar1.00",
 4156         "Bahamian dollar1.00",
 4157         "Bahamian dollars1.00",
 4158         "Bahraini Dinar1.00",
 4159         "Bahraini dinar1.00",
 4160         "Bahraini dinars1.00",
 4161         "Bangladeshi Taka1.00",
 4162         "Bangladeshi taka1.00",
 4163         "Bangladeshi takas1.00",
 4164         "Barbadian Dollar1.00",
 4165         "Barbadian dollar1.00",
 4166         "Barbadian dollars1.00",
 4167         "Belarusian Ruble (1994\\u20131999)1.00",
 4168         "Belarusian Ruble1.00",
 4169         "Belarusian ruble (1994\\u20131999)1.00",
 4170         "Belarusian rubles (1994\\u20131999)1.00",
 4171         "Belarusian ruble1.00",
 4172         "Belarusian rubles1.00",
 4173         "Belgian Franc (convertible)1.00",
 4174         "Belgian Franc (financial)1.00",
 4175         "Belgian Franc1.00",
 4176         "Belgian franc (convertible)1.00",
 4177         "Belgian franc (financial)1.00",
 4178         "Belgian franc1.00",
 4179         "Belgian francs (convertible)1.00",
 4180         "Belgian francs (financial)1.00",
 4181         "Belgian francs1.00",
 4182         "Belize Dollar1.00",
 4183         "Belize dollar1.00",
 4184         "Belize dollars1.00",
 4185         "Bermudan Dollar1.00",
 4186         "Bermudan dollar1.00",
 4187         "Bermudan dollars1.00",
 4188         "Bhutanese Ngultrum1.00",
 4189         "Bhutanese ngultrum1.00",
 4190         "Bhutanese ngultrums1.00",
 4191         "Bolivian Mvdol1.00",
 4192         "Bolivian Peso1.00",
 4193         "Bolivian mvdol1.00",
 4194         "Bolivian mvdols1.00",
 4195         "Bolivian peso1.00",
 4196         "Bolivian pesos1.00",
 4197         "Bolivian Boliviano1.00",
 4198         "Bolivian Boliviano1.00",
 4199         "Bolivian Bolivianos1.00",
 4200         "Bosnia-Herzegovina Convertible Mark1.00",
 4201         "Bosnia-Herzegovina Dinar (1992\\u20131994)1.00",
 4202         "Bosnia-Herzegovina convertible mark1.00",
 4203         "Bosnia-Herzegovina convertible marks1.00",
 4204         "Bosnia-Herzegovina dinar (1992\\u20131994)1.00",
 4205         "Bosnia-Herzegovina dinars (1992\\u20131994)1.00",
 4206         "Botswanan Pula1.00",
 4207         "Botswanan pula1.00",
 4208         "Botswanan pulas1.00",
 4209         "Brazilian New Cruzado (1989\\u20131990)1.00",
 4210         "Brazilian Cruzado (1986\\u20131989)1.00",
 4211         "Brazilian Cruzeiro (1990\\u20131993)1.00",
 4212         "Brazilian New Cruzeiro (1967\\u20131986)1.00",
 4213         "Brazilian Cruzeiro (1993\\u20131994)1.00",
 4214         "Brazilian Real1.00",
 4215         "Brazilian new cruzado (1989\\u20131990)1.00",
 4216         "Brazilian new cruzados (1989\\u20131990)1.00",
 4217         "Brazilian cruzado (1986\\u20131989)1.00",
 4218         "Brazilian cruzados (1986\\u20131989)1.00",
 4219         "Brazilian cruzeiro (1990\\u20131993)1.00",
 4220         "Brazilian new cruzeiro (1967\\u20131986)1.00",
 4221         "Brazilian cruzeiro (1993\\u20131994)1.00",
 4222         "Brazilian cruzeiros (1990\\u20131993)1.00",
 4223         "Brazilian new cruzeiros (1967\\u20131986)1.00",
 4224         "Brazilian cruzeiros (1993\\u20131994)1.00",
 4225         "Brazilian real1.00",
 4226         "Brazilian reals1.00",
 4227         "British Pound1.00",
 4228         "British pound1.00",
 4229         "British pounds1.00",
 4230         "Brunei Dollar1.00",
 4231         "Brunei dollar1.00",
 4232         "Brunei dollars1.00",
 4233         "Bulgarian Hard Lev1.00",
 4234         "Bulgarian Lev1.00",
 4235         "Bulgarian Leva1.00",
 4236         "Bulgarian hard lev1.00",
 4237         "Bulgarian hard leva1.00",
 4238         "Bulgarian lev1.00",
 4239         "Burmese Kyat1.00",
 4240         "Burmese kyat1.00",
 4241         "Burmese kyats1.00",
 4242         "Burundian Franc1.00",
 4243         "Burundian franc1.00",
 4244         "Burundian francs1.00",
 4245         "CA$1.00",
 4246         "CAD1.00",
 4247         "CDF1.00",
 4248         "CDF1.00",
 4249         "West African CFA Franc1.00",
 4250         "Central African CFA Franc1.00",
 4251         "West African CFA franc1.00",
 4252         "Central African CFA franc1.00",
 4253         "West African CFA francs1.00",
 4254         "Central African CFA francs1.00",
 4255         "CFP Franc1.00",
 4256         "CFP franc1.00",
 4257         "CFP francs1.00",
 4258         "CFPF1.00",
 4259         "CHE1.00",
 4260         "CHE1.00",
 4261         "CHF1.00",
 4262         "CHW1.00",
 4263         "CHW1.00",
 4264         "CLF1.00",
 4265         "CLF1.00",
 4266         "CLP1.00",
 4267         "CNY1.00",
 4268         "COP1.00",
 4269         "COU1.00",
 4270         "COU1.00",
 4271         "CRC1.00",
 4272         "CSD1.00",
 4273         "CSD1.00",
 4274         "CSK1.00",
 4275         "CSK1.00",
 4276         "CUP1.00",
 4277         "CUP1.00",
 4278         "CVE1.00",
 4279         "CYP1.00",
 4280         "CZK1.00",
 4281         "Cambodian Riel1.00",
 4282         "Cambodian riel1.00",
 4283         "Cambodian riels1.00",
 4284         "Canadian Dollar1.00",
 4285         "Canadian dollar1.00",
 4286         "Canadian dollars1.00",
 4287         "Cape Verdean Escudo1.00",
 4288         "Cape Verdean escudo1.00",
 4289         "Cape Verdean escudos1.00",
 4290         "Cayman Islands Dollar1.00",
 4291         "Cayman Islands dollar1.00",
 4292         "Cayman Islands dollars1.00",
 4293         "Chilean Peso1.00",
 4294         "Chilean Unit of Account (UF)1.00",
 4295         "Chilean peso1.00",
 4296         "Chilean pesos1.00",
 4297         "Chilean unit of account (UF)1.00",
 4298         "Chilean units of account (UF)1.00",
 4299         "Chinese Yuan1.00",
 4300         "Chinese yuan1.00",
 4301         "Colombian Peso1.00",
 4302         "Colombian peso1.00",
 4303         "Colombian pesos1.00",
 4304         "Comorian Franc1.00",
 4305         "Comorian franc1.00",
 4306         "Comorian francs1.00",
 4307         "Congolese Franc1.00",
 4308         "Congolese franc1.00",
 4309         "Congolese francs1.00",
 4310         "Costa Rican Col\\u00f3n1.00",
 4311         "Costa Rican col\\u00f3n1.00",
 4312         "Costa Rican col\\u00f3ns1.00",
 4313         "Croatian Dinar1.00",
 4314         "Croatian Kuna1.00",
 4315         "Croatian dinar1.00",
 4316         "Croatian dinars1.00",
 4317         "Croatian kuna1.00",
 4318         "Croatian kunas1.00",
 4319         "Cuban Peso1.00",
 4320         "Cuban peso1.00",
 4321         "Cuban pesos1.00",
 4322         "Cypriot Pound1.00",
 4323         "Cypriot pound1.00",
 4324         "Cypriot pounds1.00",
 4325         "Czech Koruna1.00",
 4326         "Czech koruna1.00",
 4327         "Czech korunas1.00",
 4328         "Czechoslovak Hard Koruna1.00",
 4329         "Czechoslovak hard koruna1.00",
 4330         "Czechoslovak hard korunas1.00",
 4331         "DDM1.00",
 4332         "DDM1.00",
 4333         "DEM1.00",
 4334         "DEM1.00",
 4335         "DJF1.00",
 4336         "DKK1.00",
 4337         "DOP1.00",
 4338         "DZD1.00",
 4339         "Danish Krone1.00",
 4340         "Danish krone1.00",
 4341         "Danish kroner1.00",
 4342         "German Mark1.00",
 4343         "German mark1.00",
 4344         "German marks1.00",
 4345         "Djiboutian Franc1.00",
 4346         "Djiboutian franc1.00",
 4347         "Djiboutian francs1.00",
 4348         "Dominican Peso1.00",
 4349         "Dominican peso1.00",
 4350         "Dominican pesos1.00"