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