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