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