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