1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
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.
13 #include "unicode/utypes.h"
15 #if !UCONFIG_NO_FORMATTING
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"
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"
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
52 bool isnan(double x
) {
60 bool isinf(double x
) {
67 using icu::number::impl::DecimalQuantity
;
68 using namespace icu::number
;
70 //#define NUMFMTST_CACHE_DEBUG 1
71 #include "stdio.h" /* for sprintf */
72 // #include "iostream" // for cout
74 //#define NUMFMTST_DEBUG 1
76 static const UChar EUR
[] = {69,85,82,0}; // "EUR"
77 static const UChar ISO_CURRENCY_USD
[] = {0x55, 0x53, 0x44, 0}; // "USD"
80 // *****************************************************************************
81 // class NumberFormatTest
82 // *****************************************************************************
84 #define CHECK(status,str) if (U_FAILURE(status)) { errcheckln(status, UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
85 #define CHECK_DATA(status,str) if (U_FAILURE(status)) { dataerrln(UnicodeString("FAIL: ") + str + " - " + u_errorName(status)); return; }
87 void NumberFormatTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
90 TESTCASE_AUTO(TestCurrencySign
);
91 TESTCASE_AUTO(TestCurrency
);
92 TESTCASE_AUTO(TestParse
);
93 TESTCASE_AUTO(TestRounding487
);
94 TESTCASE_AUTO(TestQuotes
);
95 TESTCASE_AUTO(TestExponential
);
96 TESTCASE_AUTO(TestPatterns
);
97 TESTCASE_AUTO(Test20186_SpacesAroundSemicolon
);
99 // Upgrade to alphaWorks - liu 5/99
100 TESTCASE_AUTO(TestExponent
);
101 TESTCASE_AUTO(TestScientific
);
102 TESTCASE_AUTO(TestPad
);
103 TESTCASE_AUTO(TestPatterns2
);
104 TESTCASE_AUTO(TestSecondaryGrouping
);
105 TESTCASE_AUTO(TestSurrogateSupport
);
106 TESTCASE_AUTO(TestAPI
);
108 TESTCASE_AUTO(TestCurrencyObject
);
109 TESTCASE_AUTO(TestCurrencyPatterns
);
110 //TESTCASE_AUTO(TestDigitList);
111 TESTCASE_AUTO(TestWhiteSpaceParsing
);
112 TESTCASE_AUTO(TestComplexCurrency
); // This test removed because CLDR no longer uses choice formats in currency symbols.
113 TESTCASE_AUTO(TestRegCurrency
);
114 TESTCASE_AUTO(TestSymbolsWithBadLocale
);
115 TESTCASE_AUTO(TestAdoptDecimalFormatSymbols
);
117 TESTCASE_AUTO(TestScientific2
);
118 TESTCASE_AUTO(TestScientificGrouping
);
119 TESTCASE_AUTO(TestInt64
);
121 TESTCASE_AUTO(TestPerMill
);
122 TESTCASE_AUTO(TestIllegalPatterns
);
123 TESTCASE_AUTO(TestCases
);
125 TESTCASE_AUTO(TestCurrencyNames
);
126 TESTCASE_AUTO(Test20484_NarrowSymbolFallback
);
127 TESTCASE_AUTO(TestCurrencyAmount
);
128 TESTCASE_AUTO(TestCurrencyUnit
);
129 TESTCASE_AUTO(TestCoverage
);
130 TESTCASE_AUTO(TestLocalizedPatternSymbolCoverage
);
131 TESTCASE_AUTO(TestJB3832
);
132 TESTCASE_AUTO(TestHost
);
133 TESTCASE_AUTO(TestHostClone
);
134 TESTCASE_AUTO(TestCurrencyFormat
);
135 TESTCASE_AUTO(TestRounding
);
136 TESTCASE_AUTO(TestNonpositiveMultiplier
);
137 TESTCASE_AUTO(TestNumberingSystems
);
138 TESTCASE_AUTO(TestSpaceParsing
);
139 TESTCASE_AUTO(TestMultiCurrencySign
);
140 TESTCASE_AUTO(TestCurrencyFormatForMixParsing
);
141 TESTCASE_AUTO(TestMismatchedCurrencyFormatFail
);
142 TESTCASE_AUTO(TestDecimalFormatCurrencyParse
);
143 TESTCASE_AUTO(TestCurrencyIsoPluralFormat
);
144 TESTCASE_AUTO(TestCurrencyParsing
);
145 TESTCASE_AUTO(TestParseCurrencyInUCurr
);
146 TESTCASE_AUTO(TestFormatAttributes
);
147 TESTCASE_AUTO(TestFieldPositionIterator
);
148 TESTCASE_AUTO(TestDecimal
);
149 TESTCASE_AUTO(TestCurrencyFractionDigits
);
150 TESTCASE_AUTO(TestExponentParse
);
151 TESTCASE_AUTO(TestExplicitParents
);
152 TESTCASE_AUTO(TestLenientParse
);
153 TESTCASE_AUTO(TestAvailableNumberingSystems
);
154 TESTCASE_AUTO(TestRoundingPattern
);
155 TESTCASE_AUTO(Test9087
);
156 TESTCASE_AUTO(TestFormatFastpaths
);
157 TESTCASE_AUTO(TestFormattableSize
);
158 TESTCASE_AUTO(TestUFormattable
);
159 TESTCASE_AUTO(TestSignificantDigits
);
160 TESTCASE_AUTO(TestShowZero
);
161 TESTCASE_AUTO(TestCompatibleCurrencies
);
162 TESTCASE_AUTO(TestBug9936
);
163 TESTCASE_AUTO(TestParseNegativeWithFaLocale
);
164 TESTCASE_AUTO(TestParseNegativeWithAlternateMinusSign
);
165 TESTCASE_AUTO(TestCustomCurrencySignAndSeparator
);
166 TESTCASE_AUTO(TestParseSignsAndMarks
);
167 TESTCASE_AUTO(Test10419RoundingWith0FractionDigits
);
168 TESTCASE_AUTO(Test10468ApplyPattern
);
169 TESTCASE_AUTO(TestRoundingScientific10542
);
170 TESTCASE_AUTO(TestZeroScientific10547
);
171 TESTCASE_AUTO(TestAccountingCurrency
);
172 TESTCASE_AUTO(TestEquality
);
173 TESTCASE_AUTO(TestCurrencyUsage
);
174 TESTCASE_AUTO(TestDoubleLimit11439
);
175 TESTCASE_AUTO(TestGetAffixes
);
176 TESTCASE_AUTO(TestToPatternScientific11648
);
177 TESTCASE_AUTO(TestBenchmark
);
178 TESTCASE_AUTO(TestCtorApplyPatternDifference
);
179 TESTCASE_AUTO(TestFractionalDigitsForCurrency
);
180 TESTCASE_AUTO(TestFormatCurrencyPlural
);
181 TESTCASE_AUTO(Test11868
);
182 TESTCASE_AUTO(Test11739_ParseLongCurrency
);
183 TESTCASE_AUTO(Test13035_MultiCodePointPaddingInPattern
);
184 TESTCASE_AUTO(Test13737_ParseScientificStrict
);
185 TESTCASE_AUTO(Test10727_RoundingZero
);
186 TESTCASE_AUTO(Test11376_getAndSetPositivePrefix
);
187 TESTCASE_AUTO(Test11475_signRecognition
);
188 TESTCASE_AUTO(Test11640_getAffixes
);
189 TESTCASE_AUTO(Test11649_toPatternWithMultiCurrency
);
190 TESTCASE_AUTO(Test13327_numberingSystemBufferOverflow
);
191 TESTCASE_AUTO(Test13391_chakmaParsing
);
192 TESTCASE_AUTO(Test11735_ExceptionIssue
);
193 TESTCASE_AUTO(Test11035_FormatCurrencyAmount
);
194 TESTCASE_AUTO(Test11318_DoubleConversion
);
195 TESTCASE_AUTO(TestParsePercentRegression
);
196 TESTCASE_AUTO(TestMultiplierWithScale
);
197 TESTCASE_AUTO(TestFastFormatInt32
);
198 TESTCASE_AUTO(Test11646_Equality
);
199 TESTCASE_AUTO(TestParseNaN
);
200 TESTCASE_AUTO(TestFormatFailIfMoreThanMaxDigits
);
201 TESTCASE_AUTO(TestParseCaseSensitive
);
202 TESTCASE_AUTO(TestParseNoExponent
);
203 TESTCASE_AUTO(TestSignAlwaysShown
);
204 TESTCASE_AUTO(TestMinimumGroupingDigits
);
205 TESTCASE_AUTO(Test11897_LocalizedPatternSeparator
);
206 TESTCASE_AUTO(Test13055_PercentageRounding
);
207 TESTCASE_AUTO(Test11839
);
208 TESTCASE_AUTO(Test10354
);
209 TESTCASE_AUTO(Test11645_ApplyPatternEquality
);
210 TESTCASE_AUTO(Test12567
);
211 TESTCASE_AUTO(Test11626_CustomizeCurrencyPluralInfo
);
212 TESTCASE_AUTO(Test20073_StrictPercentParseErrorIndex
);
213 TESTCASE_AUTO(Test13056_GroupingSize
);
214 TESTCASE_AUTO(Test11025_CurrencyPadding
);
215 TESTCASE_AUTO(Test11648_ExpDecFormatMalPattern
);
216 TESTCASE_AUTO(Test11649_DecFmtCurrencies
);
217 TESTCASE_AUTO(Test13148_ParseGroupingSeparators
);
218 TESTCASE_AUTO(Test12753_PatternDecimalPoint
);
219 TESTCASE_AUTO(Test11647_PatternCurrencySymbols
);
220 TESTCASE_AUTO(Test11913_BigDecimal
);
221 TESTCASE_AUTO(Test11020_RoundingInScientificNotation
);
222 TESTCASE_AUTO(Test11640_TripleCurrencySymbol
);
223 TESTCASE_AUTO(Test13763_FieldPositionIteratorOffset
);
224 TESTCASE_AUTO(Test13777_ParseLongNameNonCurrencyMode
);
225 TESTCASE_AUTO(Test13804_EmptyStringsWhenParsing
);
226 TESTCASE_AUTO(Test20037_ScientificIntegerOverflow
);
227 TESTCASE_AUTO(Test13840_ParseLongStringCrash
);
228 TESTCASE_AUTO(Test13850_EmptyStringCurrency
);
229 TESTCASE_AUTO(Test20348_CurrencyPrefixOverride
);
230 TESTCASE_AUTO(Test20358_GroupingInPattern
);
231 TESTCASE_AUTO(Test13731_DefaultCurrency
);
232 TESTCASE_AUTO(Test20499_CurrencyVisibleDigitsPlural
);
236 // -------------------------------------
238 // Test API (increase code coverage)
240 NumberFormatTest::TestAPI(void)
243 UErrorCode status
= U_ZERO_ERROR
;
244 NumberFormat
*test
= NumberFormat::createInstance("root", status
);
245 if(U_FAILURE(status
)) {
246 dataerrln("unable to create format object - %s", u_errorName(status
));
249 test
->setMinimumIntegerDigits(10);
250 test
->setMaximumIntegerDigits(1);
252 test
->setMinimumFractionDigits(10);
253 test
->setMaximumFractionDigits(1);
255 UnicodeString result
;
257 Formattable
bla("Paja Patak"); // Donald Duck for non Serbian speakers
258 test
->format(bla
, result
, pos
, status
);
259 if(U_SUCCESS(status
)) {
260 errln("Yuck... Formatted a duck... As a number!");
262 status
= U_ZERO_ERROR
;
267 test
->format(ll
, result
);
268 assertEquals("format int64_t error", u
"2.0", result
);
270 test
->setMinimumIntegerDigits(4);
271 test
->setMinimumFractionDigits(4);
274 test
->format(ll
, result
);
275 assertEquals("format int64_t error", u
"0,012.0000", result
);
278 LocalPointer
<CurrencyAmount
> currAmt(test
->parseCurrency("",ppos
));
279 // old test for (U_FAILURE(status)) was bogus here, method does not set status!
280 if (ppos
.getIndex()) {
281 errln("Parsed empty string as currency");
288 class StubNumberFormat
:public NumberFormat
{
290 StubNumberFormat(){};
291 virtual UnicodeString
& format(double ,UnicodeString
& appendTo
,FieldPosition
& ) const {
294 virtual UnicodeString
& format(int32_t ,UnicodeString
& appendTo
,FieldPosition
& ) const {
295 return appendTo
.append((UChar
)0x0033);
297 virtual UnicodeString
& format(int64_t number
,UnicodeString
& appendTo
,FieldPosition
& pos
) const {
298 return NumberFormat::format(number
, appendTo
, pos
);
300 virtual UnicodeString
& format(const Formattable
& , UnicodeString
& appendTo
, FieldPosition
& , UErrorCode
& ) const {
303 virtual void parse(const UnicodeString
& ,
305 ParsePosition
& ) const {}
306 virtual void parse( const UnicodeString
& ,
308 UErrorCode
& ) const {}
309 virtual UClassID
getDynamicClassID(void) const {
310 static char classID
= 0;
311 return (UClassID
)&classID
;
313 virtual Format
* clone() const {return NULL
;}
317 NumberFormatTest::TestCoverage(void){
318 StubNumberFormat stub
;
319 UnicodeString
agent("agent");
322 if (stub
.format(num
, agent
, pos
) != UnicodeString("agent3")){
323 errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)");
327 void NumberFormatTest::TestLocalizedPatternSymbolCoverage() {
328 IcuTestErrorCode
errorCode(*this, "TestLocalizedPatternSymbolCoverage");
329 // Ticket #12961: DecimalFormat::toLocalizedPattern() is not working as designed.
330 DecimalFormatSymbols
dfs(errorCode
);
331 dfs
.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
, u
'⁖');
332 dfs
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, u
'⁘');
333 dfs
.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
, u
'⁙');
334 dfs
.setSymbol(DecimalFormatSymbols::kDigitSymbol
, u
'▰');
335 dfs
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, u
'໐');
336 dfs
.setSymbol(DecimalFormatSymbols::kSignificantDigitSymbol
, u
'⁕');
337 dfs
.setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, u
'†');
338 dfs
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, u
'‡');
339 dfs
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, u
'⁜');
340 dfs
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, u
'‱');
341 dfs
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, u
"⁑⁑"); // tests multi-char sequence
342 dfs
.setSymbol(DecimalFormatSymbols::kPadEscapeSymbol
, u
'⁂');
345 UnicodeString
standardPattern(u
"#,##0.05+%;#,##0.05-%");
346 UnicodeString
localizedPattern(u
"▰⁖▰▰໐⁘໐໕†⁜⁙▰⁖▰▰໐⁘໐໕‡⁜");
348 DecimalFormat
df1("#", new DecimalFormatSymbols(dfs
), errorCode
);
349 df1
.applyPattern(standardPattern
, errorCode
);
350 DecimalFormat
df2("#", new DecimalFormatSymbols(dfs
), errorCode
);
351 df2
.applyLocalizedPattern(localizedPattern
, errorCode
);
352 assertTrue("DecimalFormat instances should be equal", df1
== df2
);
354 assertEquals("toPattern should match on localizedPattern instance",
355 standardPattern
, df2
.toPattern(p2
));
357 assertEquals("toLocalizedPattern should match on standardPattern instance",
358 localizedPattern
, df1
.toLocalizedPattern(lp1
));
362 UnicodeString
standardPattern(u
"* @@@E0‰");
363 UnicodeString
localizedPattern(u
"⁂ ⁕⁕⁕⁑⁑໐‱");
365 DecimalFormat
df1("#", new DecimalFormatSymbols(dfs
), errorCode
);
366 df1
.applyPattern(standardPattern
, errorCode
);
367 DecimalFormat
df2("#", new DecimalFormatSymbols(dfs
), errorCode
);
368 df2
.applyLocalizedPattern(localizedPattern
, errorCode
);
369 assertTrue("DecimalFormat instances should be equal", df1
== df2
);
371 assertEquals("toPattern should match on localizedPattern instance",
372 standardPattern
, df2
.toPattern(p2
));
374 assertEquals("toLocalizedPattern should match on standardPattern instance",
375 localizedPattern
, df1
.toLocalizedPattern(lp1
));
379 // Test various patterns
381 NumberFormatTest::TestPatterns(void)
383 UErrorCode status
= U_ZERO_ERROR
;
384 DecimalFormatSymbols
sym(Locale::getUS(), status
);
385 if (U_FAILURE(status
)) { errcheckln(status
, "FAIL: Could not construct DecimalFormatSymbols - %s", u_errorName(status
)); return; }
387 const char* pat
[] = { "#.#", "#.", ".#", "#" };
388 int32_t pat_length
= UPRV_LENGTHOF(pat
);
389 const char* newpat
[] = { "0.#", "0.", "#.0", "0" };
390 const char* num
[] = { "0", "0.", ".0", "0" };
391 for (int32_t i
=0; i
<pat_length
; ++i
)
393 status
= U_ZERO_ERROR
;
394 DecimalFormat
fmt(pat
[i
], sym
, status
);
395 if (U_FAILURE(status
)) { errln((UnicodeString
)"FAIL: DecimalFormat constructor failed for " + pat
[i
]); continue; }
396 UnicodeString newp
; fmt
.toPattern(newp
);
397 if (!(newp
== newpat
[i
]))
398 errln((UnicodeString
)"FAIL: Pattern " + pat
[i
] + " should transmute to " + newpat
[i
] +
399 "; " + newp
+ " seen instead");
401 UnicodeString s
; (*(NumberFormat
*)&fmt
).format((int32_t)0, s
);
404 errln((UnicodeString
)"FAIL: Pattern " + pat
[i
] + " should format zero as " + num
[i
] +
405 "; " + s
+ " seen instead");
406 logln((UnicodeString
)"Min integer digits = " + fmt
.getMinimumIntegerDigits());
411 void NumberFormatTest::Test20186_SpacesAroundSemicolon() {
412 IcuTestErrorCode
status(*this, "Test20186_SpacesAroundSemicolon");
413 DecimalFormat
df(u
"0.00 ; -0.00", {"en-us", status
}, status
);
414 expect2(df
, 1, u
"1.00 ");
415 expect2(df
, -1, u
" -1.00");
417 df
= DecimalFormat(u
"0.00;", {"en-us", status
}, status
);
418 expect2(df
, 1, u
"1.00");
419 expect2(df
, -1, u
"-1.00");
421 df
= DecimalFormat(u
"0.00;0.00", {"en-us", status
}, status
);
422 expect2(df
, 1, u
"1.00");
423 expect(df
, -1, u
"1.00"); // parses as 1, not -1
425 df
= DecimalFormat(u
" 0.00 ; -0.00 ", {"en-us", status
}, status
);
426 expect2(df
, 1, u
" 1.00 ");
427 expect2(df
, -1, u
" -1.00 ");
431 icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
432 icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
433 icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
437 NumberFormatTest::TestDigitList(void)
439 // API coverage for DigitList
442 list1.fDecimalAt = 1;
444 list2.set((int32_t)1);
445 if (list1 != list2) {
446 errln("digitlist append, operator!= or set failed ");
448 if (!(list1 == list2)) {
449 errln("digitlist append, operator== or set failed ");
454 // -------------------------------------
456 // Test exponential pattern
458 NumberFormatTest::TestExponential(void)
460 UErrorCode status
= U_ZERO_ERROR
;
461 DecimalFormatSymbols
sym(Locale::getUS(), status
);
462 if (U_FAILURE(status
)) { errcheckln(status
, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status
)); return; }
463 const char* pat
[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
464 int32_t pat_length
= UPRV_LENGTHOF(pat
);
466 // The following #if statements allow this test to be built and run on
467 // platforms that do not have standard IEEE numerics. For example,
468 // S/390 doubles have an exponent range of -78 to +75. For the
469 // following #if statements to work, float.h must define
470 // DBL_MAX_10_EXP to be a compile-time constant.
472 // This section may be expanded as needed.
474 #if DBL_MAX_10_EXP > 300
475 double val
[] = { 0.01234, 123456789, 1.23e300
, -3.141592653e-271 };
476 int32_t val_length
= UPRV_LENGTHOF(val
);
477 const char* valFormat
[] =
480 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
482 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
484 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
486 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
490 0.01234, 123460000, 1.23E300
, -3.1416E-271,
491 0.01234, 123460000, 1.23E300
, -3.1416E-271,
492 0.01234, 123456800, 1.23E300
, -3.141593E-271,
493 0.01234, 123500000, 1.23E300
, -3.142E-271,
495 #elif DBL_MAX_10_EXP > 70
496 double val
[] = { 0.01234, 123456789, 1.23e70
, -3.141592653e-71 };
497 int32_t val_length
= UPRV_LENGTHOF(val
);
501 "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
503 "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
505 "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
507 "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
511 0.01234, 123460000, 1.23E70
, -3.1416E-71,
512 0.01234, 123460000, 1.23E70
, -3.1416E-71,
513 0.01234, 123456800, 1.23E70
, -3.141593E-71,
514 0.01234, 123500000, 1.23E70
, -3.142E-71,
517 // Don't test double conversion
519 int32_t val_length
= 0;
520 char** valFormat
= 0;
521 double* valParse
= 0;
522 logln("Warning: Skipping double conversion tests");
525 int32_t lval
[] = { 0, -1, 1, 123456789 };
526 int32_t lval_length
= UPRV_LENGTHOF(lval
);
527 const char* lvalFormat
[] =
530 "0E0", "-1E0", "1E0", "1.2346E8",
532 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
534 "0E000", "-1E000", "1E000", "123.4568E006",
536 "0E0", "[1E0]", "1E0", "1.235E8"
538 int32_t lvalParse
[] =
545 int32_t ival
= 0, ilval
= 0;
546 for (int32_t p
=0; p
<pat_length
; ++p
)
548 DecimalFormat
fmt(pat
[p
], sym
, status
);
549 if (U_FAILURE(status
)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
550 UnicodeString pattern
;
551 logln((UnicodeString
)"Pattern \"" + pat
[p
] + "\" -toPattern-> \"" +
552 fmt
.toPattern(pattern
) + "\"");
554 for (v
=0; v
<val_length
; ++v
)
556 UnicodeString s
; (*(NumberFormat
*)&fmt
).format(val
[v
], s
);
557 logln((UnicodeString
)" " + val
[v
] + " -format-> " + s
);
558 if (s
!= valFormat
[v
+ival
])
559 errln((UnicodeString
)"FAIL: Expected " + valFormat
[v
+ival
]);
561 ParsePosition
pos(0);
563 fmt
.parse(s
, af
, pos
);
565 UBool useEpsilon
= FALSE
;
566 if (af
.getType() == Formattable::kLong
)
568 else if (af
.getType() == Formattable::kDouble
) {
570 #if U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400
571 // S/390 will show a failure like this:
572 //| -3.141592652999999e-271 -format-> -3.1416E-271
573 //| -parse-> -3.1416e-271
574 //| FAIL: Expected -3.141599999999999e-271
575 // To compensate, we use an epsilon-based equality
576 // test on S/390 only. We don't want to do this in
577 // general because it's less exacting.
582 errln(UnicodeString("FAIL: Non-numeric Formattable returned: ") + pattern
+ " " + s
);
585 if (pos
.getIndex() == s
.length())
587 logln((UnicodeString
)" -parse-> " + a
);
588 // Use epsilon comparison as necessary
590 (uprv_fabs(a
- valParse
[v
+ival
]) / a
> (2*DBL_EPSILON
))) ||
591 (!useEpsilon
&& a
!= valParse
[v
+ival
]))
593 errln((UnicodeString
)"FAIL: Expected " + valParse
[v
+ival
] + " but got " + a
598 errln((UnicodeString
)"FAIL: Partial parse (" + pos
.getIndex() + " chars) -> " + a
);
599 errln((UnicodeString
)" should be (" + s
.length() + " chars) -> " + valParse
[v
+ival
]);
602 for (v
=0; v
<lval_length
; ++v
)
605 (*(NumberFormat
*)&fmt
).format(lval
[v
], s
);
606 logln((UnicodeString
)" " + lval
[v
] + "L -format-> " + s
);
607 if (s
!= lvalFormat
[v
+ilval
])
608 errln((UnicodeString
)"ERROR: Expected " + lvalFormat
[v
+ilval
] + " Got: " + s
);
610 ParsePosition
pos(0);
612 fmt
.parse(s
, af
, pos
);
613 if (af
.getType() == Formattable::kLong
||
614 af
.getType() == Formattable::kInt64
) {
615 UErrorCode status
= U_ZERO_ERROR
;
616 int32_t a
= af
.getLong(status
);
617 if (pos
.getIndex() == s
.length())
619 logln((UnicodeString
)" -parse-> " + a
);
620 if (a
!= lvalParse
[v
+ilval
])
621 errln((UnicodeString
)"FAIL: Expected " + lvalParse
[v
+ilval
] + " but got " + a
);
624 errln((UnicodeString
)"FAIL: Partial parse (" + pos
.getIndex() + " chars) -> " + a
);
627 errln((UnicodeString
)"FAIL: Non-long Formattable returned for " + s
628 + " Double: " + af
.getDouble()
629 + ", Long: " + af
.getLong());
632 ilval
+= lval_length
;
637 NumberFormatTest::TestScientific2() {
639 UErrorCode status
= U_ZERO_ERROR
;
640 DecimalFormat
* fmt
= (DecimalFormat
*)NumberFormat::createCurrencyInstance("en_US", status
);
641 if (U_SUCCESS(status
)) {
643 expect(*fmt
, num
, "$12.34");
644 fmt
->setScientificNotation(TRUE
);
645 expect(*fmt
, num
, "$1.23E1");
646 fmt
->setScientificNotation(FALSE
);
647 expect(*fmt
, num
, "$12.34");
653 NumberFormatTest::TestScientificGrouping() {
655 UErrorCode status
= U_ZERO_ERROR
;
656 DecimalFormat
fmt("##0.00E0",status
);
657 if (assertSuccess("", status
, true, __FILE__
, __LINE__
)) {
658 expect(fmt
, .01234, "12.3E-3");
659 expect(fmt
, .1234, "123E-3");
660 expect(fmt
, 1.234, "1.23E0");
661 expect(fmt
, 12.34, "12.3E0");
662 expect(fmt
, 123.4, "123E0");
663 expect(fmt
, 1234., "1.23E3");
667 /*static void setFromString(DigitList& dl, const char* str) {
669 UBool decimalSet = FALSE;
671 while ((c = *str++)) {
673 dl.fIsPositive = FALSE;
674 } else if (c == '+') {
675 dl.fIsPositive = TRUE;
676 } else if (c == '.') {
677 dl.fDecimalAt = dl.fCount;
684 dl.fDecimalAt = dl.fCount;
689 NumberFormatTest::TestInt64() {
690 UErrorCode status
= U_ZERO_ERROR
;
691 DecimalFormat
fmt("#.#E0",status
);
692 if (U_FAILURE(status
)) {
693 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
696 fmt
.setMaximumFractionDigits(20);
697 if (U_SUCCESS(status
)) {
698 expect(fmt
, (Formattable
)(int64_t)0, "0E0");
699 expect(fmt
, (Formattable
)(int64_t)-1, "-1E0");
700 expect(fmt
, (Formattable
)(int64_t)1, "1E0");
701 expect(fmt
, (Formattable
)(int64_t)2147483647, "2.147483647E9");
702 expect(fmt
, (Formattable
)((int64_t)-2147483647-1), "-2.147483648E9");
703 expect(fmt
, (Formattable
)(int64_t)U_INT64_MAX
, "9.223372036854775807E18");
704 expect(fmt
, (Formattable
)(int64_t)U_INT64_MIN
, "-9.223372036854775808E18");
707 // also test digitlist
708 /* int64_t int64max = U_INT64_MAX;
709 int64_t int64min = U_INT64_MIN;
710 const char* int64maxstr = "9223372036854775807";
711 const char* int64minstr = "-9223372036854775808";
712 UnicodeString fail("fail: ");
714 // test max int64 value
716 setFromString(dl, int64maxstr);
718 if (!dl.fitsIntoInt64(FALSE)) {
719 errln(fail + int64maxstr + " didn't fit");
721 int64_t int64Value = dl.getInt64();
722 if (int64Value != int64max) {
723 errln(fail + int64maxstr);
726 int64Value = dl.getInt64();
727 if (int64Value != int64max) {
728 errln(fail + int64maxstr);
731 // test negative of max int64 value (1 shy of min int64 value)
732 dl.fIsPositive = FALSE;
734 if (!dl.fitsIntoInt64(FALSE)) {
735 errln(fail + "-" + int64maxstr + " didn't fit");
737 int64_t int64Value = dl.getInt64();
738 if (int64Value != -int64max) {
739 errln(fail + "-" + int64maxstr);
742 int64Value = dl.getInt64();
743 if (int64Value != -int64max) {
744 errln(fail + "-" + int64maxstr);
747 // test min int64 value
748 setFromString(dl, int64minstr);
750 if (!dl.fitsIntoInt64(FALSE)) {
751 errln(fail + "-" + int64minstr + " didn't fit");
753 int64_t int64Value = dl.getInt64();
754 if (int64Value != int64min) {
755 errln(fail + int64minstr);
758 int64Value = dl.getInt64();
759 if (int64Value != int64min) {
760 errln(fail + int64minstr);
763 // test negative of min int 64 value (1 more than max int64 value)
764 dl.fIsPositive = TRUE; // won't fit
766 if (dl.fitsIntoInt64(FALSE)) {
767 errln(fail + "-(" + int64minstr + ") didn't fit");
772 // -------------------------------------
774 // Test the handling of quotes
776 NumberFormatTest::TestQuotes(void)
778 UErrorCode status
= U_ZERO_ERROR
;
780 DecimalFormatSymbols
*sym
= new DecimalFormatSymbols(Locale::getUS(), status
);
781 if (U_FAILURE(status
)) {
782 errcheckln(status
, "Fail to create DecimalFormatSymbols - %s", u_errorName(status
));
786 pat
= new UnicodeString("a'fo''o'b#");
787 DecimalFormat
*fmt
= new DecimalFormat(*pat
, *sym
, status
);
789 ((NumberFormat
*)fmt
)->format((int32_t)123, s
);
790 logln((UnicodeString
)"Pattern \"" + *pat
+ "\"");
791 logln((UnicodeString
)" Format 123 -> " + escape(s
));
792 if (!(s
=="afo'ob123"))
793 errln((UnicodeString
)"FAIL: Expected afo'ob123");
799 pat
= new UnicodeString("a''b#");
800 fmt
= new DecimalFormat(*pat
, *sym
, status
);
801 ((NumberFormat
*)fmt
)->format((int32_t)123, s
);
802 logln((UnicodeString
)"Pattern \"" + *pat
+ "\"");
803 logln((UnicodeString
)" Format 123 -> " + escape(s
));
805 errln((UnicodeString
)"FAIL: Expected a'b123");
812 * Test the handling of the currency symbol in patterns.
815 NumberFormatTest::TestCurrencySign(void)
817 UErrorCode status
= U_ZERO_ERROR
;
818 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols(Locale::getUS(), status
);
820 UChar currency
= 0x00A4;
821 if (U_FAILURE(status
)) {
822 errcheckln(status
, "Fail to create DecimalFormatSymbols - %s", u_errorName(status
));
826 // "\xA4#,##0.00;-\xA4#,##0.00"
827 pat
.append(currency
).append("#,##0.00;-").
828 append(currency
).append("#,##0.00");
829 DecimalFormat
*fmt
= new DecimalFormat(pat
, *sym
, status
);
830 UnicodeString s
; ((NumberFormat
*)fmt
)->format(1234.56, s
);
832 logln((UnicodeString
)"Pattern \"" + fmt
->toPattern(pat
) + "\"");
833 logln((UnicodeString
)" Format " + 1234.56 + " -> " + escape(s
));
834 if (s
!= "$1,234.56") dataerrln((UnicodeString
)"FAIL: Expected $1,234.56");
836 ((NumberFormat
*)fmt
)->format(- 1234.56, s
);
837 logln((UnicodeString
)" Format " + (-1234.56) + " -> " + escape(s
));
838 if (s
!= "-$1,234.56") dataerrln((UnicodeString
)"FAIL: Expected -$1,234.56");
841 // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
842 pat
.append(currency
).append(currency
).
843 append(" #,##0.00;").
844 append(currency
).append(currency
).
845 append(" -#,##0.00");
846 fmt
= new DecimalFormat(pat
, *sym
, status
);
848 ((NumberFormat
*)fmt
)->format(1234.56, s
);
849 logln((UnicodeString
)"Pattern \"" + fmt
->toPattern(pat
) + "\"");
850 logln((UnicodeString
)" Format " + 1234.56 + " -> " + escape(s
));
851 if (s
!= "USD 1,234.56") dataerrln((UnicodeString
)"FAIL: Expected USD 1,234.56");
853 ((NumberFormat
*)fmt
)->format(-1234.56, s
);
854 logln((UnicodeString
)" Format " + (-1234.56) + " -> " + escape(s
));
855 if (s
!= "USD -1,234.56") dataerrln((UnicodeString
)"FAIL: Expected USD -1,234.56");
858 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + u_errorName(status
));
861 // -------------------------------------
863 static UChar
toHexString(int32_t i
) { return (UChar
)(i
+ (i
< 10 ? 0x30 : (0x41 - 10))); }
866 NumberFormatTest::escape(UnicodeString
& s
)
869 for (int32_t i
=0; i
<s
.length(); ++i
)
871 UChar c
= s
[(int32_t)i
];
872 if (c
<= (UChar
)0x7F) buf
+= c
;
874 buf
+= (UChar
)0x5c; buf
+= (UChar
)0x55;
875 buf
+= toHexString((c
& 0xF000) >> 12);
876 buf
+= toHexString((c
& 0x0F00) >> 8);
877 buf
+= toHexString((c
& 0x00F0) >> 4);
878 buf
+= toHexString(c
& 0x000F);
885 // -------------------------------------
886 static const char* testCases
[][2]= {
887 /* locale ID */ /* expected */
888 {"ca_ES@currency=ESP", "\\u20A7\\u00A01.150" },
889 {"de_LU@currency=LUF", "1,150\\u00A0F" },
890 {"el_GR@currency=GRD", "1.150,50\\u00A0\\u0394\\u03C1\\u03C7" },
891 {"en_BE@currency=BEF", "1.150,50\\u00A0BEF" },
892 {"es_ES@currency=ESP", "1150\\u00A0\\u20A7" },
893 {"eu_ES@currency=ESP", "\\u20A7\\u00A01.150" },
894 {"gl_ES@currency=ESP", "1.150\\u00A0\\u20A7" },
895 {"it_IT@currency=ITL", "ITL\\u00A01.150" },
896 {"pt_PT@currency=PTE", "1150$50\\u00A0\\u200B"}, // per cldrbug 7670
897 {"en_US@currency=JPY", "\\u00A51,150"},
898 {"en_US@currency=jpy", "\\u00A51,150"},
899 {"en-US-u-cu-jpy", "\\u00A51,150"}
902 * Test localized currency patterns.
905 NumberFormatTest::TestCurrency(void)
907 UErrorCode status
= U_ZERO_ERROR
;
908 NumberFormat
* currencyFmt
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
909 if (U_FAILURE(status
)) {
910 dataerrln("Error calling NumberFormat::createCurrencyInstance()");
914 UnicodeString s
; currencyFmt
->format(1.50, s
);
915 logln((UnicodeString
)"Un pauvre ici a..........." + s
);
916 if (!(s
==CharsToUnicodeString("1,50\\u00A0$")))
917 errln((UnicodeString
)"FAIL: Expected 1,50<nbsp>$ but got " + s
);
921 int len
= uloc_canonicalize("de_DE@currency=DEM", loc
, 256, &status
);
922 (void)len
; // Suppress unused variable warning.
923 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
),status
);
924 currencyFmt
->format(1.50, s
);
925 logln((UnicodeString
)"Un pauvre en Allemagne a.." + s
);
926 if (!(s
==CharsToUnicodeString("1,50\\u00A0DM")))
927 errln((UnicodeString
)"FAIL: Expected 1,50<nbsp>DM but got " + s
);
930 len
= uloc_canonicalize("fr_FR@currency=FRF", loc
, 256, &status
);
931 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
932 currencyFmt
->format(1.50, s
);
933 logln((UnicodeString
)"Un pauvre en France a....." + s
);
934 if (!(s
==CharsToUnicodeString("1,50\\u00A0F")))
935 errln((UnicodeString
)"FAIL: Expected 1,50<nbsp>F");
937 if (U_FAILURE(status
))
938 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
940 for(int i
=0; i
< UPRV_LENGTHOF(testCases
); i
++){
941 status
= U_ZERO_ERROR
;
942 const char *localeID
= testCases
[i
][0];
943 UnicodeString
expected(testCases
[i
][1], -1, US_INV
);
944 expected
= expected
.unescape();
947 uloc_canonicalize(localeID
, loc
, 256, &status
);
948 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
949 if(U_FAILURE(status
)){
950 errln("Could not create currency formatter for locale %s",localeID
);
953 currencyFmt
->format(1150.50, s
);
955 errln(UnicodeString("FAIL: Expected: ")+expected
956 + UnicodeString(" Got: ") + s
957 + UnicodeString( " for locale: ")+ UnicodeString(localeID
) );
959 if (U_FAILURE(status
)){
960 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
966 // -------------------------------------
969 * Test the Currency object handling, new as of ICU 2.2.
971 void NumberFormatTest::TestCurrencyObject() {
972 UErrorCode ec
= U_ZERO_ERROR
;
974 NumberFormat::createCurrencyInstance(Locale::getUS(), ec
);
977 dataerrln("FAIL: getCurrencyInstance(US) - %s", u_errorName(ec
));
982 Locale
null("", "", "");
984 expectCurrency(*fmt
, null
, 1234.56, "$1,234.56");
986 expectCurrency(*fmt
, Locale::getFrance(),
987 1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
989 expectCurrency(*fmt
, Locale::getJapan(),
990 1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
992 expectCurrency(*fmt
, Locale("fr", "CH", ""),
993 1234.56, "CHF 1,234.56"); // no more 0.05 rounding here, see cldrbug 5548
995 expectCurrency(*fmt
, Locale::getUS(),
996 1234.56, "$1,234.56");
999 fmt
= NumberFormat::createCurrencyInstance(Locale::getFrance(), ec
);
1001 if (U_FAILURE(ec
)) {
1002 errln("FAIL: getCurrencyInstance(FRANCE)");
1007 expectCurrency(*fmt
, null
, 1234.56, CharsToUnicodeString("1\\u202F234,56 \\u20AC"));
1009 expectCurrency(*fmt
, Locale::getJapan(),
1010 1234.56, CharsToUnicodeString("1\\u202F235 JPY")); // Yen
1012 expectCurrency(*fmt
, Locale("fr", "CH", ""),
1013 1234.56, CharsToUnicodeString("1\\u202F234,56 CHF")); // no more 0.05 rounding here, see cldrbug 5548
1015 expectCurrency(*fmt
, Locale::getUS(),
1016 1234.56, CharsToUnicodeString("1\\u202F234,56 $US"));
1018 expectCurrency(*fmt
, Locale::getFrance(),
1019 1234.56, CharsToUnicodeString("1\\u202F234,56 \\u20AC")); // Euro
1024 // -------------------------------------
1027 * Do rudimentary testing of parsing.
1030 NumberFormatTest::TestParse(void)
1032 UErrorCode status
= U_ZERO_ERROR
;
1033 UnicodeString
arg("0");
1034 DecimalFormat
* format
= new DecimalFormat("00", status
);
1036 Formattable n
; format
->parse(arg
, n
, status
);
1037 logln((UnicodeString
)"parse(" + arg
+ ") = " + n
.getLong());
1038 if (n
.getType() != Formattable::kLong
||
1039 n
.getLong() != 0) errln((UnicodeString
)"FAIL: Expected 0");
1041 if (U_FAILURE(status
)) errcheckln(status
, (UnicodeString
)"FAIL: Status " + u_errorName(status
));
1043 //catch(Exception e) {
1044 // errln((UnicodeString)"Exception caught: " + e);
1048 // -------------------------------------
1050 static const char *lenientAffixTestCases
[] = {
1057 static const char *lenientMinusTestCases
[] = {
1063 static const char *lenientCurrencyTestCases
[] = {
1074 // changed from () to - per cldrbug 5674
1075 static const char *lenientNegativeCurrencyTestCases
[] = {
1083 "-$ 1\\u00A0000.00",
1087 static const char *lenientPercentTestCases
[] = {
1096 static const char *lenientNegativePercentTestCases
[] = {
1108 static const char *strictFailureTestCases
[] = {
1115 * Test lenient parsing.
1118 NumberFormatTest::TestLenientParse(void)
1120 UErrorCode status
= U_ZERO_ERROR
;
1121 DecimalFormat
*format
= new DecimalFormat("(#,##0)", status
);
1124 if (format
== NULL
|| U_FAILURE(status
)) {
1125 dataerrln("Unable to create DecimalFormat (#,##0) - %s", u_errorName(status
));
1127 format
->setLenient(TRUE
);
1128 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientAffixTestCases
); t
+= 1) {
1129 UnicodeString testCase
= ctou(lenientAffixTestCases
[t
]);
1131 format
->parse(testCase
, n
, status
);
1132 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1134 if (U_FAILURE(status
) || n
.getType() != Formattable::kLong
||
1136 dataerrln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientAffixTestCases
[t
]
1137 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1138 status
= U_ZERO_ERROR
;
1144 Locale
en_US("en_US");
1145 Locale
sv_SE("sv_SE");
1147 NumberFormat
*mFormat
= NumberFormat::createInstance(sv_SE
, UNUM_DECIMAL
, status
);
1149 if (mFormat
== NULL
|| U_FAILURE(status
)) {
1150 dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status
));
1152 mFormat
->setLenient(TRUE
);
1153 for (int32_t t
= 0; t
< UPRV_LENGTHOF(lenientMinusTestCases
); t
+= 1) {
1154 UnicodeString testCase
= ctou(lenientMinusTestCases
[t
]);
1156 mFormat
->parse(testCase
, n
, status
);
1157 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1159 if (U_FAILURE(status
) || n
.getType() != Formattable::kLong
|| n
.getLong() != -5) {
1160 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientMinusTestCases
[t
]
1161 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1162 status
= U_ZERO_ERROR
;
1168 mFormat
= NumberFormat::createInstance(en_US
, UNUM_DECIMAL
, status
);
1170 if (mFormat
== NULL
|| U_FAILURE(status
)) {
1171 dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status
));
1173 mFormat
->setLenient(TRUE
);
1174 for (int32_t t
= 0; t
< UPRV_LENGTHOF(lenientMinusTestCases
); t
+= 1) {
1175 UnicodeString testCase
= ctou(lenientMinusTestCases
[t
]);
1177 mFormat
->parse(testCase
, n
, status
);
1178 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1180 if (U_FAILURE(status
) || n
.getType() != Formattable::kLong
|| n
.getLong() != -5) {
1181 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientMinusTestCases
[t
]
1182 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1183 status
= U_ZERO_ERROR
;
1189 NumberFormat
*cFormat
= NumberFormat::createInstance(en_US
, UNUM_CURRENCY
, status
);
1191 if (cFormat
== NULL
|| U_FAILURE(status
)) {
1192 dataerrln("Unable to create NumberFormat (en_US, UNUM_CURRENCY) - %s", u_errorName(status
));
1194 cFormat
->setLenient(TRUE
);
1195 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientCurrencyTestCases
); t
+= 1) {
1196 UnicodeString testCase
= ctou(lenientCurrencyTestCases
[t
]);
1198 cFormat
->parse(testCase
, n
, status
);
1199 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1201 if (U_FAILURE(status
) ||n
.getType() != Formattable::kLong
||
1202 n
.getLong() != 1000) {
1203 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientCurrencyTestCases
[t
]
1204 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1205 status
= U_ZERO_ERROR
;
1209 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientNegativeCurrencyTestCases
); t
+= 1) {
1210 UnicodeString testCase
= ctou(lenientNegativeCurrencyTestCases
[t
]);
1212 cFormat
->parse(testCase
, n
, status
);
1213 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1215 if (U_FAILURE(status
) ||n
.getType() != Formattable::kLong
||
1216 n
.getLong() != -1000) {
1217 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientNegativeCurrencyTestCases
[t
]
1218 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1219 status
= U_ZERO_ERROR
;
1226 NumberFormat
*pFormat
= NumberFormat::createPercentInstance(en_US
, status
);
1228 if (pFormat
== NULL
|| U_FAILURE(status
)) {
1229 dataerrln("Unable to create NumberFormat::createPercentInstance (en_US) - %s", u_errorName(status
));
1231 pFormat
->setLenient(TRUE
);
1232 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientPercentTestCases
); t
+= 1) {
1233 UnicodeString testCase
= ctou(lenientPercentTestCases
[t
]);
1235 pFormat
->parse(testCase
, n
, status
);
1236 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getDouble());
1238 if (U_FAILURE(status
) ||n
.getType() != Formattable::kDouble
||
1239 n
.getDouble() != 0.25) {
1240 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientPercentTestCases
[t
]
1241 + (UnicodeString
) "\"; error code = " + u_errorName(status
)
1242 + "; got: " + n
.getDouble(status
));
1243 status
= U_ZERO_ERROR
;
1247 for (int32_t t
= 0; t
< UPRV_LENGTHOF (lenientNegativePercentTestCases
); t
+= 1) {
1248 UnicodeString testCase
= ctou(lenientNegativePercentTestCases
[t
]);
1250 pFormat
->parse(testCase
, n
, status
);
1251 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getDouble());
1253 if (U_FAILURE(status
) ||n
.getType() != Formattable::kDouble
||
1254 n
.getDouble() != -0.25) {
1255 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) lenientNegativePercentTestCases
[t
]
1256 + (UnicodeString
) "\"; error code = " + u_errorName(status
)
1257 + "; got: " + n
.getDouble(status
));
1258 status
= U_ZERO_ERROR
;
1265 // Test cases that should fail with a strict parse and pass with a
1267 NumberFormat
*nFormat
= NumberFormat::createInstance(en_US
, status
);
1269 if (nFormat
== NULL
|| U_FAILURE(status
)) {
1270 dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status
));
1272 // first, make sure that they fail with a strict parse
1273 for (int32_t t
= 0; t
< UPRV_LENGTHOF(strictFailureTestCases
); t
+= 1) {
1274 UnicodeString testCase
= ctou(strictFailureTestCases
[t
]);
1276 nFormat
->parse(testCase
, n
, status
);
1277 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1279 if (! U_FAILURE(status
)) {
1280 errln((UnicodeString
)"Strict Parse succeeded for \"" + (UnicodeString
) strictFailureTestCases
[t
]
1281 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1284 status
= U_ZERO_ERROR
;
1287 // then, make sure that they pass with a lenient parse
1288 nFormat
->setLenient(TRUE
);
1289 for (int32_t t
= 0; t
< UPRV_LENGTHOF(strictFailureTestCases
); t
+= 1) {
1290 UnicodeString testCase
= ctou(strictFailureTestCases
[t
]);
1292 nFormat
->parse(testCase
, n
, status
);
1293 logln((UnicodeString
)"parse(" + testCase
+ ") = " + n
.getLong());
1295 if (U_FAILURE(status
) ||n
.getType() != Formattable::kLong
||
1296 n
.getLong() != 1000) {
1297 errln((UnicodeString
)"Lenient parse failed for \"" + (UnicodeString
) strictFailureTestCases
[t
]
1298 + (UnicodeString
) "\"; error code = " + u_errorName(status
));
1299 status
= U_ZERO_ERROR
;
1307 // -------------------------------------
1310 * Test proper rounding by the format method.
1313 NumberFormatTest::TestRounding487(void)
1315 UErrorCode status
= U_ZERO_ERROR
;
1316 NumberFormat
*nf
= NumberFormat::createInstance(status
);
1317 if (U_FAILURE(status
)) {
1318 dataerrln("Error calling NumberFormat::createInstance()");
1322 roundingTest(*nf
, 0.00159999, 4, "0.0016");
1323 roundingTest(*nf
, 0.00995, 4, "0.01");
1325 roundingTest(*nf
, 12.3995, 3, "12.4");
1327 roundingTest(*nf
, 12.4999, 0, "12");
1328 roundingTest(*nf
, - 19.5, 0, "-20");
1330 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
1334 * Test the functioning of the secondary grouping value.
1336 void NumberFormatTest::TestSecondaryGrouping(void) {
1337 UErrorCode status
= U_ZERO_ERROR
;
1338 DecimalFormatSymbols
US(Locale::getUS(), status
);
1339 CHECK(status
, "DecimalFormatSymbols ct");
1341 DecimalFormat
f("#,##,###", US
, status
);
1342 CHECK(status
, "DecimalFormat ct");
1344 expect2(f
, (int32_t)123456789L, "12,34,56,789");
1345 expectPat(f
, "#,##,##0");
1346 f
.applyPattern("#,###", status
);
1347 CHECK(status
, "applyPattern");
1349 f
.setSecondaryGroupingSize(4);
1350 expect2(f
, (int32_t)123456789L, "12,3456,789");
1351 expectPat(f
, "#,####,##0");
1352 NumberFormat
*g
= NumberFormat::createInstance(Locale("hi", "IN"), status
);
1353 CHECK_DATA(status
, "createInstance(hi_IN)");
1356 int32_t l
= (int32_t)1876543210L;
1359 // expect "1,87,65,43,210", but with Hindi digits
1362 if (out
.length() != 14) {
1365 for (int32_t i
=0; i
<out
.length(); ++i
) {
1366 UBool expectGroup
= FALSE
;
1375 // Later -- fix this to get the actual grouping
1376 // character from the resource bundle.
1377 UBool isGroup
= (out
.charAt(i
) == 0x002C);
1378 if (isGroup
!= expectGroup
) {
1385 errln((UnicodeString
)"FAIL Expected " + l
+
1386 " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
1387 escape(out
) + "\"");
1389 logln((UnicodeString
)"Ok " + l
+
1391 escape(out
) + "\"");
1395 void NumberFormatTest::TestWhiteSpaceParsing(void) {
1396 UErrorCode ec
= U_ZERO_ERROR
;
1397 DecimalFormatSymbols
US(Locale::getUS(), ec
);
1398 DecimalFormat
fmt("a b#0c ", US
, ec
);
1399 if (U_FAILURE(ec
)) {
1400 errcheckln(ec
, "FAIL: Constructor - %s", u_errorName(ec
));
1403 // From ICU 62, flexible whitespace needs lenient mode
1404 fmt
.setLenient(TRUE
);
1406 expect(fmt
, "a b1234c ", n
);
1407 expect(fmt
, "a b1234c ", n
);
1411 * Test currencies whose display name is a ChoiceFormat.
1413 void NumberFormatTest::TestComplexCurrency() {
1415 // UErrorCode ec = U_ZERO_ERROR;
1416 // Locale loc("kn", "IN", "");
1417 // NumberFormat* fmt = NumberFormat::createCurrencyInstance(loc, ec);
1418 // if (U_SUCCESS(ec)) {
1419 // expect2(*fmt, 1.0, CharsToUnicodeString("Re.\\u00A01.00"));
1420 // Use .00392625 because that's 2^-8. Any value less than 0.005 is fine.
1421 // expect(*fmt, 1.00390625, CharsToUnicodeString("Re.\\u00A01.00")); // tricky
1422 // expect2(*fmt, 12345678.0, CharsToUnicodeString("Rs.\\u00A01,23,45,678.00"));
1423 // expect2(*fmt, 0.5, CharsToUnicodeString("Rs.\\u00A00.50"));
1424 // expect2(*fmt, -1.0, CharsToUnicodeString("-Re.\\u00A01.00"));
1425 // expect2(*fmt, -10.0, CharsToUnicodeString("-Rs.\\u00A010.00"));
1427 // errln("FAIL: getCurrencyInstance(kn_IN)");
1433 // -------------------------------------
1436 NumberFormatTest::roundingTest(NumberFormat
& nf
, double x
, int32_t maxFractionDigits
, const char* expected
)
1438 nf
.setMaximumFractionDigits(maxFractionDigits
);
1439 UnicodeString out
; nf
.format(x
, out
);
1440 logln((UnicodeString
)"" + x
+ " formats with " + maxFractionDigits
+ " fractional digits to " + out
);
1441 if (!(out
==expected
)) errln((UnicodeString
)"FAIL: Expected " + expected
);
1445 * Upgrade to alphaWorks
1447 void NumberFormatTest::TestExponent(void) {
1448 UErrorCode status
= U_ZERO_ERROR
;
1449 DecimalFormatSymbols
US(Locale::getUS(), status
);
1450 CHECK(status
, "DecimalFormatSymbols constructor");
1451 DecimalFormat
fmt1(UnicodeString("0.###E0"), US
, status
);
1452 CHECK(status
, "DecimalFormat(0.###E0)");
1453 DecimalFormat
fmt2(UnicodeString("0.###E+0"), US
, status
);
1454 CHECK(status
, "DecimalFormat(0.###E+0)");
1456 expect2(fmt1
, n
, "1.234E3");
1457 expect2(fmt2
, n
, "1.234E+3");
1458 expect(fmt1
, "1.234E+3", n
); // Either format should parse "E+3"
1462 * Upgrade to alphaWorks
1464 void NumberFormatTest::TestScientific(void) {
1465 UErrorCode status
= U_ZERO_ERROR
;
1466 DecimalFormatSymbols
US(Locale::getUS(), status
);
1467 CHECK(status
, "DecimalFormatSymbols constructor");
1469 // Test pattern round-trip
1470 const char* PAT
[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
1471 "0.###E0;[0.###E0]" };
1472 int32_t PAT_length
= UPRV_LENGTHOF(PAT
);
1473 int32_t DIGITS
[] = {
1474 // min int, max int, min frac, max frac
1475 1, 1, 0, 0, // "#E0"
1476 1, 1, 0, 4, // "0.####E0"
1477 2, 2, 3, 3, // "00.000E00"
1478 1, 3, 0, 4, // "##0.####E000"
1479 1, 1, 0, 3, // "0.###E0;[0.###E0]"
1481 for (int32_t i
=0; i
<PAT_length
; ++i
) {
1482 UnicodeString
pat(PAT
[i
]);
1483 DecimalFormat
df(pat
, US
, status
);
1484 CHECK(status
, "DecimalFormat constructor");
1488 logln(UnicodeString("Ok Pattern rt \"") +
1492 errln(UnicodeString("FAIL Pattern rt \"") +
1496 // Make sure digit counts match what we expect
1497 if (df
.getMinimumIntegerDigits() != DIGITS
[4*i
] ||
1498 df
.getMaximumIntegerDigits() != DIGITS
[4*i
+1] ||
1499 df
.getMinimumFractionDigits() != DIGITS
[4*i
+2] ||
1500 df
.getMaximumFractionDigits() != DIGITS
[4*i
+3]) {
1501 errln(UnicodeString("FAIL \"" + pat
+
1502 "\" min/max int; min/max frac = ") +
1503 df
.getMinimumIntegerDigits() + "/" +
1504 df
.getMaximumIntegerDigits() + ";" +
1505 df
.getMinimumFractionDigits() + "/" +
1506 df
.getMaximumFractionDigits() + ", expect " +
1508 DIGITS
[4*i
+1] + ";" +
1509 DIGITS
[4*i
+2] + "/" +
1515 // Test the constructor for default locale. We have to
1516 // manually set the default locale, as there is no
1517 // guarantee that the default locale has the same
1518 // scientific format.
1519 Locale def
= Locale::getDefault();
1520 Locale::setDefault(Locale::getUS(), status
);
1521 expect2(NumberFormat::createScientificInstance(status
),
1523 "1.2345678901E4", status
);
1524 Locale::setDefault(def
, status
);
1526 expect2(new DecimalFormat("#E0", US
, status
),
1528 "1.2345E4", status
);
1529 expect(new DecimalFormat("0E0", US
, status
),
1532 expect2(NumberFormat::createScientificInstance(Locale::getUS(), status
),
1534 "1.2345678901E4", status
);
1535 expect(new DecimalFormat("##0.###E0", US
, status
),
1538 expect(new DecimalFormat("##0.###E0", US
, status
),
1541 expect2(new DecimalFormat("##0.####E0", US
, status
),
1543 "12.345E3", status
);
1544 expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status
),
1546 "1,2345678901E4", status
);
1547 expect(new DecimalFormat("##0.####E0", US
, status
),
1549 "789.12E-9", status
);
1550 expect2(new DecimalFormat("##0.####E0", US
, status
),
1553 expect(new DecimalFormat(".###E0", US
, status
),
1556 expect2(new DecimalFormat(".###E0", US
, status
),
1560 expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
1561 new DecimalFormat("##E0", US),
1562 new DecimalFormat("####E0", US),
1563 new DecimalFormat("0E0", US),
1564 new DecimalFormat("00E0", US),
1565 new DecimalFormat("000E0", US),
1568 new String[] { "4.5678E7",
1577 ! Unroll this test into individual tests below...
1580 expect2(new DecimalFormat("#E0", US
, status
),
1581 (int32_t) 45678000, "4.5678E7", status
);
1582 expect2(new DecimalFormat("##E0", US
, status
),
1583 (int32_t) 45678000, "45.678E6", status
);
1584 expect2(new DecimalFormat("####E0", US
, status
),
1585 (int32_t) 45678000, "4567.8E4", status
);
1586 expect(new DecimalFormat("0E0", US
, status
),
1587 (int32_t) 45678000, "5E7", status
);
1588 expect(new DecimalFormat("00E0", US
, status
),
1589 (int32_t) 45678000, "46E6", status
);
1590 expect(new DecimalFormat("000E0", US
, status
),
1591 (int32_t) 45678000, "457E5", status
);
1593 expect(new DecimalFormat("###E0", US, status),
1594 new Object[] { new Double(0.0000123), "12.3E-6",
1595 new Double(0.000123), "123E-6",
1596 new Double(0.00123), "1.23E-3",
1597 new Double(0.0123), "12.3E-3",
1598 new Double(0.123), "123E-3",
1599 new Double(1.23), "1.23E0",
1600 new Double(12.3), "12.3E0",
1601 new Double(123), "123E0",
1602 new Double(1230), "1.23E3",
1605 ! Unroll this test into individual tests below...
1608 expect2(new DecimalFormat("###E0", US
, status
),
1609 0.0000123, "12.3E-6", status
);
1610 expect2(new DecimalFormat("###E0", US
, status
),
1611 0.000123, "123E-6", status
);
1612 expect2(new DecimalFormat("###E0", US
, status
),
1613 0.00123, "1.23E-3", status
);
1614 expect2(new DecimalFormat("###E0", US
, status
),
1615 0.0123, "12.3E-3", status
);
1616 expect2(new DecimalFormat("###E0", US
, status
),
1617 0.123, "123E-3", status
);
1618 expect2(new DecimalFormat("###E0", US
, status
),
1619 1.23, "1.23E0", status
);
1620 expect2(new DecimalFormat("###E0", US
, status
),
1621 12.3, "12.3E0", status
);
1622 expect2(new DecimalFormat("###E0", US
, status
),
1623 123.0, "123E0", status
);
1624 expect2(new DecimalFormat("###E0", US
, status
),
1625 1230.0, "1.23E3", status
);
1627 expect(new DecimalFormat("0.#E+00", US, status),
1628 new Object[] { new Double(0.00012), "1.2E-04",
1629 new Long(12000), "1.2E+04",
1632 ! Unroll this test into individual tests below...
1635 expect2(new DecimalFormat("0.#E+00", US
, status
),
1636 0.00012, "1.2E-04", status
);
1637 expect2(new DecimalFormat("0.#E+00", US
, status
),
1638 (int32_t) 12000, "1.2E+04", status
);
1642 * Upgrade to alphaWorks
1644 void NumberFormatTest::TestPad(void) {
1645 UErrorCode status
= U_ZERO_ERROR
;
1646 DecimalFormatSymbols
US(Locale::getUS(), status
);
1647 CHECK(status
, "DecimalFormatSymbols constructor");
1649 expect2(new DecimalFormat("*^##.##", US
, status
),
1650 int32_t(0), "^^^^0", status
);
1651 expect2(new DecimalFormat("*^##.##", US
, status
),
1652 -1.3, "^-1.3", status
);
1653 expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US
, status
),
1654 int32_t(0), "0.0E0______ g-m/s^2", status
);
1655 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US
, status
),
1656 1.0/3, "333.333E-3_ g-m/s^2", status
);
1657 expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US
, status
),
1658 int32_t(0), "0.0______ g-m/s^2", status
);
1659 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US
, status
),
1660 1.0/3, "0.33333__ g-m/s^2", status
);
1662 // Test padding before a sign
1663 const char *formatStr
= "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
1664 expect2(new DecimalFormat(formatStr
, US
, status
),
1665 int32_t(-10), "xxxxxxxxxx(10.0)", status
);
1666 expect2(new DecimalFormat(formatStr
, US
, status
),
1667 int32_t(-1000),"xxxxxxx(1,000.0)", status
);
1668 expect2(new DecimalFormat(formatStr
, US
, status
),
1669 int32_t(-1000000),"xxx(1,000,000.0)", status
);
1670 expect2(new DecimalFormat(formatStr
, US
, status
),
1671 -100.37, "xxxxxxxx(100.37)", status
);
1672 expect2(new DecimalFormat(formatStr
, US
, status
),
1673 -10456.37, "xxxxx(10,456.37)", status
);
1674 expect2(new DecimalFormat(formatStr
, US
, status
),
1675 -1120456.37, "xx(1,120,456.37)", status
);
1676 expect2(new DecimalFormat(formatStr
, US
, status
),
1677 -112045600.37, "(112,045,600.37)", status
);
1678 expect2(new DecimalFormat(formatStr
, US
, status
),
1679 -1252045600.37,"(1,252,045,600.37)", status
);
1681 expect2(new DecimalFormat(formatStr
, US
, status
),
1682 int32_t(10), "xxxxxxxxxxxx10.0", status
);
1683 expect2(new DecimalFormat(formatStr
, US
, status
),
1684 int32_t(1000),"xxxxxxxxx1,000.0", status
);
1685 expect2(new DecimalFormat(formatStr
, US
, status
),
1686 int32_t(1000000),"xxxxx1,000,000.0", status
);
1687 expect2(new DecimalFormat(formatStr
, US
, status
),
1688 100.37, "xxxxxxxxxx100.37", status
);
1689 expect2(new DecimalFormat(formatStr
, US
, status
),
1690 10456.37, "xxxxxxx10,456.37", status
);
1691 expect2(new DecimalFormat(formatStr
, US
, status
),
1692 1120456.37, "xxxx1,120,456.37", status
);
1693 expect2(new DecimalFormat(formatStr
, US
, status
),
1694 112045600.37, "xx112,045,600.37", status
);
1695 expect2(new DecimalFormat(formatStr
, US
, status
),
1696 10252045600.37,"10,252,045,600.37", status
);
1699 // Test padding between a sign and a number
1700 const char *formatStr2
= "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
1701 expect2(new DecimalFormat(formatStr2
, US
, status
),
1702 int32_t(-10), "(10.0xxxxxxxxxx)", status
);
1703 expect2(new DecimalFormat(formatStr2
, US
, status
),
1704 int32_t(-1000),"(1,000.0xxxxxxx)", status
);
1705 expect2(new DecimalFormat(formatStr2
, US
, status
),
1706 int32_t(-1000000),"(1,000,000.0xxx)", status
);
1707 expect2(new DecimalFormat(formatStr2
, US
, status
),
1708 -100.37, "(100.37xxxxxxxx)", status
);
1709 expect2(new DecimalFormat(formatStr2
, US
, status
),
1710 -10456.37, "(10,456.37xxxxx)", status
);
1711 expect2(new DecimalFormat(formatStr2
, US
, status
),
1712 -1120456.37, "(1,120,456.37xx)", status
);
1713 expect2(new DecimalFormat(formatStr2
, US
, status
),
1714 -112045600.37, "(112,045,600.37)", status
);
1715 expect2(new DecimalFormat(formatStr2
, US
, status
),
1716 -1252045600.37,"(1,252,045,600.37)", status
);
1718 expect2(new DecimalFormat(formatStr2
, US
, status
),
1719 int32_t(10), "10.0xxxxxxxxxxxx", status
);
1720 expect2(new DecimalFormat(formatStr2
, US
, status
),
1721 int32_t(1000),"1,000.0xxxxxxxxx", status
);
1722 expect2(new DecimalFormat(formatStr2
, US
, status
),
1723 int32_t(1000000),"1,000,000.0xxxxx", status
);
1724 expect2(new DecimalFormat(formatStr2
, US
, status
),
1725 100.37, "100.37xxxxxxxxxx", status
);
1726 expect2(new DecimalFormat(formatStr2
, US
, status
),
1727 10456.37, "10,456.37xxxxxxx", status
);
1728 expect2(new DecimalFormat(formatStr2
, US
, status
),
1729 1120456.37, "1,120,456.37xxxx", status
);
1730 expect2(new DecimalFormat(formatStr2
, US
, status
),
1731 112045600.37, "112,045,600.37xx", status
);
1732 expect2(new DecimalFormat(formatStr2
, US
, status
),
1733 10252045600.37,"10,252,045,600.37", status
);
1735 //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
1736 DecimalFormat
fmt("#", US
, status
);
1737 CHECK(status
, "DecimalFormat constructor");
1738 UnicodeString
padString("P");
1739 fmt
.setPadCharacter(padString
);
1740 expectPad(fmt
, "*P##.##", DecimalFormat::kPadBeforePrefix
, 5, padString
);
1741 fmt
.setPadCharacter((UnicodeString
)"^");
1742 expectPad(fmt
, "*^#", DecimalFormat::kPadBeforePrefix
, 1, (UnicodeString
)"^");
1743 //commented untill implementation is complete
1744 /* fmt.setPadCharacter((UnicodeString)"^^^");
1745 expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
1747 padString.append((UChar)0x0061);
1748 padString.append((UChar)0x0302);
1749 fmt.setPadCharacter(padString);
1750 UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
1751 UnicodeString pattern(patternChars);
1752 expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
1758 * Upgrade to alphaWorks
1760 void NumberFormatTest::TestPatterns2(void) {
1761 UErrorCode status
= U_ZERO_ERROR
;
1762 DecimalFormatSymbols
US(Locale::getUS(), status
);
1763 CHECK(status
, "DecimalFormatSymbols constructor");
1765 DecimalFormat
fmt("#", US
, status
);
1766 CHECK(status
, "DecimalFormat constructor");
1768 UChar hat
= 0x005E; /*^*/
1770 expectPad(fmt
, "*^#", DecimalFormat::kPadBeforePrefix
, 1, hat
);
1771 expectPad(fmt
, "$*^#", DecimalFormat::kPadAfterPrefix
, 2, hat
);
1772 expectPad(fmt
, "#*^", DecimalFormat::kPadBeforeSuffix
, 1, hat
);
1773 expectPad(fmt
, "#$*^", DecimalFormat::kPadAfterSuffix
, 2, hat
);
1774 expectPad(fmt
, "$*^$#", ILLEGAL
);
1775 expectPad(fmt
, "#$*^$", ILLEGAL
);
1776 expectPad(fmt
, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix
,
1777 12, (UChar
)0x0078 /*x*/);
1778 expectPad(fmt
, "''#0*x", DecimalFormat::kPadBeforeSuffix
,
1779 3, (UChar
)0x0078 /*x*/);
1780 expectPad(fmt
, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix
,
1781 10, (UChar
)0x0061 /*a*/);
1783 fmt
.applyPattern("AA#,##0.00ZZ", status
);
1784 CHECK(status
, "applyPattern");
1785 fmt
.setPadCharacter(hat
);
1787 fmt
.setFormatWidth(10);
1789 fmt
.setPadPosition(DecimalFormat::kPadBeforePrefix
);
1790 expectPat(fmt
, "*^AA#,##0.00ZZ");
1792 fmt
.setPadPosition(DecimalFormat::kPadBeforeSuffix
);
1793 expectPat(fmt
, "AA#,##0.00*^ZZ");
1795 fmt
.setPadPosition(DecimalFormat::kPadAfterSuffix
);
1796 expectPat(fmt
, "AA#,##0.00ZZ*^");
1799 UnicodeString
exp("AA*^#,##0.00ZZ", "");
1800 fmt
.setFormatWidth(12);
1801 fmt
.setPadPosition(DecimalFormat::kPadAfterPrefix
);
1802 expectPat(fmt
, exp
);
1804 fmt
.setFormatWidth(13);
1806 expectPat(fmt
, "AA*^##,##0.00ZZ");
1808 fmt
.setFormatWidth(14);
1810 expectPat(fmt
, "AA*^###,##0.00ZZ");
1812 fmt
.setFormatWidth(15);
1814 expectPat(fmt
, "AA*^####,##0.00ZZ"); // This is the interesting case
1816 fmt
.setFormatWidth(16);
1817 // 12 34567890123456
1818 expectPat(fmt
, "AA*^#####,##0.00ZZ");
1821 void NumberFormatTest::TestSurrogateSupport(void) {
1822 UErrorCode status
= U_ZERO_ERROR
;
1823 DecimalFormatSymbols
custom(Locale::getUS(), status
);
1824 CHECK(status
, "DecimalFormatSymbols constructor");
1826 custom
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, "decimal");
1827 custom
.setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, "plus");
1828 custom
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, " minus ");
1829 custom
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, "exponent");
1831 UnicodeString
patternStr("*\\U00010000##.##", "");
1832 patternStr
= patternStr
.unescape();
1833 UnicodeString
expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
1834 expStr
= expStr
.unescape();
1835 expect2(new DecimalFormat(patternStr
, custom
, status
),
1836 int32_t(0), expStr
, status
);
1838 status
= U_ZERO_ERROR
;
1839 expect2(new DecimalFormat("*^##.##", custom
, status
),
1840 int32_t(0), "^^^^0", status
);
1841 status
= U_ZERO_ERROR
;
1842 expect2(new DecimalFormat("##.##", custom
, status
),
1843 -1.3, " minus 1decimal3", status
);
1844 status
= U_ZERO_ERROR
;
1845 expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom
, status
),
1846 int32_t(0), "0decimal0exponent0 g-m/s^2", status
);
1847 status
= U_ZERO_ERROR
;
1848 expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom
, status
),
1849 1.0/3, "333decimal333exponent minus 3 g-m/s^2", status
);
1850 status
= U_ZERO_ERROR
;
1851 expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom
, status
),
1852 int32_t(0), "0decimal0 g-m/s^2", status
);
1853 status
= U_ZERO_ERROR
;
1854 expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom
, status
),
1855 1.0/3, "0decimal33333 g-m/s^2", status
);
1857 UnicodeString
zero((UChar32
)0x10000);
1858 UnicodeString
one((UChar32
)0x10001);
1859 UnicodeString
two((UChar32
)0x10002);
1860 UnicodeString
five((UChar32
)0x10005);
1861 custom
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, zero
);
1862 custom
.setSymbol(DecimalFormatSymbols::kOneDigitSymbol
, one
);
1863 custom
.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol
, two
);
1864 custom
.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol
, five
);
1865 expStr
= UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
1866 expStr
= expStr
.unescape();
1867 status
= U_ZERO_ERROR
;
1868 expect2(new DecimalFormat("##0.000", custom
, status
),
1869 1.25, expStr
, status
);
1871 custom
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, (UChar
)0x30);
1872 custom
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "units of money");
1873 custom
.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, "money separator");
1874 patternStr
= UNICODE_STRING_SIMPLE("0.00 \\u00A4' in your bank account'");
1875 patternStr
= patternStr
.unescape();
1876 expStr
= UnicodeString(" minus 20money separator00 units of money in your bank account", "");
1877 status
= U_ZERO_ERROR
;
1878 expect2(new DecimalFormat(patternStr
, custom
, status
),
1879 int32_t(-20), expStr
, status
);
1881 custom
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, "percent");
1882 patternStr
= "'You''ve lost ' -0.00 %' of your money today'";
1883 patternStr
= patternStr
.unescape();
1884 expStr
= UnicodeString(" minus You've lost minus 2000decimal00 percent of your money today", "");
1885 status
= U_ZERO_ERROR
;
1886 expect2(new DecimalFormat(patternStr
, custom
, status
),
1887 int32_t(-20), expStr
, status
);
1890 void NumberFormatTest::TestCurrencyPatterns(void) {
1891 int32_t i
, locCount
;
1892 const Locale
* locs
= NumberFormat::getAvailableLocales(locCount
);
1893 for (i
=0; i
<locCount
; ++i
) {
1894 UErrorCode ec
= U_ZERO_ERROR
;
1895 NumberFormat
* nf
= NumberFormat::createCurrencyInstance(locs
[i
], ec
);
1896 if (U_FAILURE(ec
)) {
1897 errln("FAIL: Can't create NumberFormat(%s) - %s", locs
[i
].getName(), u_errorName(ec
));
1899 // Make sure currency formats do not have a variable number
1900 // of fraction digits
1901 int32_t min
= nf
->getMinimumFractionDigits();
1902 int32_t max
= nf
->getMaximumFractionDigits();
1906 nf
->format(1.125, b
);
1907 errln((UnicodeString
)"FAIL: " + locs
[i
].getName() +
1908 " min fraction digits != max fraction digits; "
1909 "x 1.0 => " + escape(a
) +
1910 "; x 1.125 => " + escape(b
));
1913 // Make sure EURO currency formats have exactly 2 fraction digits
1914 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
1916 if (u_strcmp(EUR
, df
->getCurrency()) == 0) {
1917 if (min
!= 2 || max
!= 2) {
1920 errln((UnicodeString
)"FAIL: " + locs
[i
].getName() +
1921 " is a EURO format but it does not have 2 fraction digits; "
1932 void NumberFormatTest::TestRegCurrency(void) {
1933 #if !UCONFIG_NO_SERVICE
1934 UErrorCode status
= U_ZERO_ERROR
;
1936 ucurr_forLocale("en_US", USD
, 4, &status
);
1938 ucurr_forLocale("ja_JP", YEN
, 4, &status
);
1941 if(U_FAILURE(status
)) {
1942 errcheckln(status
, "Unable to get currency for locale, error %s", u_errorName(status
));
1946 UCurrRegistryKey enkey
= ucurr_register(YEN
, "en_US", &status
);
1948 ucurr_forLocale("en_US", TMP
, 4, &status
);
1949 if (u_strcmp(YEN
, TMP
) != 0) {
1950 errln("FAIL: didn't return YEN registered for en_US");
1953 int32_t fallbackLen
= ucurr_forLocale("en_XX_BAR", TMP
, 4, &status
);
1955 errln("FAIL: tried to fallback en_XX_BAR");
1957 status
= U_ZERO_ERROR
; // reset
1959 if (!ucurr_unregister(enkey
, &status
)) {
1960 errln("FAIL: couldn't unregister enkey");
1963 ucurr_forLocale("en_US", TMP
, 4, &status
);
1964 if (u_strcmp(USD
, TMP
) != 0) {
1965 errln("FAIL: didn't return USD for en_US after unregister of en_US");
1967 status
= U_ZERO_ERROR
; // reset
1969 ucurr_forLocale("en_US_BLAH", TMP
, 4, &status
);
1970 if (u_strcmp(USD
, TMP
) != 0) {
1971 errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
1973 status
= U_ZERO_ERROR
; // reset
1977 void NumberFormatTest::TestCurrencyNames(void) {
1978 // Do a basic check of getName()
1979 // USD { "US$", "US Dollar" } // 04/04/1792-
1980 UErrorCode ec
= U_ZERO_ERROR
;
1981 static const UChar USD
[] = {0x55, 0x53, 0x44, 0}; /*USD*/
1982 static const UChar USX
[] = {0x55, 0x53, 0x58, 0}; /*USX*/
1983 static const UChar CAD
[] = {0x43, 0x41, 0x44, 0}; /*CAD*/
1984 static const UChar ITL
[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/
1985 UBool isChoiceFormat
;
1987 const UBool possibleDataError
= TRUE
;
1988 // Warning: HARD-CODED LOCALE DATA in this test. If it fails, CHECK
1989 // THE LOCALE DATA before diving into the code.
1990 assertEquals("USD.getName(SYMBOL_NAME, en)",
1992 UnicodeString(ucurr_getName(USD
, "en",
1994 &isChoiceFormat
, &len
, &ec
)),
1996 assertEquals("USD.getName(NARROW_SYMBOL_NAME, en)",
1998 UnicodeString(ucurr_getName(USD
, "en",
1999 UCURR_NARROW_SYMBOL_NAME
,
2000 &isChoiceFormat
, &len
, &ec
)),
2002 assertEquals("USD.getName(LONG_NAME, en)",
2003 UnicodeString("US Dollar"),
2004 UnicodeString(ucurr_getName(USD
, "en",
2006 &isChoiceFormat
, &len
, &ec
)),
2008 assertEquals("CAD.getName(SYMBOL_NAME, en)",
2009 UnicodeString("CA$"),
2010 UnicodeString(ucurr_getName(CAD
, "en",
2012 &isChoiceFormat
, &len
, &ec
)),
2014 assertEquals("CAD.getName(NARROW_SYMBOL_NAME, en)",
2016 UnicodeString(ucurr_getName(CAD
, "en",
2017 UCURR_NARROW_SYMBOL_NAME
,
2018 &isChoiceFormat
, &len
, &ec
)),
2020 assertEquals("CAD.getName(SYMBOL_NAME, en_CA)",
2022 UnicodeString(ucurr_getName(CAD
, "en_CA",
2024 &isChoiceFormat
, &len
, &ec
)),
2026 assertEquals("USD.getName(SYMBOL_NAME, en_CA)",
2027 UnicodeString("US$"),
2028 UnicodeString(ucurr_getName(USD
, "en_CA",
2030 &isChoiceFormat
, &len
, &ec
)),
2032 assertEquals("USD.getName(NARROW_SYMBOL_NAME, en_CA)",
2034 UnicodeString(ucurr_getName(USD
, "en_CA",
2035 UCURR_NARROW_SYMBOL_NAME
,
2036 &isChoiceFormat
, &len
, &ec
)),
2038 assertEquals("USD.getName(SYMBOL_NAME) in en_NZ",
2039 UnicodeString("US$"),
2040 UnicodeString(ucurr_getName(USD
, "en_NZ",
2042 &isChoiceFormat
, &len
, &ec
)),
2044 assertEquals("CAD.getName(SYMBOL_NAME)",
2045 UnicodeString("CA$"),
2046 UnicodeString(ucurr_getName(CAD
, "en_NZ",
2048 &isChoiceFormat
, &len
, &ec
)),
2050 assertEquals("USX.getName(SYMBOL_NAME)",
2051 UnicodeString("USX"),
2052 UnicodeString(ucurr_getName(USX
, "en_US",
2054 &isChoiceFormat
, &len
, &ec
)),
2056 assertEquals("USX.getName(NARROW_SYMBOL_NAME)",
2057 UnicodeString("USX"),
2058 UnicodeString(ucurr_getName(USX
, "en_US",
2059 UCURR_NARROW_SYMBOL_NAME
,
2060 &isChoiceFormat
, &len
, &ec
)),
2062 assertEquals("USX.getName(LONG_NAME)",
2063 UnicodeString("USX"),
2064 UnicodeString(ucurr_getName(USX
, "en_US",
2066 &isChoiceFormat
, &len
, &ec
)),
2068 assertSuccess("ucurr_getName", ec
);
2072 // Test that a default or fallback warning is being returned. JB 4239.
2073 ucurr_getName(CAD
, "es_ES", UCURR_LONG_NAME
, &isChoiceFormat
,
2075 assertTrue("ucurr_getName (es_ES fallback)",
2076 U_USING_FALLBACK_WARNING
== ec
, TRUE
, possibleDataError
);
2078 ucurr_getName(CAD
, "zh_TW", UCURR_LONG_NAME
, &isChoiceFormat
,
2080 assertTrue("ucurr_getName (zh_TW fallback)",
2081 U_USING_FALLBACK_WARNING
== ec
, TRUE
, possibleDataError
);
2083 ucurr_getName(CAD
, "en_US", UCURR_LONG_NAME
, &isChoiceFormat
,
2085 assertTrue("ucurr_getName (en_US default)",
2086 U_USING_DEFAULT_WARNING
== ec
|| U_USING_FALLBACK_WARNING
== ec
, TRUE
);
2088 ucurr_getName(CAD
, "ti", UCURR_LONG_NAME
, &isChoiceFormat
,
2090 assertTrue("ucurr_getName (ti default)",
2091 U_USING_DEFAULT_WARNING
== ec
, TRUE
);
2093 // Test that a default warning is being returned when falling back to root. JB 4536.
2094 ucurr_getName(ITL
, "cy", UCURR_LONG_NAME
, &isChoiceFormat
,
2096 assertTrue("ucurr_getName (cy default to root)",
2097 U_USING_DEFAULT_WARNING
== ec
, TRUE
);
2099 // TODO add more tests later
2102 void NumberFormatTest::Test20484_NarrowSymbolFallback(){
2103 IcuTestErrorCode
status(*this, "Test20484_NarrowSymbolFallback");
2107 const char16_t* isoCode
;
2108 const char16_t* expectedShort
;
2109 const char16_t* expectedNarrow
;
2110 UErrorCode expectedNarrowError
;
2112 {"en-US", u
"CAD", u
"CA$", u
"$", U_USING_DEFAULT_WARNING
}, // narrow: fallback to root
2113 {"en-US", u
"CDF", u
"CDF", u
"CDF", U_USING_FALLBACK_WARNING
}, // narrow: fallback to short
2114 {"sw-CD", u
"CDF", u
"FC", u
"FC", U_USING_FALLBACK_WARNING
}, // narrow: fallback to short
2115 {"en-US", u
"GEL", u
"GEL", u
"₾", U_USING_DEFAULT_WARNING
}, // narrow: fallback to root
2116 {"ka-GE", u
"GEL", u
"₾", u
"₾", U_USING_FALLBACK_WARNING
}, // narrow: fallback to ka
2117 {"ka", u
"GEL", u
"₾", u
"₾", U_ZERO_ERROR
}, // no fallback on narrow
2119 for (const auto& cas
: cases
) {
2120 status
.setScope(cas
.isoCode
);
2121 UBool choiceFormatIgnored
;
2122 int32_t lengthIgnored
;
2123 const UChar
* actualShort
= ucurr_getName(
2127 &choiceFormatIgnored
,
2130 status
.errIfFailureAndReset();
2131 const UChar
* actualNarrow
= ucurr_getName(
2134 UCURR_NARROW_SYMBOL_NAME
,
2135 &choiceFormatIgnored
,
2138 status
.expectErrorAndReset(cas
.expectedNarrowError
);
2139 assertEquals(UnicodeString("Short symbol: ") + cas
.locale
+ u
": " + cas
.isoCode
,
2140 cas
.expectedShort
, actualShort
);
2141 assertEquals(UnicodeString("Narrow symbol: ") + cas
.locale
+ ": " + cas
.isoCode
,
2142 cas
.expectedNarrow
, actualNarrow
);
2146 void NumberFormatTest::TestCurrencyUnit(void){
2147 UErrorCode ec
= U_ZERO_ERROR
;
2148 static const UChar USD
[] = u
"USD";
2149 static const char USD8
[] = "USD";
2150 static const UChar BAD
[] = u
"???";
2151 static const UChar BAD2
[] = u
"??A";
2152 static const UChar XXX
[] = u
"XXX";
2153 static const char XXX8
[] = "XXX";
2154 static const UChar INV
[] = u
"{$%";
2155 static const char INV8
[] = "{$%";
2156 static const UChar ZZZ
[] = u
"zz";
2157 static const char ZZZ8
[] = "zz";
2159 UChar
* EUR
= (UChar
*) malloc(6);
2163 char* EUR8
= (char*) malloc(3);
2168 CurrencyUnit
cu(USD
, ec
);
2169 assertSuccess("CurrencyUnit", ec
);
2171 assertEquals("getISOCurrency()", USD
, cu
.getISOCurrency());
2172 assertEquals("getSubtype()", USD8
, cu
.getSubtype());
2174 CurrencyUnit
inv(INV
, ec
);
2175 assertEquals("non-invariant", U_INVARIANT_CONVERSION_ERROR
, ec
);
2176 assertEquals("non-invariant", XXX
, inv
.getISOCurrency());
2179 CurrencyUnit
zzz(ZZZ
, ec
);
2180 assertEquals("too short", U_ILLEGAL_ARGUMENT_ERROR
, ec
);
2181 assertEquals("too short", XXX
, zzz
.getISOCurrency());
2184 CurrencyUnit
eur(EUR
, ec
);
2185 assertEquals("non-nul-terminated", u
"EUR", eur
.getISOCurrency());
2186 assertEquals("non-nul-terminated", "EUR", eur
.getSubtype());
2188 // Test StringPiece constructor
2189 CurrencyUnit
cu8(USD8
, ec
);
2190 assertEquals("StringPiece constructor", USD
, cu8
.getISOCurrency());
2192 CurrencyUnit
inv8(INV8
, ec
);
2193 assertEquals("non-invariant 8", U_INVARIANT_CONVERSION_ERROR
, ec
);
2194 assertEquals("non-invariant 8", XXX
, inv8
.getISOCurrency());
2197 CurrencyUnit
zzz8(ZZZ8
, ec
);
2198 assertEquals("too short 8", U_ILLEGAL_ARGUMENT_ERROR
, ec
);
2199 assertEquals("too short 8", XXX
, zzz8
.getISOCurrency());
2202 CurrencyUnit
zzz8b({ZZZ8
, 3}, ec
);
2203 assertEquals("too short 8b", U_ILLEGAL_ARGUMENT_ERROR
, ec
);
2204 assertEquals("too short 8b", XXX
, zzz8b
.getISOCurrency());
2207 CurrencyUnit
eur8({EUR8
, 3}, ec
);
2208 assertEquals("non-nul-terminated 8", u
"EUR", eur8
.getISOCurrency());
2209 assertEquals("non-nul-terminated 8", "EUR", eur8
.getSubtype());
2211 CurrencyUnit
cu2(cu
);
2213 errln("CurrencyUnit copy constructed object should be same");
2216 CurrencyUnit
* cu3
= (CurrencyUnit
*)cu
.clone();
2218 errln("CurrencyUnit cloned object should be same");
2220 CurrencyUnit
bad(BAD
, ec
);
2221 assertSuccess("CurrencyUnit", ec
);
2222 if (cu
.getIndex() == bad
.getIndex()) {
2223 errln("Indexes of different currencies should differ.");
2225 CurrencyUnit
bad2(BAD2
, ec
);
2226 assertSuccess("CurrencyUnit", ec
);
2227 if (bad2
.getIndex() != bad
.getIndex()) {
2228 errln("Indexes of unrecognized currencies should be the same.");
2231 errln("Different unrecognized currencies should not be equal.");
2235 errln("Currency unit assignment should be the same.");
2239 // Test default constructor
2241 assertEquals("Default currency", XXX
, def
.getISOCurrency());
2242 assertEquals("Default currency as subtype", XXX8
, def
.getSubtype());
2245 MeasureUnit sliced1
= cu
;
2246 MeasureUnit sliced2
= cu
;
2247 assertEquals("Subtype after slicing 1", USD8
, sliced1
.getSubtype());
2248 assertEquals("Subtype after slicing 2", USD8
, sliced2
.getSubtype());
2249 CurrencyUnit
restored1(sliced1
, ec
);
2250 CurrencyUnit
restored2(sliced2
, ec
);
2251 assertSuccess("Restoring from MeasureUnit", ec
);
2252 assertEquals("Subtype after restoring 1", USD8
, restored1
.getSubtype());
2253 assertEquals("Subtype after restoring 2", USD8
, restored2
.getSubtype());
2254 assertEquals("ISO Code after restoring 1", USD
, restored1
.getISOCurrency());
2255 assertEquals("ISO Code after restoring 2", USD
, restored2
.getISOCurrency());
2257 // Test copy constructor failure
2258 LocalPointer
<MeasureUnit
> meter(MeasureUnit::createMeter(ec
));
2259 assertSuccess("Creating meter", ec
);
2260 CurrencyUnit
failure(*meter
, ec
);
2261 assertEquals("Copying from meter should fail", ec
, U_ILLEGAL_ARGUMENT_ERROR
);
2262 assertEquals("Copying should not give uninitialized ISO code", u
"", failure
.getISOCurrency());
2268 void NumberFormatTest::TestCurrencyAmount(void){
2269 UErrorCode ec
= U_ZERO_ERROR
;
2270 static const UChar USD
[] = {85, 83, 68, 0}; /*USD*/
2271 CurrencyAmount
ca(9, USD
, ec
);
2272 assertSuccess("CurrencyAmount", ec
);
2274 CurrencyAmount
ca2(ca
);
2276 errln("CurrencyAmount copy constructed object should be same");
2281 errln("CurrencyAmount assigned object should be same");
2284 CurrencyAmount
*ca3
= (CurrencyAmount
*)ca
.clone();
2286 errln("CurrencyAmount cloned object should be same");
2291 void NumberFormatTest::TestSymbolsWithBadLocale(void) {
2293 static const char *badLocales
[] = {
2294 // length < ULOC_FULLNAME_CAPACITY
2295 "x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME",
2297 // length > ULOC_FULLNAME_CAPACITY
2298 "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"
2299 }; // expect U_USING_DEFAULT_WARNING for both
2302 for (i
= 0; i
< UPRV_LENGTHOF(badLocales
); i
++) {
2303 const char *localeName
= badLocales
[i
];
2304 Locale
locBad(localeName
);
2305 assertTrue(WHERE
, !locBad
.isBogus());
2306 UErrorCode status
= U_ZERO_ERROR
;
2307 UnicodeString
intlCurrencySymbol((UChar
)0xa4);
2309 intlCurrencySymbol
.append((UChar
)0xa4);
2311 logln("Current locale is %s", Locale::getDefault().getName());
2312 Locale::setDefault(locBad
, status
);
2313 logln("Current locale is %s", Locale::getDefault().getName());
2314 DecimalFormatSymbols
mySymbols(status
);
2315 if (status
!= U_USING_DEFAULT_WARNING
) {
2316 errln("DecimalFormatSymbols should return U_USING_DEFAULT_WARNING.");
2318 if (strcmp(mySymbols
.getLocale().getName(), locBad
.getName()) != 0) {
2319 errln("DecimalFormatSymbols does not have the right locale.", locBad
.getName());
2321 int symbolEnum
= (int)DecimalFormatSymbols::kDecimalSeparatorSymbol
;
2322 for (; symbolEnum
< (int)DecimalFormatSymbols::kFormatSymbolCount
; symbolEnum
++) {
2323 UnicodeString symbolString
= mySymbols
.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbolEnum
);
2324 logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum
+ UnicodeString("] = ") + prettify(symbolString
));
2325 if (symbolString
.length() == 0
2326 && symbolEnum
!= (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
2327 && symbolEnum
!= (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
)
2329 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum
);
2333 status
= U_ZERO_ERROR
;
2334 Locale::setDefault(locDefault
, status
);
2335 logln("Current locale is %s", Locale::getDefault().getName());
2340 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
2341 * behave the same, except for memory ownership semantics. (No
2342 * version of this test on Java, since Java has only one method.)
2344 void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
2345 UErrorCode ec
= U_ZERO_ERROR
;
2346 DecimalFormatSymbols
*sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
2347 if (U_FAILURE(ec
)) {
2348 errcheckln(ec
, "Fail: DecimalFormatSymbols constructor - %s", u_errorName(ec
));
2352 UnicodeString
pat(" #,##0.00");
2353 pat
.insert(0, (UChar
)0x00A4);
2354 DecimalFormat
fmt(pat
, sym
, ec
);
2355 if (U_FAILURE(ec
)) {
2356 errln("Fail: DecimalFormat constructor");
2361 fmt
.format(2350.75, str
);
2362 if (str
== "$ 2,350.75") {
2365 dataerrln("Fail: " + str
+ ", expected $ 2,350.75");
2368 sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
2369 if (U_FAILURE(ec
)) {
2370 errln("Fail: DecimalFormatSymbols constructor");
2374 sym
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "Q");
2375 fmt
.adoptDecimalFormatSymbols(sym
);
2378 fmt
.format(2350.75, str
);
2379 if (str
== "Q 2,350.75") {
2382 dataerrln("Fail: adoptDecimalFormatSymbols -> " + str
+ ", expected Q 2,350.75");
2385 sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
2386 if (U_FAILURE(ec
)) {
2387 errln("Fail: DecimalFormatSymbols constructor");
2391 DecimalFormat
fmt2(pat
, sym
, ec
);
2392 if (U_FAILURE(ec
)) {
2393 errln("Fail: DecimalFormat constructor");
2397 DecimalFormatSymbols
sym2(Locale::getUS(), ec
);
2398 if (U_FAILURE(ec
)) {
2399 errln("Fail: DecimalFormatSymbols constructor");
2402 sym2
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "Q");
2403 fmt2
.setDecimalFormatSymbols(sym2
);
2406 fmt2
.format(2350.75, str
);
2407 if (str
== "Q 2,350.75") {
2410 dataerrln("Fail: setDecimalFormatSymbols -> " + str
+ ", expected Q 2,350.75");
2414 void NumberFormatTest::TestPerMill() {
2415 UErrorCode ec
= U_ZERO_ERROR
;
2417 DecimalFormat
fmt(ctou("###.###\\u2030"), ec
);
2418 if (!assertSuccess("DecimalFormat ct", ec
)) return;
2419 assertEquals("0.4857 x ###.###\\u2030",
2420 ctou("485.7\\u2030"), fmt
.format(0.4857, str
), true);
2422 DecimalFormatSymbols
sym(Locale::getUS(), ec
);
2423 if (!assertSuccess("", ec
, true, __FILE__
, __LINE__
)) {
2426 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, ctou("m"));
2427 DecimalFormat
fmt2("", sym
, ec
);
2428 if (!assertSuccess("", ec
, true, __FILE__
, __LINE__
)) {
2431 fmt2
.applyLocalizedPattern("###.###m", ec
);
2432 if (!assertSuccess("setup", ec
)) return;
2434 assertEquals("0.4857 x ###.###m",
2435 "485.7m", fmt2
.format(0.4857, str
));
2439 * Generic test for patterns that should be legal/illegal.
2441 void NumberFormatTest::TestIllegalPatterns() {
2443 // Prefix with "-:" for illegal patterns
2444 // Prefix with "+:" for legal patterns
2445 const char* DATA
[] = {
2446 // Unquoted special characters in the suffix are illegal
2451 for (int32_t i
=0; DATA
[i
]; ++i
) {
2452 const char* pat
=DATA
[i
];
2453 UBool valid
= (*pat
) == '+';
2455 UErrorCode ec
= U_ZERO_ERROR
;
2456 DecimalFormat
fmt(pat
, ec
); // locale doesn't matter here
2457 if (U_SUCCESS(ec
) == valid
) {
2458 logln("Ok: pattern \"%s\": %s",
2459 pat
, u_errorName(ec
));
2461 errcheckln(ec
, "FAIL: pattern \"%s\" should have %s; got %s",
2462 pat
, (valid
?"succeeded":"failed"),
2468 //----------------------------------------------------------------------
2470 static const char* KEYWORDS
[] = {
2471 /*0*/ "ref=", // <reference pattern to parse numbers>
2472 /*1*/ "loc=", // <locale for formats>
2473 /*2*/ "f:", // <pattern or '-'> <number> <exp. string>
2474 /*3*/ "fp:", // <pattern or '-'> <number> <exp. string> <exp. number>
2475 /*4*/ "rt:", // <pattern or '-'> <(exp.) number> <(exp.) string>
2476 /*5*/ "p:", // <pattern or '-'> <string> <exp. number>
2477 /*6*/ "perr:", // <pattern or '-'> <invalid string>
2478 /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
2479 /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2484 * Return an integer representing the next token from this
2485 * iterator. The integer will be an index into the given list, or
2486 * -1 if there are no more tokens, or -2 if the token is not on
2489 static int32_t keywordIndex(const UnicodeString
& tok
) {
2490 for (int32_t i
=0; KEYWORDS
[i
]!=0; ++i
) {
2491 if (tok
==KEYWORDS
[i
]) {
2499 * Parse a CurrencyAmount using the given NumberFormat, with
2500 * the 'delim' character separating the number and the currency.
2502 static void parseCurrencyAmount(const UnicodeString
& str
,
2503 const NumberFormat
& fmt
,
2505 Formattable
& result
,
2507 UnicodeString num
, cur
;
2508 int32_t i
= str
.indexOf(delim
);
2509 str
.extractBetween(0, i
, num
);
2510 str
.extractBetween(i
+1, INT32_MAX
, cur
);
2512 fmt
.parse(num
, n
, ec
);
2513 result
.adoptObject(new CurrencyAmount(n
, cur
.getTerminatedBuffer(), ec
));
2516 void NumberFormatTest::TestCases() {
2517 UErrorCode ec
= U_ZERO_ERROR
;
2518 TextFile
reader("NumberFormatTestCases.txt", "UTF8", ec
);
2519 if (U_FAILURE(ec
)) {
2520 dataerrln("Couldn't open NumberFormatTestCases.txt");
2523 TokenIterator
tokens(&reader
);
2525 Locale
loc("en", "US", "");
2526 DecimalFormat
*ref
= 0, *fmt
= 0;
2527 MeasureFormat
*mfmt
= 0;
2528 UnicodeString pat
, tok
, mloc
, str
, out
, where
, currAmt
;
2533 if (!tokens
.next(tok
, ec
)) {
2536 where
= UnicodeString("(") + tokens
.getLineNumber() + ") ";
2537 int32_t cmd
= keywordIndex(tok
);
2540 // ref= <reference pattern>
2541 if (!tokens
.next(tok
, ec
)) goto error
;
2543 ref
= new DecimalFormat(tok
,
2544 new DecimalFormatSymbols(Locale::getUS(), ec
), ec
);
2545 if (U_FAILURE(ec
)) {
2546 dataerrln("Error constructing DecimalFormat");
2552 if (!tokens
.next(tok
, ec
)) goto error
;
2553 loc
= Locale::createFromName(CharString().appendInvariantChars(tok
, ec
).data());
2559 if (!tokens
.next(tok
, ec
)) goto error
;
2563 fmt
= new DecimalFormat(pat
, new DecimalFormatSymbols(loc
, ec
), ec
);
2564 if (U_FAILURE(ec
)) {
2565 errln("FAIL: " + where
+ "Pattern \"" + pat
+ "\": " + u_errorName(ec
));
2567 if (!tokens
.next(tok
, ec
)) goto error
;
2568 if (!tokens
.next(tok
, ec
)) goto error
;
2570 if (!tokens
.next(tok
, ec
)) goto error
;
2575 if (cmd
== 2 || cmd
== 3 || cmd
== 4) {
2576 // f: <pattern or '-'> <number> <exp. string>
2577 // fp: <pattern or '-'> <number> <exp. string> <exp. number>
2578 // rt: <pattern or '-'> <number> <string>
2580 if (!tokens
.next(num
, ec
)) goto error
;
2581 if (!tokens
.next(str
, ec
)) goto error
;
2582 ref
->parse(num
, n
, ec
);
2583 assertSuccess("parse", ec
);
2584 assertEquals(where
+ "\"" + pat
+ "\".format(" + num
+ ")",
2585 str
, fmt
->format(n
, out
.remove(), ec
));
2586 assertSuccess("format", ec
);
2587 if (cmd
== 3) { // fp:
2588 if (!tokens
.next(num
, ec
)) goto error
;
2589 ref
->parse(num
, n
, ec
);
2590 assertSuccess("parse", ec
);
2592 if (cmd
!= 2) { // != f:
2594 fmt
->parse(str
, m
, ec
);
2595 assertSuccess("parse", ec
);
2596 assertEquals(where
+ "\"" + pat
+ "\".parse(\"" + str
+ "\")",
2600 // p: <pattern or '-'> <string to parse> <exp. number>
2602 UnicodeString expstr
;
2603 if (!tokens
.next(str
, ec
)) goto error
;
2604 if (!tokens
.next(expstr
, ec
)) goto error
;
2606 ref
->parse(expstr
, exp
, ec
);
2607 assertSuccess("parse", ec
);
2608 fmt
->parse(str
, n
, ec
);
2609 assertSuccess("parse", ec
);
2610 assertEquals(where
+ "\"" + pat
+ "\".parse(\"" + str
+ "\")",
2615 if (!tokens
.next(tok
, ec
)) goto error
;
2619 mfmt
= MeasureFormat::createCurrencyFormat(
2620 Locale::createFromName(
2621 CharString().appendInvariantChars(mloc
, ec
).data()), ec
);
2622 if (U_FAILURE(ec
)) {
2623 errln("FAIL: " + where
+ "Loc \"" + mloc
+ "\": " + u_errorName(ec
));
2625 if (!tokens
.next(tok
, ec
)) goto error
;
2626 if (!tokens
.next(tok
, ec
)) goto error
;
2627 if (!tokens
.next(tok
, ec
)) goto error
;
2630 } else if (mfmt
== NULL
) {
2631 errln("FAIL: " + where
+ "Loc \"" + mloc
+ "\": skip case using previous locale, no valid MeasureFormat");
2632 if (!tokens
.next(tok
, ec
)) goto error
;
2633 if (!tokens
.next(tok
, ec
)) goto error
;
2634 if (!tokens
.next(tok
, ec
)) goto error
;
2637 // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
2638 if (!tokens
.next(currAmt
, ec
)) goto error
;
2639 if (!tokens
.next(str
, ec
)) goto error
;
2640 parseCurrencyAmount(currAmt
, *ref
, (UChar
)0x2F/*'/'*/, n
, ec
);
2641 if (assertSuccess("parseCurrencyAmount", ec
)) {
2642 assertEquals(where
+ "getCurrencyFormat(" + mloc
+ ").format(" + currAmt
+ ")",
2643 str
, mfmt
->format(n
, out
.remove(), ec
));
2644 assertSuccess("format", ec
);
2646 if (!tokens
.next(currAmt
, ec
)) goto error
;
2647 parseCurrencyAmount(currAmt
, *ref
, (UChar
)0x2F/*'/'*/, n
, ec
);
2648 if (assertSuccess("parseCurrencyAmount", ec
)) {
2651 mfmt
->parseObject(str
, m
, ec
);
2652 if (assertSuccess("parseCurrency", ec
)) {
2653 assertEquals(where
+ "getCurrencyFormat(" + mloc
+ ").parse(\"" + str
+ "\")",
2656 errln("FAIL: source " + str
);
2661 // perr: <pattern or '-'> <invalid string>
2662 errln("FAIL: Under construction");
2665 // pat: <pattern> <exp. toPattern, or '-' or 'err'>
2666 UnicodeString testpat
;
2667 UnicodeString exppat
;
2668 if (!tokens
.next(testpat
, ec
)) goto error
;
2669 if (!tokens
.next(exppat
, ec
)) goto error
;
2670 UBool err
= exppat
== "err";
2671 UBool existingPat
= FALSE
;
2672 if (testpat
== "-") {
2674 errln("FAIL: " + where
+ "Invalid command \"pat: - err\"");
2680 if (exppat
== "-") exppat
= testpat
;
2681 DecimalFormat
* f
= 0;
2682 UErrorCode ec2
= U_ZERO_ERROR
;
2686 f
= new DecimalFormat(testpat
, ec2
);
2688 if (U_SUCCESS(ec2
)) {
2690 errln("FAIL: " + where
+ "Invalid pattern \"" + testpat
+
2694 assertEquals(where
+ "\"" + testpat
+ "\".toPattern()",
2695 exppat
, f
->toPattern(pat2
));
2699 logln("Ok: " + where
+ "Invalid pattern \"" + testpat
+
2700 "\" failed: " + u_errorName(ec2
));
2702 errln("FAIL: " + where
+ "Valid pattern \"" + testpat
+
2703 "\" failed: " + u_errorName(ec2
));
2706 if (!existingPat
) delete f
;
2709 errln("FAIL: " + where
+ "Unknown command \"" + tok
+ "\"");
2716 if (U_SUCCESS(ec
)) {
2717 errln("FAIL: Unexpected EOF");
2719 errcheckln(ec
, "FAIL: " + where
+ "Unexpected " + u_errorName(ec
));
2729 //----------------------------------------------------------------------
2731 //----------------------------------------------------------------------
2733 UBool
NumberFormatTest::equalValue(const Formattable
& a
, const Formattable
& b
) {
2734 if (a
.getType() == b
.getType()) {
2738 if (a
.getType() == Formattable::kLong
) {
2739 if (b
.getType() == Formattable::kInt64
) {
2740 return a
.getLong() == b
.getLong();
2741 } else if (b
.getType() == Formattable::kDouble
) {
2742 return (double) a
.getLong() == b
.getDouble(); // TODO check use of double instead of long
2744 } else if (a
.getType() == Formattable::kDouble
) {
2745 if (b
.getType() == Formattable::kLong
) {
2746 return a
.getDouble() == (double) b
.getLong();
2747 } else if (b
.getType() == Formattable::kInt64
) {
2748 return a
.getDouble() == (double)b
.getInt64();
2750 } else if (a
.getType() == Formattable::kInt64
) {
2751 if (b
.getType() == Formattable::kLong
) {
2752 return a
.getInt64() == (int64_t)b
.getLong();
2753 } else if (b
.getType() == Formattable::kDouble
) {
2754 return a
.getInt64() == (int64_t)b
.getDouble();
2760 void NumberFormatTest::expect3(NumberFormat
& fmt
, const Formattable
& n
, const UnicodeString
& str
) {
2761 // Don't round-trip format test, since we explicitly do it
2762 expect_rbnf(fmt
, n
, str
, FALSE
);
2763 expect_rbnf(fmt
, str
, n
);
2766 void NumberFormatTest::expect2(NumberFormat
& fmt
, const Formattable
& n
, const UnicodeString
& str
) {
2767 // Don't round-trip format test, since we explicitly do it
2768 expect(fmt
, n
, str
, FALSE
);
2769 expect(fmt
, str
, n
);
2772 void NumberFormatTest::expect2(NumberFormat
* fmt
, const Formattable
& n
,
2773 const UnicodeString
& exp
,
2774 UErrorCode status
) {
2775 if (fmt
== NULL
|| U_FAILURE(status
)) {
2776 dataerrln("FAIL: NumberFormat constructor");
2778 expect2(*fmt
, n
, exp
);
2783 void NumberFormatTest::expect(NumberFormat
& fmt
, const UnicodeString
& str
, const Formattable
& n
) {
2784 UErrorCode status
= U_ZERO_ERROR
;
2786 fmt
.parse(str
, num
, status
);
2787 if (U_FAILURE(status
)) {
2788 dataerrln(UnicodeString("FAIL: Parse failed for \"") + str
+ "\" - " + u_errorName(status
));
2792 ((DecimalFormat
*) &fmt
)->toPattern(pat
);
2793 if (equalValue(num
, n
)) {
2794 logln(UnicodeString("Ok \"") + str
+ "\" x " +
2798 dataerrln(UnicodeString("FAIL \"") + str
+ "\" x " +
2800 toString(num
) + ", expected " + toString(n
));
2804 void NumberFormatTest::expect_rbnf(NumberFormat
& fmt
, const UnicodeString
& str
, const Formattable
& n
) {
2805 UErrorCode status
= U_ZERO_ERROR
;
2807 fmt
.parse(str
, num
, status
);
2808 if (U_FAILURE(status
)) {
2809 errln(UnicodeString("FAIL: Parse failed for \"") + str
+ "\"");
2812 if (equalValue(num
, n
)) {
2813 logln(UnicodeString("Ok \"") + str
+ " = " +
2816 errln(UnicodeString("FAIL \"") + str
+ " = " +
2817 toString(num
) + ", expected " + toString(n
));
2821 void NumberFormatTest::expect_rbnf(NumberFormat
& fmt
, const Formattable
& n
,
2822 const UnicodeString
& exp
, UBool rt
) {
2825 UErrorCode status
= U_ZERO_ERROR
;
2826 fmt
.format(n
, saw
, pos
, status
);
2827 CHECK(status
, "NumberFormat::format");
2829 logln(UnicodeString("Ok ") + toString(n
) +
2831 escape(saw
) + "\"");
2832 // We should be able to round-trip the formatted string =>
2833 // number => string (but not the other way around: number
2834 // => string => number2, might have number2 != number):
2837 fmt
.parse(exp
, n2
, status
);
2838 if (U_FAILURE(status
)) {
2839 errln(UnicodeString("FAIL: Parse failed for \"") + exp
+ "\"");
2843 fmt
.format(n2
, saw2
, pos
, status
);
2844 CHECK(status
, "NumberFormat::format");
2846 errln((UnicodeString
)"FAIL \"" + exp
+ "\" => " + toString(n2
) +
2847 " => \"" + saw2
+ "\"");
2851 errln(UnicodeString("FAIL ") + toString(n
) +
2853 escape(saw
) + "\", expected \"" + exp
+ "\"");
2857 void NumberFormatTest::expect(NumberFormat
& fmt
, const Formattable
& n
,
2858 const UnicodeString
& exp
, UBool rt
) {
2861 UErrorCode status
= U_ZERO_ERROR
;
2862 fmt
.format(n
, saw
, pos
, status
);
2863 CHECK(status
, "NumberFormat::format");
2865 ((DecimalFormat
*) &fmt
)->toPattern(pat
);
2867 logln(UnicodeString("Ok ") + toString(n
) + " x " +
2868 escape(pat
) + " = \"" +
2869 escape(saw
) + "\"");
2870 // We should be able to round-trip the formatted string =>
2871 // number => string (but not the other way around: number
2872 // => string => number2, might have number2 != number):
2875 fmt
.parse(exp
, n2
, status
);
2876 if (U_FAILURE(status
)) {
2877 errln(UnicodeString("FAIL: Parse failed for \"") + exp
+ "\" - " + u_errorName(status
));
2881 fmt
.format(n2
, saw2
, pos
, status
);
2882 CHECK(status
, "NumberFormat::format");
2884 errln((UnicodeString
)"FAIL \"" + exp
+ "\" => " + toString(n2
) +
2885 " => \"" + saw2
+ "\"");
2889 dataerrln(UnicodeString("FAIL ") + toString(n
) + " x " +
2890 escape(pat
) + " = \"" +
2891 escape(saw
) + "\", expected \"" + exp
+ "\"");
2895 void NumberFormatTest::expect(NumberFormat
* fmt
, const Formattable
& n
,
2896 const UnicodeString
& exp
, UBool rt
,
2897 UErrorCode status
) {
2898 if (fmt
== NULL
|| U_FAILURE(status
)) {
2899 dataerrln("FAIL: NumberFormat constructor");
2901 expect(*fmt
, n
, exp
, rt
);
2906 void NumberFormatTest::expectCurrency(NumberFormat
& nf
, const Locale
& locale
,
2907 double value
, const UnicodeString
& string
) {
2908 UErrorCode ec
= U_ZERO_ERROR
;
2909 DecimalFormat
& fmt
= * (DecimalFormat
*) &nf
;
2910 const UChar DEFAULT_CURR
[] = {45/*-*/,0};
2912 u_strcpy(curr
, DEFAULT_CURR
);
2913 if (*locale
.getLanguage() != 0) {
2914 ucurr_forLocale(locale
.getName(), curr
, 4, &ec
);
2915 assertSuccess("ucurr_forLocale", ec
);
2916 fmt
.setCurrency(curr
, ec
);
2917 assertSuccess("DecimalFormat::setCurrency", ec
);
2918 fmt
.setCurrency(curr
); //Deprecated variant, for coverage only
2921 fmt
.format(value
, s
);
2922 s
.findAndReplace((UChar32
)0x00A0, (UChar32
)0x0020);
2924 // Default display of the number yields "1234.5599999999999"
2925 // instead of "1234.56". Use a formatter to fix this.
2927 NumberFormat::createInstance(Locale::getUS(), ec
);
2929 if (U_FAILURE(ec
)) {
2930 // Oops; bad formatter. Use default op+= display.
2931 v
= (UnicodeString
)"" + value
;
2933 f
->setMaximumFractionDigits(4);
2934 f
->setGroupingUsed(FALSE
);
2935 f
->format(value
, v
);
2940 logln((UnicodeString
)"Ok: " + v
+ " x " + curr
+ " => " + prettify(s
));
2942 errln((UnicodeString
)"FAIL: " + v
+ " x " + curr
+ " => " + prettify(s
) +
2943 ", expected " + prettify(string
));
2947 void NumberFormatTest::expectPat(DecimalFormat
& fmt
, const UnicodeString
& exp
) {
2951 logln(UnicodeString("Ok \"") + pat
+ "\"");
2953 errln(UnicodeString("FAIL \"") + pat
+ "\", expected \"" + exp
+ "\"");
2957 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2959 expectPad(fmt
, pat
, pos
, 0, (UnicodeString
)"");
2961 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2962 int32_t pos
, int32_t width
, UChar pad
) {
2963 expectPad(fmt
, pat
, pos
, width
, UnicodeString(pad
));
2965 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2966 int32_t pos
, int32_t width
, const UnicodeString
& pad
) {
2967 int32_t apos
= 0, awidth
= 0;
2968 UnicodeString apadStr
;
2969 UErrorCode status
= U_ZERO_ERROR
;
2970 fmt
.applyPattern(pat
, status
);
2971 if (U_SUCCESS(status
)) {
2972 apos
= fmt
.getPadPosition();
2973 awidth
= fmt
.getFormatWidth();
2974 apadStr
=fmt
.getPadCharacterString();
2980 if (apos
== pos
&& awidth
== width
&& apadStr
== pad
) {
2981 UnicodeString infoStr
;
2982 if (pos
== ILLEGAL
) {
2983 infoStr
= UnicodeString(" width=", "") + awidth
+ UnicodeString(" pad=", "") + apadStr
;
2985 logln(UnicodeString("Ok \"") + pat
+ "\" pos=" + apos
+ infoStr
);
2987 errln(UnicodeString("FAIL \"") + pat
+ "\" pos=" + apos
+
2988 " width=" + awidth
+ " pad=" + apadStr
+
2989 ", expected " + pos
+ " " + width
+ " " + pad
);
2993 // This test is flaky b/c the symbols for CNY and JPY are equivalent in this locale - FIXME
2994 void NumberFormatTest::TestCompatibleCurrencies() {
2996 static const UChar JPY[] = {0x4A, 0x50, 0x59, 0};
2997 static const UChar CNY[] = {0x43, 0x4E, 0x59, 0};
2998 UErrorCode status = U_ZERO_ERROR;
2999 LocalPointer<NumberFormat> fmt(
3000 NumberFormat::createCurrencyInstance(Locale::getUS(), status));
3001 if (U_FAILURE(status)) {
3002 errln("Could not create number format instance.");
3005 logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
3006 expectParseCurrency(*fmt, JPY, 1235, "\\u00A51,235");
3007 logln("%s:%d - testing parse of fullwidth yen sign\n", __FILE__, __LINE__);
3008 expectParseCurrency(*fmt, JPY, 1235, "\\uFFE51,235");
3009 logln("%s:%d - testing parse of halfwidth yen sign\n", __FILE__, __LINE__);
3010 expectParseCurrency(*fmt, CNY, 1235, "CN\\u00A51,235");
3012 LocalPointer<NumberFormat> fmtTW(
3013 NumberFormat::createCurrencyInstance(Locale::getTaiwan(), status));
3015 logln("%s:%d - testing parse of halfwidth yen sign in TW\n", __FILE__, __LINE__);
3016 expectParseCurrency(*fmtTW, CNY, 1235, "\\u00A51,235");
3017 logln("%s:%d - testing parse of fullwidth yen sign in TW\n", __FILE__, __LINE__);
3018 expectParseCurrency(*fmtTW, CNY, 1235, "\\uFFE51,235");
3020 LocalPointer<NumberFormat> fmtJP(
3021 NumberFormat::createCurrencyInstance(Locale::getJapan(), status));
3023 logln("%s:%d - testing parse of halfwidth yen sign in JP\n", __FILE__, __LINE__);
3024 expectParseCurrency(*fmtJP, JPY, 1235, "\\u00A51,235");
3025 logln("%s:%d - testing parse of fullwidth yen sign in JP\n", __FILE__, __LINE__);
3026 expectParseCurrency(*fmtJP, JPY, 1235, "\\uFFE51,235");
3032 void NumberFormatTest::expectParseCurrency(const NumberFormat
&fmt
, const UChar
* currency
, double amount
, const char *text
) {
3034 UnicodeString utext
= ctou(text
);
3035 LocalPointer
<CurrencyAmount
> currencyAmount(fmt
.parseCurrency(utext
, ppos
));
3036 if (!ppos
.getIndex()) {
3037 errln(UnicodeString("Parse of ") + utext
+ " should have succeeded.");
3040 UErrorCode status
= U_ZERO_ERROR
;
3043 sprintf(theInfo
, "For locale %s, string \"%s\", currency ",
3044 fmt
.getLocale(ULOC_ACTUAL_LOCALE
, status
).getBaseName(),
3046 u_austrcpy(theInfo
+uprv_strlen(theInfo
), currency
);
3048 char theOperation
[100];
3050 uprv_strcpy(theOperation
, theInfo
);
3051 uprv_strcat(theOperation
, ", check amount:");
3052 assertTrue(theOperation
, amount
== currencyAmount
->getNumber().getDouble(status
));
3054 uprv_strcpy(theOperation
, theInfo
);
3055 uprv_strcat(theOperation
, ", check currency:");
3056 assertEquals(theOperation
, currency
, currencyAmount
->getISOCurrency());
3060 void NumberFormatTest::TestJB3832(){
3061 const char* localeID
= "pt_PT@currency=PTE";
3062 Locale
loc(localeID
);
3063 UErrorCode status
= U_ZERO_ERROR
;
3064 UnicodeString
expected(CharsToUnicodeString("1150$50\\u00A0\\u200B")); // per cldrbug 7670
3066 NumberFormat
* currencyFmt
= NumberFormat::createCurrencyInstance(loc
, status
);
3067 if(U_FAILURE(status
)){
3068 dataerrln("Could not create currency formatter for locale %s - %s", localeID
, u_errorName(status
));
3071 currencyFmt
->format(1150.50, s
);
3073 errln(UnicodeString("FAIL: Expected: ")+expected
3074 + UnicodeString(" Got: ") + s
3075 + UnicodeString( " for locale: ")+ UnicodeString(localeID
) );
3077 if (U_FAILURE(status
)){
3078 errln("FAIL: Status %s", u_errorName(status
));
3083 void NumberFormatTest::TestHost()
3085 #if U_PLATFORM_USES_ONLY_WIN32_API
3086 Win32NumberTest::testLocales(this);
3088 Locale
loc("en_US@compat=host");
3089 for (UNumberFormatStyle k
= UNUM_DECIMAL
;
3090 k
< UNUM_FORMAT_STYLE_COUNT
; k
= (UNumberFormatStyle
)(k
+1)) {
3091 UErrorCode status
= U_ZERO_ERROR
;
3092 LocalPointer
<NumberFormat
> full(NumberFormat::createInstance(loc
, k
, status
));
3093 if (!NumberFormat::isStyleSupported(k
)) {
3094 if (status
!= U_UNSUPPORTED_ERROR
) {
3095 errln("FAIL: expected style %d to be unsupported - %s",
3096 k
, u_errorName(status
));
3100 if (full
.isNull() || U_FAILURE(status
)) {
3101 dataerrln("FAIL: Can't create number instance of style %d for host - %s",
3102 k
, u_errorName(status
));
3105 UnicodeString result1
;
3106 Formattable
number(10.00);
3107 full
->format(number
, result1
, status
);
3108 if (U_FAILURE(status
)) {
3109 errln("FAIL: Can't format for host");
3112 Formattable formattable
;
3113 full
->parse(result1
, formattable
, status
);
3114 if (U_FAILURE(status
)) {
3115 errln("FAIL: Can't parse for host");
3121 void NumberFormatTest::TestHostClone()
3124 Verify that a cloned formatter gives the same results
3125 and is useable after the original has been deleted.
3127 // This is mainly important on Windows.
3128 UErrorCode status
= U_ZERO_ERROR
;
3129 Locale
loc("en_US@compat=host");
3130 UDate now
= Calendar::getNow();
3131 NumberFormat
*full
= NumberFormat::createInstance(loc
, status
);
3132 if (full
== NULL
|| U_FAILURE(status
)) {
3133 dataerrln("FAIL: Can't create NumberFormat date instance - %s", u_errorName(status
));
3136 UnicodeString result1
;
3137 full
->format(now
, result1
, status
);
3138 Format
*fullClone
= full
->clone();
3142 UnicodeString result2
;
3143 fullClone
->format(now
, result2
, status
);
3144 if (U_FAILURE(status
)) {
3145 errln("FAIL: format failure.");
3147 if (result1
!= result2
) {
3148 errln("FAIL: Clone returned different result from non-clone.");
3153 void NumberFormatTest::TestCurrencyFormat()
3155 // This test is here to increase code coverage.
3156 UErrorCode status
= U_ZERO_ERROR
;
3157 MeasureFormat
*cloneObj
;
3159 Formattable toFormat
, result
;
3160 static const UChar ISO_CODE
[4] = {0x0047, 0x0042, 0x0050, 0};
3162 Locale saveDefaultLocale
= Locale::getDefault();
3163 Locale::setDefault( Locale::getUK(), status
);
3164 if (U_FAILURE(status
)) {
3165 errln("couldn't set default Locale!");
3169 MeasureFormat
*measureObj
= MeasureFormat::createCurrencyFormat(status
);
3170 if (U_FAILURE(status
)){
3171 dataerrln("FAIL: MeasureFormat::createCurrencyFormat status %s", u_errorName(status
));
3174 Locale::setDefault( saveDefaultLocale
, status
);
3175 if (U_FAILURE(status
)){
3176 dataerrln("FAIL: Locale::setDefault status %s", u_errorName(status
));
3179 cloneObj
= (MeasureFormat
*)measureObj
->clone();
3180 if (cloneObj
== NULL
) {
3181 errln("Clone doesn't work");
3184 toFormat
.adoptObject(new CurrencyAmount(1234.56, ISO_CODE
, status
));
3185 measureObj
->format(toFormat
, str
, status
);
3186 measureObj
->parseObject(str
, result
, status
);
3187 if (U_FAILURE(status
)){
3188 errln("FAIL: Status %s", u_errorName(status
));
3190 if (result
!= toFormat
) {
3191 errln("measureObj does not round trip. Formatted string was \"" + str
+ "\" Got: " + toString(result
) + " Expected: " + toString(toFormat
));
3193 status
= U_ZERO_ERROR
;
3195 cloneObj
->format(toFormat
, str
, status
);
3196 cloneObj
->parseObject(str
, result
, status
);
3197 if (U_FAILURE(status
)){
3198 errln("FAIL: Status %s", u_errorName(status
));
3200 if (result
!= toFormat
) {
3201 errln("Clone does not round trip. Formatted string was \"" + str
+ "\" Got: " + toString(result
) + " Expected: " + toString(toFormat
));
3203 if (*measureObj
!= *cloneObj
) {
3204 errln("Cloned object is not equal to the original object");
3209 status
= U_USELESS_COLLATOR_ERROR
;
3210 if (MeasureFormat::createCurrencyFormat(status
) != NULL
) {
3211 errln("createCurrencyFormat should have returned NULL.");
3215 /* Port of ICU4J rounding test. */
3216 void NumberFormatTest::TestRounding() {
3217 UErrorCode status
= U_ZERO_ERROR
;
3218 DecimalFormat
*df
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status
);
3220 if (U_FAILURE(status
)) {
3221 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status
));
3225 int roundingIncrements
[]={1, 2, 5, 20, 50, 100};
3226 int testValues
[]={0, 300};
3228 for (int j
=0; j
<2; j
++) {
3229 for (int mode
=DecimalFormat::kRoundUp
;mode
<DecimalFormat::kRoundHalfEven
;mode
++) {
3230 df
->setRoundingMode((DecimalFormat::ERoundingMode
)mode
);
3231 for (int increment
=0; increment
<6; increment
++) {
3232 double base
=testValues
[j
];
3233 double rInc
=roundingIncrements
[increment
];
3234 checkRounding(df
, base
, 20, rInc
);
3235 rInc
=1.000000000/rInc
;
3236 checkRounding(df
, base
, 20, rInc
);
3243 void NumberFormatTest::TestRoundingPattern() {
3244 UErrorCode status
= U_ZERO_ERROR
;
3246 UnicodeString pattern
;
3248 UnicodeString expected
;
3250 { (UnicodeString
)"##0.65", 1.234, (UnicodeString
)"1.30" },
3251 { (UnicodeString
)"#50", 1230, (UnicodeString
)"1250" }
3253 int32_t numOfTests
= UPRV_LENGTHOF(tests
);
3254 UnicodeString result
;
3256 DecimalFormat
*df
= (DecimalFormat
*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status
);
3257 if (U_FAILURE(status
)) {
3258 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status
));
3262 for (int32_t i
= 0; i
< numOfTests
; i
++) {
3265 df
->applyPattern(tests
[i
].pattern
, status
);
3266 if (U_FAILURE(status
)) {
3267 errln("Unable to apply pattern to decimal formatter. - %s", u_errorName(status
));
3270 df
->format(tests
[i
].testCase
, result
);
3272 if (result
!= tests
[i
].expected
) {
3273 errln("String Pattern Rounding Test Failed: Pattern: \"" + tests
[i
].pattern
+ "\" Number: " + tests
[i
].testCase
+ " - Got: " + result
+ " Expected: " + tests
[i
].expected
);
3280 void NumberFormatTest::checkRounding(DecimalFormat
* df
, double base
, int iterations
, double increment
) {
3281 df
->setRoundingIncrement(increment
);
3282 double lastParsed
=INT32_MIN
; //Intger.MIN_VALUE
3283 for (int i
=-iterations
; i
<=iterations
;i
++) {
3284 double iValue
=base
+(increment
*(i
*0.1));
3285 double smallIncrement
=0.00000001;
3287 smallIncrement
*=iValue
;
3289 //we not only test the value, but some values in a small range around it
3290 lastParsed
=checkRound(df
, iValue
-smallIncrement
, lastParsed
);
3291 lastParsed
=checkRound(df
, iValue
, lastParsed
);
3292 lastParsed
=checkRound(df
, iValue
+smallIncrement
, lastParsed
);
3296 double NumberFormatTest::checkRound(DecimalFormat
* df
, double iValue
, double lastParsed
) {
3297 UErrorCode status
=U_ZERO_ERROR
;
3298 UnicodeString formattedDecimal
;
3301 df
->format(iValue
, formattedDecimal
, status
);
3303 if (U_FAILURE(status
)) {
3304 errln("Error formatting number.");
3307 df
->parse(formattedDecimal
, result
, status
);
3309 if (U_FAILURE(status
)) {
3310 errln("Error parsing number.");
3313 parsed
=result
.getDouble();
3315 if (lastParsed
>parsed
) {
3316 errln("Rounding wrong direction! %d > %d", lastParsed
, parsed
);
3322 void NumberFormatTest::TestNonpositiveMultiplier() {
3323 UErrorCode status
= U_ZERO_ERROR
;
3324 DecimalFormatSymbols
US(Locale::getUS(), status
);
3325 CHECK(status
, "DecimalFormatSymbols constructor");
3326 DecimalFormat
df(UnicodeString("0"), US
, status
);
3327 CHECK(status
, "DecimalFormat(0)");
3329 // test zero multiplier
3331 int32_t mult
= df
.getMultiplier();
3332 df
.setMultiplier(0);
3333 if (df
.getMultiplier() != mult
) {
3334 errln("DecimalFormat.setMultiplier(0) did not ignore its zero input");
3337 // test negative multiplier
3339 df
.setMultiplier(-1);
3340 if (df
.getMultiplier() != -1) {
3341 errln("DecimalFormat.setMultiplier(-1) ignored its negative input");
3345 expect(df
, "1122.123", -1122.123);
3346 expect(df
, "-1122.123", 1122.123);
3347 expect(df
, "1.2", -1.2);
3348 expect(df
, "-1.2", 1.2);
3350 // Note: the tests with the final parameter of FALSE will not round trip.
3351 // The initial numeric value will format correctly, after the multiplier.
3352 // Parsing the formatted text will be out-of-range for an int64, however.
3353 // The expect() function could be modified to detect this and fall back
3354 // to looking at the decimal parsed value, but it doesn't.
3355 expect(df
, U_INT64_MIN
, "9223372036854775808", FALSE
);
3356 expect(df
, U_INT64_MIN
+1, "9223372036854775807");
3357 expect(df
, (int64_t)-123, "123");
3358 expect(df
, (int64_t)123, "-123");
3359 expect(df
, U_INT64_MAX
-1, "-9223372036854775806");
3360 expect(df
, U_INT64_MAX
, "-9223372036854775807");
3362 df
.setMultiplier(-2);
3363 expect(df
, -(U_INT64_MIN
/2)-1, "-9223372036854775806");
3364 expect(df
, -(U_INT64_MIN
/2), "-9223372036854775808");
3365 expect(df
, -(U_INT64_MIN
/2)+1, "-9223372036854775810", FALSE
);
3367 df
.setMultiplier(-7);
3368 expect(df
, -(U_INT64_MAX
/7)-1, "9223372036854775814", FALSE
);
3369 expect(df
, -(U_INT64_MAX
/7), "9223372036854775807");
3370 expect(df
, -(U_INT64_MAX
/7)+1, "9223372036854775800");
3372 // TODO: uncomment (and fix up) all the following int64_t tests once BigInteger is ported
3373 // (right now the big numbers get turned into doubles and lose tons of accuracy)
3374 //expect2(df, U_INT64_MAX, Int64ToUnicodeString(-U_INT64_MAX));
3375 //expect2(df, U_INT64_MIN, UnicodeString(Int64ToUnicodeString(U_INT64_MIN), 1));
3376 //expect2(df, U_INT64_MAX / 2, Int64ToUnicodeString(-(U_INT64_MAX / 2)));
3377 //expect2(df, U_INT64_MIN / 2, Int64ToUnicodeString(-(U_INT64_MIN / 2)));
3379 // TODO: uncomment (and fix up) once BigDecimal is ported and DecimalFormat can handle it
3380 //expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
3381 //expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
3382 //expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
3383 //expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
3387 const char * stringToParse
;
3391 } TestSpaceParsingItem
;
3394 NumberFormatTest::TestSpaceParsing() {
3396 // the string to be parsed, parsed position, parsed error index
3397 const TestSpaceParsingItem DATA
[] = {
3398 {"$124", 4, -1, FALSE
},
3399 {"$124 $124", 4, -1, FALSE
},
3400 {"$124 ", 4, -1, FALSE
},
3401 //{"$ 124 ", 0, 1, FALSE},
3402 {"$ 124 ", 5, -1, FALSE
}, // Apple <rdar://problem/38565910> also changes this expected result (for the better...)
3403 {"$\\u00A0124 ", 5, -1, FALSE
},
3404 {" $ 124 ", 0, 0, FALSE
},
3405 {"124$", 0, 4, FALSE
},
3406 {"124 $", 0, 3, FALSE
},
3407 {"$124", 4, -1, TRUE
},
3408 {"$124 $124", 4, -1, TRUE
},
3409 {"$124 ", 4, -1, TRUE
},
3410 {"$ 124 ", 5, -1, TRUE
},
3411 {"$\\u00A0124 ", 5, -1, TRUE
},
3412 {" $ 124 ", 6, -1, TRUE
},
3413 {"124$", 4, -1, TRUE
},
3414 {"124$", 4, -1, TRUE
},
3415 {"124 $", 5, -1, TRUE
},
3416 {"124 $", 5, -1, TRUE
},
3418 UErrorCode status
= U_ZERO_ERROR
;
3419 Locale
locale("en_US");
3420 NumberFormat
* foo
= NumberFormat::createCurrencyInstance(locale
, status
);
3422 if (U_FAILURE(status
)) {
3426 for (uint32_t i
= 0; i
< UPRV_LENGTHOF(DATA
); ++i
) {
3427 ParsePosition
parsePosition(0);
3428 UnicodeString stringToBeParsed
= ctou(DATA
[i
].stringToParse
);
3429 int parsedPosition
= DATA
[i
].parsedPos
;
3430 int errorIndex
= DATA
[i
].errorIndex
;
3431 foo
->setLenient(DATA
[i
].lenient
);
3433 foo
->parse(stringToBeParsed
, result
, parsePosition
);
3434 logln("Parsing: " + stringToBeParsed
);
3435 if (parsePosition
.getIndex() != parsedPosition
||
3436 parsePosition
.getErrorIndex() != errorIndex
) {
3437 errln("FAILED parse " + stringToBeParsed
+ "; lenient: " + DATA
[i
].lenient
+ "; wrong position, expected: (" + parsedPosition
+ ", " + errorIndex
+ "); got (" + parsePosition
.getIndex() + ", " + parsePosition
.getErrorIndex() + ")");
3439 if (parsePosition
.getErrorIndex() == -1 &&
3440 result
.getType() == Formattable::kLong
&&
3441 result
.getLong() != 124) {
3442 errln("FAILED parse " + stringToBeParsed
+ "; wrong number, expect: 124, got " + result
.getLong());
3449 * Test using various numbering systems and numbering system keyword.
3452 const char *localeName
;
3455 const char *expectedResult
;
3456 } TestNumberingSystemItem
;
3458 void NumberFormatTest::TestNumberingSystems() {
3460 const TestNumberingSystemItem DATA
[] = {
3461 { "en_US@numbers=thai", 1234.567, FALSE
, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" },
3462 { "en_US@numbers=hebr", 5678.0, TRUE
, "\\u05D4\\u05F3\\u05EA\\u05E8\\u05E2\\u05F4\\u05D7" },
3463 { "en_US@numbers=arabext", 1234.567, FALSE
, "\\u06F1\\u066c\\u06F2\\u06F3\\u06F4\\u066b\\u06F5\\u06F6\\u06F7" },
3464 { "ar_EG", 1234.567, FALSE
, "\\u0661\\u066C\\u0662\\u0663\\u0664\\u066b\\u0665\\u0666\\u0667" },
3465 { "th_TH@numbers=traditional", 1234.567, FALSE
, "\\u0E51,\\u0E52\\u0E53\\u0E54.\\u0E55\\u0E56\\u0E57" }, // fall back to native per TR35
3466 { "ar_MA", 1234.567, FALSE
, "1.234,567" },
3467 { "en_US@numbers=hanidec", 1234.567, FALSE
, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3468 { "ta_IN@numbers=native", 1234.567, FALSE
, "\\u0BE7,\\u0BE8\\u0BE9\\u0BEA.\\u0BEB\\u0BEC\\u0BED" },
3469 { "ta_IN@numbers=traditional", 1235.0, TRUE
, "\\u0BF2\\u0BE8\\u0BF1\\u0BE9\\u0BF0\\u0BEB" },
3470 { "ta_IN@numbers=finance", 1234.567, FALSE
, "1,234.567" }, // fall back to default per TR35
3471 { "zh_TW@numbers=native", 1234.567, FALSE
, "\\u4e00,\\u4e8c\\u4e09\\u56db.\\u4e94\\u516d\\u4e03" },
3472 { "zh_TW@numbers=traditional", 1234.567, TRUE
, "\\u4E00\\u5343\\u4E8C\\u767E\\u4E09\\u5341\\u56DB\\u9EDE\\u4E94\\u516D\\u4E03" },
3473 { "zh_TW@numbers=finance", 1234.567, TRUE
, "\\u58F9\\u4EDF\\u8CB3\\u4F70\\u53C3\\u62FE\\u8086\\u9EDE\\u4F0D\\u9678\\u67D2" },
3474 { NULL
, 0, FALSE
, NULL
}
3479 const TestNumberingSystemItem
*item
;
3480 for (item
= DATA
; item
->localeName
!= NULL
; item
++) {
3482 Locale loc
= Locale::createFromName(item
->localeName
);
3484 NumberFormat
*origFmt
= NumberFormat::createInstance(loc
,ec
);
3485 if (U_FAILURE(ec
)) {
3486 dataerrln("FAIL: getInstance(%s) - %s", item
->localeName
, u_errorName(ec
));
3489 // Clone to test ticket #10682
3490 NumberFormat
*fmt
= (NumberFormat
*) origFmt
->clone();
3495 expect3(*fmt
,item
->value
,CharsToUnicodeString(item
->expectedResult
));
3497 expect2(*fmt
,item
->value
,CharsToUnicodeString(item
->expectedResult
));
3503 // Test bogus keyword value
3505 Locale loc4
= Locale::createFromName("en_US@numbers=foobar");
3506 NumberFormat
* fmt4
= NumberFormat::createInstance(loc4
, ec
);
3507 if ( ec
!= U_UNSUPPORTED_ERROR
) {
3508 errln("FAIL: getInstance(en_US@numbers=foobar) should have returned U_UNSUPPORTED_ERROR");
3513 NumberingSystem
*ns
= NumberingSystem::createInstance(ec
);
3514 if (U_FAILURE(ec
)) {
3515 dataerrln("FAIL: NumberingSystem::createInstance(ec); - %s", u_errorName(ec
));
3519 ns
->getDynamicClassID();
3520 ns
->getStaticClassID();
3522 errln("FAIL: getInstance() returned NULL.");
3525 NumberingSystem
*ns1
= new NumberingSystem(*ns
);
3527 errln("FAIL: NumberSystem copy constructor returned NULL.");
3537 NumberFormatTest::TestMultiCurrencySign() {
3538 const char* DATA
[][6] = {
3539 // the fields in the following test are:
3541 // currency pattern (with negative pattern),
3542 // currency number to be formatted,
3543 // currency format using currency symbol name, such as "$" for USD,
3544 // currency format using currency ISO name, such as "USD",
3545 // currency format using plural name, such as "US dollars".
3547 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1234.56", "$1,234.56", "USD\\u00A01,234.56", "US dollars\\u00A01,234.56"},
3548 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD\\u00A01,234.56", "-US dollars\\u00A01,234.56"},
3549 {"en_US", "\\u00A4#,##0.00;-\\u00A4#,##0.00", "1", "$1.00", "USD\\u00A01.00", "US dollars\\u00A01.00"},
3551 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1234.56", "\\u00A51,234.56", "CNY\\u00A01,234.56", "\\u4EBA\\u6C11\\u5E01\\u00A01,234.56"},
3552 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "-1234.56", "(\\u00A51,234.56)", "(CNY\\u00A01,234.56)", "(\\u4EBA\\u6C11\\u5E01\\u00A01,234.56)"},
3553 {"zh_CN", "\\u00A4#,##0.00;(\\u00A4#,##0.00)", "1", "\\u00A51.00", "CNY\\u00A01.00", "\\u4EBA\\u6C11\\u5E01\\u00A01.00"}
3556 const UChar doubleCurrencySign
[] = {0xA4, 0xA4, 0};
3557 UnicodeString
doubleCurrencyStr(doubleCurrencySign
);
3558 const UChar tripleCurrencySign
[] = {0xA4, 0xA4, 0xA4, 0};
3559 UnicodeString
tripleCurrencyStr(tripleCurrencySign
);
3561 for (uint32_t i
=0; i
<UPRV_LENGTHOF(DATA
); ++i
) {
3562 const char* locale
= DATA
[i
][0];
3563 UnicodeString pat
= ctou(DATA
[i
][1]);
3564 double numberToBeFormat
= atof(DATA
[i
][2]);
3565 UErrorCode status
= U_ZERO_ERROR
;
3566 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols(Locale(locale
), status
);
3567 if (U_FAILURE(status
)) {
3571 for (int j
=1; j
<=3; ++j
) {
3572 // j represents the number of currency sign in the pattern.
3574 pat
= pat
.findAndReplace(ctou("\\u00A4"), doubleCurrencyStr
);
3575 } else if (j
== 3) {
3576 pat
= pat
.findAndReplace(ctou("\\u00A4\\u00A4"), tripleCurrencyStr
);
3579 DecimalFormat
* fmt
= new DecimalFormat(pat
, new DecimalFormatSymbols(*sym
), status
);
3580 if (U_FAILURE(status
)) {
3581 errln("FAILED init DecimalFormat ");
3586 ((NumberFormat
*) fmt
)->format(numberToBeFormat
, s
);
3587 // DATA[i][3] is the currency format result using a
3588 // single currency sign.
3589 // DATA[i][4] is the currency format result using
3590 // double currency sign.
3591 // DATA[i][5] is the currency format result using
3592 // triple currency sign.
3593 // DATA[i][j+2] is the currency format result using
3594 // 'j' number of currency sign.
3595 UnicodeString currencyFormatResult
= ctou(DATA
[i
][2+j
]);
3596 if (s
.compare(currencyFormatResult
)) {
3597 errln("FAIL format: Expected " + currencyFormatResult
+ "; Got " + s
);
3599 // mix style parsing
3600 for (int k
=3; k
<=5; ++k
) {
3601 // DATA[i][3] is the currency format result using a
3602 // single currency sign.
3603 // DATA[i][4] is the currency format result using
3604 // double currency sign.
3605 // DATA[i][5] is the currency format result using
3606 // triple currency sign.
3607 UnicodeString oneCurrencyFormat
= ctou(DATA
[i
][k
]);
3608 UErrorCode status
= U_ZERO_ERROR
;
3609 Formattable parseRes
;
3610 fmt
->parse(oneCurrencyFormat
, parseRes
, status
);
3611 if (U_FAILURE(status
) ||
3612 (parseRes
.getType() == Formattable::kDouble
&&
3613 parseRes
.getDouble() != numberToBeFormat
) ||
3614 (parseRes
.getType() == Formattable::kLong
&&
3615 parseRes
.getLong() != numberToBeFormat
)) {
3616 errln("FAILED parse " + oneCurrencyFormat
+ "; (i, j, k): " +
3617 i
+ ", " + j
+ ", " + k
);
3628 NumberFormatTest::TestCurrencyFormatForMixParsing() {
3629 UErrorCode status
= U_ZERO_ERROR
;
3630 MeasureFormat
* curFmt
= MeasureFormat::createCurrencyFormat(Locale("en_US"), status
);
3631 if (U_FAILURE(status
)) {
3635 const char* formats
[] = {
3636 "$1,234.56", // string to be parsed
3638 "US dollars1,234.56",
3639 // "1,234.56 US dollars" // Fails in 62 because currency format is not compatible with pattern.
3641 const CurrencyAmount
* curramt
= NULL
;
3642 for (uint32_t i
= 0; i
< UPRV_LENGTHOF(formats
); ++i
) {
3643 UnicodeString stringToBeParsed
= ctou(formats
[i
]);
3644 logln(UnicodeString("stringToBeParsed: ") + stringToBeParsed
);
3646 UErrorCode status
= U_ZERO_ERROR
;
3647 curFmt
->parseObject(stringToBeParsed
, result
, status
);
3648 if (U_FAILURE(status
)) {
3649 errln("FAIL: measure format parsing: '%s' ec: %s", formats
[i
], u_errorName(status
));
3650 } else if (result
.getType() != Formattable::kObject
||
3651 (curramt
= dynamic_cast<const CurrencyAmount
*>(result
.getObject())) == NULL
||
3652 curramt
->getNumber().getDouble() != 1234.56 ||
3653 UnicodeString(curramt
->getISOCurrency()).compare(ISO_CURRENCY_USD
)
3655 errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number ");
3656 if (curramt
->getNumber().getDouble() != 1234.56) {
3657 errln((UnicodeString
)"wong number, expect: 1234.56" + ", got: " + curramt
->getNumber().getDouble());
3659 if (curramt
->getISOCurrency() != ISO_CURRENCY_USD
) {
3660 errln((UnicodeString
)"wong currency, expect: USD" + ", got: " + curramt
->getISOCurrency());
3668 /** Starting in ICU 62, strict mode is actually strict with currency formats. */
3669 void NumberFormatTest::TestMismatchedCurrencyFormatFail() {
3670 IcuTestErrorCode
status(*this, "TestMismatchedCurrencyFormatFail");
3671 LocalPointer
<DecimalFormat
> df(
3672 dynamic_cast<DecimalFormat
*>(DecimalFormat::createCurrencyInstance("en", status
)), status
);
3673 if (!assertSuccess("createCurrencyInstance() failed.", status
, true, __FILE__
, __LINE__
)) {return;}
3674 UnicodeString pattern
;
3675 assertEquals("Test assumes that currency sign is at the beginning",
3677 df
->toPattern(pattern
));
3678 // Should round-trip on the correct currency format:
3679 expect2(*df
, 1.23, u
"\u00A41.23");
3680 df
->setCurrency(u
"EUR", status
);
3681 expect2(*df
, 1.23, u
"\u20AC1.23");
3682 // Should parse with currency in the wrong place in lenient mode
3683 df
->setLenient(TRUE
);
3684 expect(*df
, u
"1.23\u20AC", 1.23);
3685 expectParseCurrency(*df
, u
"EUR", 1.23, "1.23\\u20AC");
3686 // Should NOT parse with currency in the wrong place in STRICT mode
3687 df
->setLenient(FALSE
);
3690 ErrorCode failStatus
;
3691 df
->parse(u
"1.23\u20AC", result
, failStatus
);
3692 assertEquals("Should fail to parse", U_INVALID_FORMAT_ERROR
, failStatus
);
3696 df
->parseCurrency(u
"1.23\u20AC", ppos
);
3697 assertEquals("Should fail to parse currency", 0, ppos
.getIndex());
3703 NumberFormatTest::TestDecimalFormatCurrencyParse() {
3705 UErrorCode status
= U_ZERO_ERROR
;
3706 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols(Locale("en_US"), status
);
3707 if (U_FAILURE(status
)) {
3712 UChar currency
= 0x00A4;
3713 // "\xA4#,##0.00;-\xA4#,##0.00"
3714 pat
.append(currency
).append(currency
).append(currency
).append("#,##0.00;-").append(currency
).append(currency
).append(currency
).append("#,##0.00");
3715 DecimalFormat
* fmt
= new DecimalFormat(pat
, sym
, status
);
3716 if (U_FAILURE(status
)) {
3718 errln("failed to new DecimalFormat in TestDecimalFormatCurrencyParse");
3721 const char* DATA
[][2] = {
3723 // string to be parsed, the parsed result (number)
3726 {"1.00 US dollar", "1"},
3727 {"$1,234.56", "1234.56"},
3728 {"USD1,234.56", "1234.56"},
3729 {"1,234.56 US dollar", "1234.56"},
3731 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3732 fmt
->setLenient(TRUE
);
3733 for (uint32_t i
= 0; i
< UPRV_LENGTHOF(DATA
); ++i
) {
3734 UnicodeString stringToBeParsed
= ctou(DATA
[i
][0]);
3735 double parsedResult
= atof(DATA
[i
][1]);
3736 UErrorCode status
= U_ZERO_ERROR
;
3738 fmt
->parse(stringToBeParsed
, result
, status
);
3739 logln((UnicodeString
)"Input: " + stringToBeParsed
+ "; output: " + result
.getDouble(status
));
3740 if (U_FAILURE(status
) ||
3741 (result
.getType() == Formattable::kDouble
&&
3742 result
.getDouble() != parsedResult
) ||
3743 (result
.getType() == Formattable::kLong
&&
3744 result
.getLong() != parsedResult
)) {
3745 errln((UnicodeString
)"FAIL parse: Expected " + parsedResult
);
3753 NumberFormatTest::TestCurrencyIsoPluralFormat() {
3754 static const char* DATA
[][6] = {
3757 // currency amount to be formatted,
3758 // currency ISO code to be formatted,
3759 // format result using CURRENCYSTYLE,
3760 // format result using ISOCURRENCYSTYLE,
3761 // format result using PLURALCURRENCYSTYLE,
3763 {"en_US", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00 US dollars"},
3764 {"en_US", "1234.56", "USD", "$1,234.56", "USD\\u00A01,234.56", "1,234.56 US dollars"},
3765 {"en_US", "-1234.56", "USD", "-$1,234.56", "-USD\\u00A01,234.56", "-1,234.56 US dollars"},
3766 {"zh_CN", "1", "USD", "US$1.00", "USD\\u00A01.00", "1.00\\u00A0\\u7F8E\\u5143"},
3767 {"zh_CN", "1234.56", "USD", "US$1,234.56", "USD\\u00A01,234.56", "1,234.56\\u00A0\\u7F8E\\u5143"},
3768 {"zh_CN", "1", "CNY", "\\u00A51.00", "CNY\\u00A01.00", "1.00\\u00A0\\u4EBA\\u6C11\\u5E01"},
3769 {"zh_CN", "1234.56", "CNY", "\\u00A51,234.56", "CNY\\u00A01,234.56", "1,234.56\\u00A0\\u4EBA\\u6C11\\u5E01"},
3770 {"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"},
3771 {"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"},
3772 {"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"},
3773 // test locale without currency information
3774 {"root", "-1.23", "USD", "-US$\\u00A01.23", "-USD\\u00A01.23", "-1.23 USD"},
3775 // test choice format
3776 {"es_AR", "1", "INR", "INR\\u00A01,00", "INR\\u00A01,00", "1,00 rupia india"},
3778 static const UNumberFormatStyle currencyStyles
[] = {
3781 UNUM_CURRENCY_PLURAL
3784 for (int32_t i
=0; i
<UPRV_LENGTHOF(DATA
); ++i
) {
3785 const char* localeString
= DATA
[i
][0];
3786 double numberToBeFormat
= atof(DATA
[i
][1]);
3787 const char* currencyISOCode
= DATA
[i
][2];
3788 logln(UnicodeString(u
"Locale: ") + localeString
+ "; amount: " + numberToBeFormat
);
3789 Locale
locale(localeString
);
3790 for (int32_t kIndex
= 0; kIndex
< UPRV_LENGTHOF(currencyStyles
); ++kIndex
) {
3791 UNumberFormatStyle k
= currencyStyles
[kIndex
];
3792 logln(UnicodeString(u
"UNumberFormatStyle: ") + k
);
3793 UErrorCode status
= U_ZERO_ERROR
;
3794 NumberFormat
* numFmt
= NumberFormat::createInstance(locale
, k
, status
);
3795 if (U_FAILURE(status
)) {
3797 dataerrln((UnicodeString
)"can not create instance, locale:" + localeString
+ ", style: " + k
+ " - " + u_errorName(status
));
3800 UChar currencyCode
[4];
3801 u_charsToUChars(currencyISOCode
, currencyCode
, 4);
3802 numFmt
->setCurrency(currencyCode
, status
);
3803 if (U_FAILURE(status
)) {
3805 errln((UnicodeString
)"can not set currency:" + currencyISOCode
);
3809 UnicodeString strBuf
;
3810 numFmt
->format(numberToBeFormat
, strBuf
);
3811 int resultDataIndex
= 3 + kIndex
;
3812 // DATA[i][resultDataIndex] is the currency format result
3813 // using 'k' currency style.
3814 UnicodeString formatResult
= ctou(DATA
[i
][resultDataIndex
]);
3815 if (strBuf
.compare(formatResult
)) {
3816 errln("FAIL: Expected " + formatResult
+ " actual: " + strBuf
);
3818 // test parsing, and test parsing for all currency formats.
3819 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3820 numFmt
->setLenient(TRUE
);
3821 for (int j
= 3; j
< 6; ++j
) {
3822 // DATA[i][3] is the currency format result using
3823 // CURRENCYSTYLE formatter.
3824 // DATA[i][4] is the currency format result using
3825 // ISOCURRENCYSTYLE formatter.
3826 // DATA[i][5] is the currency format result using
3827 // PLURALCURRENCYSTYLE formatter.
3828 UnicodeString oneCurrencyFormatResult
= ctou(DATA
[i
][j
]);
3829 UErrorCode status
= U_ZERO_ERROR
;
3830 Formattable parseResult
;
3831 numFmt
->parse(oneCurrencyFormatResult
, parseResult
, status
);
3832 if (U_FAILURE(status
) ||
3833 (parseResult
.getType() == Formattable::kDouble
&&
3834 parseResult
.getDouble() != numberToBeFormat
) ||
3835 (parseResult
.getType() == Formattable::kLong
&&
3836 parseResult
.getLong() != numberToBeFormat
)) {
3837 errln((UnicodeString
)"FAIL: getCurrencyFormat of locale " +
3838 localeString
+ " failed roundtripping the number");
3839 if (parseResult
.getType() == Formattable::kDouble
) {
3840 errln((UnicodeString
)"expected: " + numberToBeFormat
+ "; actual: " +parseResult
.getDouble());
3842 errln((UnicodeString
)"expected: " + numberToBeFormat
+ "; actual: " +parseResult
.getLong());
3852 NumberFormatTest::TestCurrencyParsing() {
3853 static const char* DATA
[][6] = {
3856 // currency amount to be formatted,
3857 // currency ISO code to be formatted,
3858 // format result using CURRENCYSTYLE,
3859 // format result using ISOCURRENCYSTYLE,
3860 // format result using PLURALCURRENCYSTYLE,
3861 {"en_US", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00 US dollars"},
3862 {"pa_IN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\u0a2f\\u0a42.\\u0a10\\u0a38. \\u0a21\\u0a3e\\u0a32\\u0a30"},
3863 {"es_AR", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 d\\u00f3lar estadounidense"},
3864 {"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"},
3865 {"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"},
3866 {"he_IL", "1", "USD", "\\u200f1.00\\u00a0$", "\\u200f1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"},
3867 {"hr_HR", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 ameri\\u010Dkih dolara"},
3868 {"id_ID", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 Dolar Amerika Serikat"},
3869 {"it_IT", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 dollari statunitensi"},
3870 {"ko_KR", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"},
3871 {"ja_JP", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00\\u00A0\\u7c73\\u30c9\\u30eb"},
3872 {"zh_CN", "1", "CNY", "\\u00A51.00", "CNY\\u00A001.00", "1.00\\u00A0\\u4EBA\\u6C11\\u5E01"},
3873 {"zh_TW", "1", "CNY", "CN\\u00A51.00", "CNY\\u00A01.00", "1.00\\u00A0\\u4eba\\u6c11\\u5e63"},
3874 {"zh_Hant", "1", "CNY", "CN\\u00A51.00", "CNY\\u00A01.00", "1.00\\u00A0\\u4eba\\u6c11\\u5e63"},
3875 {"zh_Hant", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1\\u00A0\\u65E5\\u5713"},
3876 {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1\\u00A0\\u5186"},
3877 // ICU 62 requires #parseCurrency() to recognize variants when parsing
3878 // {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1\\u00A0\\u5186"},
3879 {"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"}
3881 static const UNumberFormatStyle currencyStyles
[] = {
3884 UNUM_CURRENCY_PLURAL
3886 static const char* currencyStyleNames
[] = {
3888 "UNUM_CURRENCY_ISO",
3889 "UNUM_CURRENCY_PLURAL"
3892 #ifdef NUMFMTST_CACHE_DEBUG
3895 printf("loop: %d\n", deadloop
++);
3897 for (uint32_t i
=0; i
< UPRV_LENGTHOF(DATA
); ++i
) { /* i = test case # - should be i=0*/
3898 for (int32_t kIndex
= 2; kIndex
< UPRV_LENGTHOF(currencyStyles
); ++kIndex
) {
3899 UNumberFormatStyle k
= currencyStyles
[kIndex
]; /* k = style */
3900 const char* localeString
= DATA
[i
][0];
3901 double numberToBeFormat
= atof(DATA
[i
][1]);
3902 const char* currencyISOCode
= DATA
[i
][2];
3903 Locale
locale(localeString
);
3904 UErrorCode status
= U_ZERO_ERROR
;
3905 NumberFormat
* numFmt
= NumberFormat::createInstance(locale
, k
, status
);
3906 logln("#%d NumberFormat(%s, %s) Currency=%s\n",
3907 i
, localeString
, currencyStyleNames
[kIndex
],
3910 if (U_FAILURE(status
)) {
3912 dataerrln((UnicodeString
)"can not create instance, locale:" + localeString
+ ", style: " + k
+ " - " + u_errorName(status
));
3915 UChar currencyCode
[4];
3916 u_charsToUChars(currencyISOCode
, currencyCode
, 4);
3917 numFmt
->setCurrency(currencyCode
, status
);
3918 if (U_FAILURE(status
)) {
3920 errln((UnicodeString
)"can not set currency:" + currencyISOCode
);
3924 UnicodeString strBuf
;
3925 numFmt
->format(numberToBeFormat
, strBuf
);
3926 int resultDataIndex
= 3 + kIndex
;
3927 // DATA[i][resultDataIndex] is the currency format result
3928 // using 'k' currency style.
3929 UnicodeString formatResult
= ctou(DATA
[i
][resultDataIndex
]);
3930 if (strBuf
.compare(formatResult
)) {
3931 errln("FAIL: Expected " + formatResult
+ " actual: " + strBuf
);
3933 // test parsing, and test parsing for all currency formats.
3934 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3935 numFmt
->setLenient(TRUE
);
3936 for (int j
= 3; j
< 6; ++j
) {
3937 // DATA[i][3] is the currency format result using
3938 // CURRENCYSTYLE formatter.
3939 // DATA[i][4] is the currency format result using
3940 // ISOCURRENCYSTYLE formatter.
3941 // DATA[i][5] is the currency format result using
3942 // PLURALCURRENCYSTYLE formatter.
3943 UnicodeString oneCurrencyFormatResult
= ctou(DATA
[i
][j
]);
3944 UErrorCode status
= U_ZERO_ERROR
;
3945 Formattable parseResult
;
3946 logln("parse(%s)", DATA
[i
][j
]);
3947 numFmt
->parse(oneCurrencyFormatResult
, parseResult
, status
);
3948 if (U_FAILURE(status
) ||
3949 (parseResult
.getType() == Formattable::kDouble
&&
3950 parseResult
.getDouble() != numberToBeFormat
) ||
3951 (parseResult
.getType() == Formattable::kLong
&&
3952 parseResult
.getLong() != numberToBeFormat
)) {
3953 errln((UnicodeString
)"FAIL: NumberFormat(" + localeString
+", " + currencyStyleNames
[kIndex
] +
3954 "), Currency="+currencyISOCode
+", parse("+DATA
[i
][j
]+") returned error " + (UnicodeString
)u_errorName(status
)+". Testcase: data[" + i
+ "][" + currencyStyleNames
[j
-3] +"="+j
+"]");
3955 if (parseResult
.getType() == Formattable::kDouble
) {
3956 errln((UnicodeString
)"expected: " + numberToBeFormat
+ "; actual (double): " +parseResult
.getDouble());
3958 errln((UnicodeString
)"expected: " + numberToBeFormat
+ "; actual (long): " +parseResult
.getLong());
3960 errln((UnicodeString
)" round-trip would be: " + strBuf
);
3966 #ifdef NUMFMTST_CACHE_DEBUG
3973 NumberFormatTest::TestParseCurrencyInUCurr() {
3974 const char* DATA
[] = {
3975 "1.00 US DOLLAR", // case in-sensitive
3978 "usd1.00", // case in-sensitive: #13696
4013 "Afghan Afghani (1927\\u20132002)1.00",
4014 "Afghan afghani (1927\\u20132002)1.00",
4015 "Afghan Afghani1.00",
4016 "Afghan Afghanis1.00",
4019 "Albanian lek\\u00eb1.00",
4020 "Algerian Dinar1.00",
4021 "Algerian dinar1.00",
4022 "Algerian dinars1.00",
4023 "Andorran Peseta1.00",
4024 "Andorran peseta1.00",
4025 "Andorran pesetas1.00",
4026 "Angolan Kwanza (1977\\u20131991)1.00",
4027 "Angolan Readjusted Kwanza (1995\\u20131999)1.00",
4028 "Angolan Kwanza1.00",
4029 "Angolan New Kwanza (1990\\u20132000)1.00",
4030 "Angolan kwanza (1977\\u20131991)1.00",
4031 "Angolan readjusted kwanza (1995\\u20131999)1.00",
4032 "Angolan kwanza1.00",
4033 "Angolan kwanzas (1977\\u20131991)1.00",
4034 "Angolan readjusted kwanzas (1995\\u20131999)1.00",
4035 "Angolan kwanzas1.00",
4036 "Angolan new kwanza (1990\\u20132000)1.00",
4037 "Angolan new kwanzas (1990\\u20132000)1.00",
4038 "Argentine Austral1.00",
4039 "Argentine Peso (1983\\u20131985)1.00",
4040 "Argentine Peso1.00",
4041 "Argentine austral1.00",
4042 "Argentine australs1.00",
4043 "Argentine peso (1983\\u20131985)1.00",
4044 "Argentine peso1.00",
4045 "Argentine pesos (1983\\u20131985)1.00",
4046 "Argentine pesos1.00",
4047 "Armenian Dram1.00",
4048 "Armenian dram1.00",
4049 "Armenian drams1.00",
4050 "Aruban Florin1.00",
4051 "Aruban florin1.00",
4052 "Australian Dollar1.00",
4053 "Australian dollar1.00",
4054 "Australian dollars1.00",
4055 "Austrian Schilling1.00",
4056 "Austrian schilling1.00",
4057 "Austrian schillings1.00",
4058 "Azerbaijani Manat (1993\\u20132006)1.00",
4059 "Azerbaijani Manat1.00",
4060 "Azerbaijani manat (1993\\u20132006)1.00",
4061 "Azerbaijani manat1.00",
4062 "Azerbaijani manats (1993\\u20132006)1.00",
4063 "Azerbaijani manats1.00",
4107 "Bahamian Dollar1.00",
4108 "Bahamian dollar1.00",
4109 "Bahamian dollars1.00",
4110 "Bahraini Dinar1.00",
4111 "Bahraini dinar1.00",
4112 "Bahraini dinars1.00",
4113 "Bangladeshi Taka1.00",
4114 "Bangladeshi taka1.00",
4115 "Bangladeshi takas1.00",
4116 "Barbadian Dollar1.00",
4117 "Barbadian dollar1.00",
4118 "Barbadian dollars1.00",
4119 "Belarusian Ruble (1994\\u20131999)1.00",
4120 "Belarusian Ruble1.00",
4121 "Belarusian ruble (1994\\u20131999)1.00",
4122 "Belarusian rubles (1994\\u20131999)1.00",
4123 "Belarusian ruble1.00",
4124 "Belarusian rubles1.00",
4125 "Belgian Franc (convertible)1.00",
4126 "Belgian Franc (financial)1.00",
4127 "Belgian Franc1.00",
4128 "Belgian franc (convertible)1.00",
4129 "Belgian franc (financial)1.00",
4130 "Belgian franc1.00",
4131 "Belgian francs (convertible)1.00",
4132 "Belgian francs (financial)1.00",
4133 "Belgian francs1.00",
4134 "Belize Dollar1.00",
4135 "Belize dollar1.00",
4136 "Belize dollars1.00",
4137 "Bermudan Dollar1.00",
4138 "Bermudan dollar1.00",
4139 "Bermudan dollars1.00",
4140 "Bhutanese Ngultrum1.00",
4141 "Bhutanese ngultrum1.00",
4142 "Bhutanese ngultrums1.00",
4143 "Bolivian Mvdol1.00",
4144 "Bolivian Peso1.00",
4145 "Bolivian mvdol1.00",
4146 "Bolivian mvdols1.00",
4147 "Bolivian peso1.00",
4148 "Bolivian pesos1.00",
4149 "Bolivian Boliviano1.00",
4150 "Bolivian Boliviano1.00",
4151 "Bolivian Bolivianos1.00",
4152 "Bosnia-Herzegovina Convertible Mark1.00",
4153 "Bosnia-Herzegovina Dinar (1992\\u20131994)1.00",
4154 "Bosnia-Herzegovina convertible mark1.00",
4155 "Bosnia-Herzegovina convertible marks1.00",
4156 "Bosnia-Herzegovina dinar (1992\\u20131994)1.00",
4157 "Bosnia-Herzegovina dinars (1992\\u20131994)1.00",
4158 "Botswanan Pula1.00",
4159 "Botswanan pula1.00",
4160 "Botswanan pulas1.00",
4161 "Brazilian New Cruzado (1989\\u20131990)1.00",
4162 "Brazilian Cruzado (1986\\u20131989)1.00",
4163 "Brazilian Cruzeiro (1990\\u20131993)1.00",
4164 "Brazilian New Cruzeiro (1967\\u20131986)1.00",
4165 "Brazilian Cruzeiro (1993\\u20131994)1.00",
4166 "Brazilian Real1.00",
4167 "Brazilian new cruzado (1989\\u20131990)1.00",
4168 "Brazilian new cruzados (1989\\u20131990)1.00",
4169 "Brazilian cruzado (1986\\u20131989)1.00",
4170 "Brazilian cruzados (1986\\u20131989)1.00",
4171 "Brazilian cruzeiro (1990\\u20131993)1.00",
4172 "Brazilian new cruzeiro (1967\\u20131986)1.00",
4173 "Brazilian cruzeiro (1993\\u20131994)1.00",
4174 "Brazilian cruzeiros (1990\\u20131993)1.00",
4175 "Brazilian new cruzeiros (1967\\u20131986)1.00",
4176 "Brazilian cruzeiros (1993\\u20131994)1.00",
4177 "Brazilian real1.00",
4178 "Brazilian reals1.00",
4179 "British Pound1.00",
4180 "British pound1.00",
4181 "British pounds1.00",
4182 "Brunei Dollar1.00",
4183 "Brunei dollar1.00",
4184 "Brunei dollars1.00",
4185 "Bulgarian Hard Lev1.00",
4186 "Bulgarian Lev1.00",
4187 "Bulgarian Leva1.00",
4188 "Bulgarian hard lev1.00",
4189 "Bulgarian hard leva1.00",
4190 "Bulgarian lev1.00",
4193 "Burmese kyats1.00",
4194 "Burundian Franc1.00",
4195 "Burundian franc1.00",
4196 "Burundian francs1.00",
4201 "West African CFA Franc1.00",
4202 "Central African CFA Franc1.00",
4203 "West African CFA franc1.00",
4204 "Central African CFA franc1.00",
4205 "West African CFA francs1.00",
4206 "Central African CFA francs1.00",
4233 "Cambodian Riel1.00",
4234 "Cambodian riel1.00",
4235 "Cambodian riels1.00",
4236 "Canadian Dollar1.00",
4237 "Canadian dollar1.00",
4238 "Canadian dollars1.00",
4239 "Cape Verdean Escudo1.00",
4240 "Cape Verdean escudo1.00",
4241 "Cape Verdean escudos1.00",
4242 "Cayman Islands Dollar1.00",
4243 "Cayman Islands dollar1.00",
4244 "Cayman Islands dollars1.00",
4246 "Chilean Unit of Account (UF)1.00",
4248 "Chilean pesos1.00",
4249 "Chilean unit of account (UF)1.00",
4250 "Chilean units of account (UF)1.00",
4253 "Colombian Peso1.00",
4254 "Colombian peso1.00",
4255 "Colombian pesos1.00",
4256 "Comorian Franc1.00",
4257 "Comorian franc1.00",
4258 "Comorian francs1.00",
4259 "Congolese Franc1.00",
4260 "Congolese franc1.00",
4261 "Congolese francs1.00",
4262 "Costa Rican Col\\u00f3n1.00",
4263 "Costa Rican col\\u00f3n1.00",
4264 "Costa Rican col\\u00f3ns1.00",
4265 "Croatian Dinar1.00",
4266 "Croatian Kuna1.00",
4267 "Croatian dinar1.00",
4268 "Croatian dinars1.00",
4269 "Croatian kuna1.00",
4270 "Croatian kunas1.00",
4274 "Cypriot Pound1.00",
4275 "Cypriot pound1.00",
4276 "Cypriot pounds1.00",
4279 "Czech korunas1.00",
4280 "Czechoslovak Hard Koruna1.00",
4281 "Czechoslovak hard koruna1.00",
4282 "Czechoslovak hard korunas1.00",
4293 "Danish kroner1.00",
4297 "Djiboutian Franc1.00",
4298 "Djiboutian franc1.00",
4299 "Djiboutian francs1.00",
4300 "Dominican Peso1.00",
4301 "Dominican peso1.00",
4302 "Dominican pesos1.00",
4321 "East Caribbean Dollar1.00",
4322 "East Caribbean dollar1.00",
4323 "East Caribbean dollars1.00",
4324 "East German Mark1.00",
4325 "East German mark1.00",
4326 "East German marks1.00",
4327 "Ecuadorian Sucre1.00",
4328 "Ecuadorian Unit of Constant Value1.00",
4329 "Ecuadorian sucre1.00",
4330 "Ecuadorian sucres1.00",
4331 "Ecuadorian unit of constant value1.00",
4332 "Ecuadorian units of constant value1.00",
4333 "Egyptian Pound1.00",
4334 "Egyptian pound1.00",
4335 "Egyptian pounds1.00",
4336 "Salvadoran Col\\u00f3n1.00",
4337 "Salvadoran col\\u00f3n1.00",
4338 "Salvadoran colones1.00",
4339 "Equatorial Guinean Ekwele1.00",
4340 "Equatorial Guinean ekwele1.00",
4341 "Eritrean Nakfa1.00",
4342 "Eritrean nakfa1.00",
4343 "Eritrean nakfas1.00",
4344 "Estonian Kroon1.00",
4345 "Estonian kroon1.00",
4346 "Estonian kroons1.00",
4347 "Ethiopian Birr1.00",
4348 "Ethiopian birr1.00",
4349 "Ethiopian birrs1.00",
4351 "European Composite Unit1.00",
4352 "European Currency Unit1.00",
4353 "European Monetary Unit1.00",
4354 "European Unit of Account (XBC)1.00",
4355 "European Unit of Account (XBD)1.00",
4356 "European composite unit1.00",
4357 "European composite units1.00",
4358 "European currency unit1.00",
4359 "European currency units1.00",
4360 "European monetary unit1.00",
4361 "European monetary units1.00",
4362 "European unit of account (XBC)1.00",
4363 "European unit of account (XBD)1.00",
4364 "European units of account (XBC)1.00",
4365 "European units of account (XBD)1.00",
4373 "Falkland Islands Pound1.00",
4374 "Falkland Islands pound1.00",
4375 "Falkland Islands pounds1.00",
4376 "Fijian Dollar1.00",
4377 "Fijian dollar1.00",
4378 "Fijian dollars1.00",
4379 "Finnish Markka1.00",
4380 "Finnish markka1.00",
4381 "Finnish markkas1.00",
4384 "French Gold Franc1.00",
4385 "French UIC-Franc1.00",
4386 "French UIC-franc1.00",
4387 "French UIC-francs1.00",
4389 "French francs1.00",
4390 "French gold franc1.00",
4391 "French gold francs1.00",
4416 "Gambian Dalasi1.00",
4417 "Gambian dalasi1.00",
4418 "Gambian dalasis1.00",
4419 "Georgian Kupon Larit1.00",
4420 "Georgian Lari1.00",
4421 "Georgian kupon larit1.00",
4422 "Georgian kupon larits1.00",
4423 "Georgian lari1.00",
4424 "Georgian laris1.00",
4425 "Ghanaian Cedi (1979\\u20132007)1.00",
4426 "Ghanaian Cedi1.00",
4427 "Ghanaian cedi (1979\\u20132007)1.00",
4428 "Ghanaian cedi1.00",
4429 "Ghanaian cedis (1979\\u20132007)1.00",
4430 "Ghanaian cedis1.00",
4431 "Gibraltar Pound1.00",
4432 "Gibraltar pound1.00",
4433 "Gibraltar pounds1.00",
4436 "Greek Drachma1.00",
4437 "Greek drachma1.00",
4438 "Greek drachmas1.00",
4439 "Guatemalan Quetzal1.00",
4440 "Guatemalan quetzal1.00",
4441 "Guatemalan quetzals1.00",
4442 "Guinean Franc1.00",
4444 "Guinean franc1.00",
4445 "Guinean francs1.00",
4447 "Guinean sylis1.00",
4448 "Guinea-Bissau Peso1.00",
4449 "Guinea-Bissau peso1.00",
4450 "Guinea-Bissau pesos1.00",
4451 "Guyanaese Dollar1.00",
4452 "Guyanaese dollar1.00",
4453 "Guyanaese dollars1.00",
4464 "Haitian Gourde1.00",
4465 "Haitian gourde1.00",
4466 "Haitian gourdes1.00",
4467 "Honduran Lempira1.00",
4468 "Honduran lempira1.00",
4469 "Honduran lempiras1.00",
4470 "Hong Kong Dollar1.00",
4471 "Hong Kong dollar1.00",
4472 "Hong Kong dollars1.00",
4473 "Hungarian Forint1.00",
4474 "Hungarian forint1.00",
4475 "Hungarian forints1.00",
4487 "Icelandic Kr\\u00f3na1.00",
4488 "Icelandic kr\\u00f3na1.00",
4489 "Icelandic kr\\u00f3nur1.00",
4492 "Indian rupees1.00",
4493 "Indonesian Rupiah1.00",
4494 "Indonesian rupiah1.00",
4495 "Indonesian rupiahs1.00",
4498 "Iranian rials1.00",
4505 "Israeli Pound1.00",
4506 "Israeli new shekel1.00",
4507 "Israeli pound1.00",
4508 "Israeli pounds1.00",
4511 "Italian liras1.00",
4515 "Jamaican Dollar1.00",
4516 "Jamaican dollar1.00",
4517 "Jamaican dollars1.00",
4520 "Jordanian Dinar1.00",
4521 "Jordanian dinar1.00",
4522 "Jordanian dinars1.00",
4534 "Kazakhstani Tenge1.00",
4535 "Kazakhstani tenge1.00",
4536 "Kazakhstani tenges1.00",
4537 "Kenyan Shilling1.00",
4538 "Kenyan shilling1.00",
4539 "Kenyan shillings1.00",
4540 "Kuwaiti Dinar1.00",
4541 "Kuwaiti dinar1.00",
4542 "Kuwaiti dinars1.00",
4543 "Kyrgystani Som1.00",
4544 "Kyrgystani som1.00",
4545 "Kyrgystani soms1.00",
4573 "Latvian Ruble1.00",
4576 "Latvian ruble1.00",
4577 "Latvian rubles1.00",
4578 "Lebanese Pound1.00",
4579 "Lebanese pound1.00",
4580 "Lebanese pounds1.00",
4583 "Lesotho lotis1.00",
4584 "Liberian Dollar1.00",
4585 "Liberian dollar1.00",
4586 "Liberian dollars1.00",
4589 "Libyan dinars1.00",
4590 "Lithuanian Litas1.00",
4591 "Lithuanian Talonas1.00",
4592 "Lithuanian litas1.00",
4593 "Lithuanian litai1.00",
4594 "Lithuanian talonas1.00",
4595 "Lithuanian talonases1.00",
4596 "Luxembourgian Convertible Franc1.00",
4597 "Luxembourg Financial Franc1.00",
4598 "Luxembourgian Franc1.00",
4599 "Luxembourgian convertible franc1.00",
4600 "Luxembourgian convertible francs1.00",
4601 "Luxembourg financial franc1.00",
4602 "Luxembourg financial francs1.00",
4603 "Luxembourgian franc1.00",
4604 "Luxembourgian francs1.00",
4643 "Macanese Pataca1.00",
4644 "Macanese pataca1.00",
4645 "Macanese patacas1.00",
4646 "Macedonian Denar1.00",
4647 "Macedonian denar1.00",
4648 "Macedonian denari1.00",
4649 "Malagasy Ariaries1.00",
4650 "Malagasy Ariary1.00",
4651 "Malagasy Ariary1.00",
4652 "Malagasy Franc1.00",
4653 "Malagasy franc1.00",
4654 "Malagasy francs1.00",
4655 "Malawian Kwacha1.00",
4656 "Malawian Kwacha1.00",
4657 "Malawian Kwachas1.00",
4658 "Malaysian Ringgit1.00",
4659 "Malaysian ringgit1.00",
4660 "Malaysian ringgits1.00",
4661 "Maldivian Rufiyaa1.00",
4662 "Maldivian rufiyaa1.00",
4663 "Maldivian rufiyaas1.00",
4666 "Malian francs1.00",
4668 "Maltese Pound1.00",
4671 "Maltese pound1.00",
4672 "Maltese pounds1.00",
4673 "Mauritanian Ouguiya1.00",
4674 "Mauritanian ouguiya1.00",
4675 "Mauritanian ouguiyas1.00",
4676 "Mauritian Rupee1.00",
4677 "Mauritian rupee1.00",
4678 "Mauritian rupees1.00",
4680 "Mexican Silver Peso (1861\\u20131992)1.00",
4681 "Mexican Investment Unit1.00",
4683 "Mexican pesos1.00",
4684 "Mexican silver peso (1861\\u20131992)1.00",
4685 "Mexican silver pesos (1861\\u20131992)1.00",
4686 "Mexican investment unit1.00",
4687 "Mexican investment units1.00",
4691 "Mongolian Tugrik1.00",
4692 "Mongolian tugrik1.00",
4693 "Mongolian tugriks1.00",
4694 "Moroccan Dirham1.00",
4695 "Moroccan Franc1.00",
4696 "Moroccan dirham1.00",
4697 "Moroccan dirhams1.00",
4698 "Moroccan franc1.00",
4699 "Moroccan francs1.00",
4700 "Mozambican Escudo1.00",
4701 "Mozambican Metical1.00",
4702 "Mozambican escudo1.00",
4703 "Mozambican escudos1.00",
4704 "Mozambican metical1.00",
4705 "Mozambican meticals1.00",
4708 "Myanmar kyats1.00",
4721 "Namibian Dollar1.00",
4722 "Namibian dollar1.00",
4723 "Namibian dollars1.00",
4724 "Nepalese Rupee1.00",
4725 "Nepalese rupee1.00",
4726 "Nepalese rupees1.00",
4727 "Netherlands Antillean Guilder1.00",
4728 "Netherlands Antillean guilder1.00",
4729 "Netherlands Antillean guilders1.00",
4730 "Dutch Guilder1.00",
4731 "Dutch guilder1.00",
4732 "Dutch guilders1.00",
4733 "Israeli New Shekel1.00",
4734 "Israeli New Shekels1.00",
4735 "New Zealand Dollar1.00",
4736 "New Zealand dollar1.00",
4737 "New Zealand dollars1.00",
4738 "Nicaraguan C\\u00f3rdoba1.00",
4739 "Nicaraguan C\\u00f3rdoba (1988\\u20131991)1.00",
4740 "Nicaraguan c\\u00f3rdoba1.00",
4741 "Nicaraguan c\\u00f3rdobas1.00",
4742 "Nicaraguan c\\u00f3rdoba (1988\\u20131991)1.00",
4743 "Nicaraguan c\\u00f3rdobas (1988\\u20131991)1.00",
4744 "Nigerian Naira1.00",
4745 "Nigerian naira1.00",
4746 "Nigerian nairas1.00",
4747 "North Korean Won1.00",
4748 "North Korean won1.00",
4749 "North Korean won1.00",
4750 "Norwegian Krone1.00",
4751 "Norwegian krone1.00",
4752 "Norwegian kroner1.00",
4754 "Mozambican Metical (1980\\u20132006)1.00",
4755 "Mozambican metical (1980\\u20132006)1.00",
4756 "Mozambican meticals (1980\\u20132006)1.00",
4757 "Romanian Lei (1952\\u20132006)1.00",
4758 "Romanian Leu (1952\\u20132006)1.00",
4759 "Romanian leu (1952\\u20132006)1.00",
4760 "Serbian Dinar (2002\\u20132006)1.00",
4761 "Serbian dinar (2002\\u20132006)1.00",
4762 "Serbian dinars (2002\\u20132006)1.00",
4763 "Sudanese Dinar (1992\\u20132007)1.00",
4764 "Sudanese Pound (1957\\u20131998)1.00",
4765 "Sudanese dinar (1992\\u20132007)1.00",
4766 "Sudanese dinars (1992\\u20132007)1.00",
4767 "Sudanese pound (1957\\u20131998)1.00",
4768 "Sudanese pounds (1957\\u20131998)1.00",
4769 "Turkish Lira (1922\\u20132005)1.00",
4770 "Turkish Lira (1922\\u20132005)1.00",
4792 "Pakistani Rupee1.00",
4793 "Pakistani rupee1.00",
4794 "Pakistani rupees1.00",
4797 "Panamanian Balboa1.00",
4798 "Panamanian balboa1.00",
4799 "Panamanian balboas1.00",
4800 "Papua New Guinean Kina1.00",
4801 "Papua New Guinean kina1.00",
4802 "Papua New Guinean kina1.00",
4803 "Paraguayan Guarani1.00",
4804 "Paraguayan guarani1.00",
4805 "Paraguayan guaranis1.00",
4806 "Peruvian Inti1.00",
4808 "Peruvian Sol (1863\\u20131965)1.00",
4809 "Peruvian inti1.00",
4810 "Peruvian intis1.00",
4812 "Peruvian soles1.00",
4813 "Peruvian sol (1863\\u20131965)1.00",
4814 "Peruvian soles (1863\\u20131965)1.00",
4815 "Philippine Piso1.00",
4816 "Philippine piso1.00",
4817 "Philippine pisos1.00",
4820 "Polish Zloty (1950\\u20131995)1.00",
4822 "Polish zlotys1.00",
4823 "Polish zloty (PLZ)1.00",
4825 "Polish zlotys (PLZ)1.00",
4826 "Portuguese Escudo1.00",
4827 "Portuguese Guinea Escudo1.00",
4828 "Portuguese Guinea escudo1.00",
4829 "Portuguese Guinea escudos1.00",
4830 "Portuguese escudo1.00",
4831 "Portuguese escudos1.00",
4853 "Rhodesian Dollar1.00",
4854 "Rhodesian dollar1.00",
4855 "Rhodesian dollars1.00",
4859 "Russian Ruble (1991\\u20131998)1.00",
4860 "Russian Ruble1.00",
4861 "Russian ruble (1991\\u20131998)1.00",
4862 "Russian ruble1.00",
4863 "Russian rubles (1991\\u20131998)1.00",
4864 "Russian rubles1.00",
4865 "Rwandan Franc1.00",
4866 "Rwandan franc1.00",
4867 "Rwandan francs1.00",
4897 "St. Helena Pound1.00",
4898 "St. Helena pound1.00",
4899 "St. Helena pounds1.00",
4900 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobra1.00",
4901 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobra1.00",
4902 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobras1.00",
4906 "Serbian Dinar1.00",
4907 "Serbian dinar1.00",
4908 "Serbian dinars1.00",
4909 "Seychellois Rupee1.00",
4910 "Seychellois rupee1.00",
4911 "Seychellois rupees1.00",
4912 "Sierra Leonean Leone1.00",
4913 "Sierra Leonean leone1.00",
4914 "Sierra Leonean leones1.00",
4917 "Singapore Dollar1.00",
4918 "Singapore dollar1.00",
4919 "Singapore dollars1.00",
4920 "Slovak Koruna1.00",
4921 "Slovak koruna1.00",
4922 "Slovak korunas1.00",
4923 "Slovenian Tolar1.00",
4924 "Slovenian tolar1.00",
4925 "Slovenian tolars1.00",
4926 "Solomon Islands Dollar1.00",
4927 "Solomon Islands dollar1.00",
4928 "Solomon Islands dollars1.00",
4929 "Somali Shilling1.00",
4930 "Somali shilling1.00",
4931 "Somali shillings1.00",
4932 "South African Rand (financial)1.00",
4933 "South African Rand1.00",
4934 "South African rand (financial)1.00",
4935 "South African rand1.00",
4936 "South African rands (financial)1.00",
4937 "South African rand1.00",
4938 "South Korean Won1.00",
4939 "South Korean won1.00",
4940 "South Korean won1.00",
4941 "Soviet Rouble1.00",
4942 "Soviet rouble1.00",
4943 "Soviet roubles1.00",
4944 "Spanish Peseta (A account)1.00",
4945 "Spanish Peseta (convertible account)1.00",
4946 "Spanish Peseta1.00",
4947 "Spanish peseta (A account)1.00",
4948 "Spanish peseta (convertible account)1.00",
4949 "Spanish peseta1.00",
4950 "Spanish pesetas (A account)1.00",
4951 "Spanish pesetas (convertible account)1.00",
4952 "Spanish pesetas1.00",
4953 "Special Drawing Rights1.00",
4954 "Sri Lankan Rupee1.00",
4955 "Sri Lankan rupee1.00",
4956 "Sri Lankan rupees1.00",
4957 "Sudanese Pound1.00",
4958 "Sudanese pound1.00",
4959 "Sudanese pounds1.00",
4960 "Surinamese Dollar1.00",
4961 "Surinamese dollar1.00",
4962 "Surinamese dollars1.00",
4963 "Surinamese Guilder1.00",
4964 "Surinamese guilder1.00",
4965 "Surinamese guilders1.00",
4966 "Swazi Lilangeni1.00",
4967 "Swazi lilangeni1.00",
4968 "Swazi emalangeni1.00",
4969 "Swedish Krona1.00",
4970 "Swedish krona1.00",
4971 "Swedish kronor1.00",
4977 "Syrian pounds1.00",
4996 "New Taiwan Dollar1.00",
4997 "New Taiwan dollar1.00",
4998 "New Taiwan dollars1.00",
4999 "Tajikistani Ruble1.00",
5000 "Tajikistani Somoni1.00",
5001 "Tajikistani ruble1.00",
5002 "Tajikistani rubles1.00",
5003 "Tajikistani somoni1.00",
5004 "Tajikistani somonis1.00",
5005 "Tanzanian Shilling1.00",
5006 "Tanzanian shilling1.00",
5007 "Tanzanian shillings1.00",
5008 "Testing Currency Code1.00",
5009 "Testing Currency Code1.00",
5013 "Timorese Escudo1.00",
5014 "Timorese escudo1.00",
5015 "Timorese escudos1.00",
5016 "Tongan Pa\\u02bbanga1.00",
5017 "Tongan pa\\u02bbanga1.00",
5018 "Tongan pa\\u02bbanga1.00",
5019 "Trinidad & Tobago Dollar1.00",
5020 "Trinidad & Tobago dollar1.00",
5021 "Trinidad & Tobago dollars1.00",
5022 "Tunisian Dinar1.00",
5023 "Tunisian dinar1.00",
5024 "Tunisian dinars1.00",
5028 "Turkmenistani Manat1.00",
5029 "Turkmenistani manat1.00",
5030 "Turkmenistani manat1.00",
5039 "US Dollar (Next day)1.00",
5040 "US Dollar (Same day)1.00",
5042 "US dollar (next day)1.00",
5043 "US dollar (same day)1.00",
5045 "US dollars (next day)1.00",
5046 "US dollars (same day)1.00",
5060 "Ugandan Shilling (1966\\u20131987)1.00",
5061 "Ugandan Shilling1.00",
5062 "Ugandan shilling (1966\\u20131987)1.00",
5063 "Ugandan shilling1.00",
5064 "Ugandan shillings (1966\\u20131987)1.00",
5065 "Ugandan shillings1.00",
5066 "Ukrainian Hryvnia1.00",
5067 "Ukrainian Karbovanets1.00",
5068 "Ukrainian hryvnia1.00",
5069 "Ukrainian hryvnias1.00",
5070 "Ukrainian karbovanets1.00",
5071 "Ukrainian karbovantsiv1.00",
5072 "Colombian Real Value Unit1.00",
5073 "United Arab Emirates Dirham1.00",
5074 "Unknown Currency1.00",
5075 "Uruguayan Peso (1975\\u20131993)1.00",
5076 "Uruguayan Peso1.00",
5077 "Uruguayan Peso (Indexed Units)1.00",
5078 "Uruguayan peso (1975\\u20131993)1.00",
5079 "Uruguayan peso (indexed units)1.00",
5080 "Uruguayan peso1.00",
5081 "Uruguayan pesos (1975\\u20131993)1.00",
5082 "Uruguayan pesos (indexed units)1.00",
5083 "Uruguayan pesos1.00",
5084 "Uzbekistani Som1.00",
5085 "Uzbekistani som1.00",
5086 "Uzbekistani som1.00",
5093 "Vanuatu vatus1.00",
5094 "Venezuelan Bol\\u00edvar1.00",
5095 "Venezuelan Bol\\u00edvar (1871\\u20132008)1.00",
5096 "Venezuelan bol\\u00edvar1.00",
5097 "Venezuelan bol\\u00edvars1.00",
5098 "Venezuelan bol\\u00edvar (1871\\u20132008)1.00",
5099 "Venezuelan bol\\u00edvars (1871\\u20132008)1.00",
5100 "Vietnamese Dong1.00",
5101 "Vietnamese dong1.00",
5102 "Vietnamese dong1.00",
5162 "Yemeni dinars1.00",
5165 "Yugoslavian Convertible Dinar (1990\\u20131992)1.00",
5166 "Yugoslavian Hard Dinar (1966\\u20131990)1.00",
5167 "Yugoslavian New Dinar (1994\\u20132002)1.00",
5168 "Yugoslavian convertible dinar (1990\\u20131992)1.00",
5169 "Yugoslavian convertible dinars (1990\\u20131992)1.00",
5170 "Yugoslavian hard dinar (1966\\u20131990)1.00",
5171 "Yugoslavian hard dinars (1966\\u20131990)1.00",
5172 "Yugoslavian new dinar (1994\\u20132002)1.00",
5173 "Yugoslavian new dinars (1994\\u20132002)1.00",
5184 "Zairean New Zaire (1993\\u20131998)1.00",
5185 "Zairean Zaire (1971\\u20131993)1.00",
5186 "Zairean new zaire (1993\\u20131998)1.00",
5187 "Zairean new zaires (1993\\u20131998)1.00",
5188 "Zairean zaire (1971\\u20131993)1.00",
5189 "Zairean zaires (1971\\u20131993)1.00",
5190 "Zambian Kwacha1.00",
5191 "Zambian kwacha1.00",
5192 "Zambian kwachas1.00",
5193 "Zimbabwean Dollar (1980\\u20132008)1.00",
5194 "Zimbabwean dollar (1980\\u20132008)1.00",
5195 "Zimbabwean dollars (1980\\u20132008)1.00",
5198 "Turkish lira (1922\\u20132005)1.00",
5199 "special drawing rights1.00",
5200 "Colombian real value unit1.00",
5201 "Colombian real value units1.00",
5202 "unknown currency1.00",
5210 // Following has extra text, should be parsed correctly too
5213 "1.00 US dollar random",
5214 "1.00 US dollars random",
5215 "1.00 Afghan Afghani random",
5216 "1.00 Afghan Afghani random",
5217 "1.00 Afghan Afghanis (1927\\u20131992) random",
5218 "1.00 Afghan Afghanis random",
5219 "1.00 Albanian Lek random",
5220 "1.00 Albanian lek random",
5221 "1.00 Albanian lek\\u00eb random",
5222 "1.00 Algerian Dinar random",
5223 "1.00 Algerian dinar random",
5224 "1.00 Algerian dinars random",
5225 "1.00 Andorran Peseta random",
5226 "1.00 Andorran peseta random",
5227 "1.00 Andorran pesetas random",
5228 "1.00 Angolan Kwanza (1977\\u20131990) random",
5229 "1.00 Angolan Readjusted Kwanza (1995\\u20131999) random",
5230 "1.00 Angolan Kwanza random",
5231 "1.00 Angolan New Kwanza (1990\\u20132000) random",
5232 "1.00 Angolan kwanza (1977\\u20131991) random",
5233 "1.00 Angolan readjusted kwanza (1995\\u20131999) random",
5234 "1.00 Angolan kwanza random",
5235 "1.00 Angolan kwanzas (1977\\u20131991) random",
5236 "1.00 Angolan readjusted kwanzas (1995\\u20131999) random",
5237 "1.00 Angolan kwanzas random",
5238 "1.00 Angolan new kwanza (1990\\u20132000) random",
5239 "1.00 Angolan new kwanzas (1990\\u20132000) random",
5240 "1.00 Argentine Austral random",
5241 "1.00 Argentine Peso (1983\\u20131985) random",
5242 "1.00 Argentine Peso random",
5243 "1.00 Argentine austral random",
5244 "1.00 Argentine australs random",
5245 "1.00 Argentine peso (1983\\u20131985) random",
5246 "1.00 Argentine peso random",
5247 "1.00 Argentine pesos (1983\\u20131985) random",
5248 "1.00 Argentine pesos random",
5249 "1.00 Armenian Dram random",
5250 "1.00 Armenian dram random",
5251 "1.00 Armenian drams random",
5252 "1.00 Aruban Florin random",
5253 "1.00 Aruban florin random",
5254 "1.00 Australian Dollar random",
5255 "1.00 Australian dollar random",
5256 "1.00 Australian dollars random",
5257 "1.00 Austrian Schilling random",
5258 "1.00 Austrian schilling random",
5259 "1.00 Austrian schillings random",
5260 "1.00 Azerbaijani Manat (1993\\u20132006) random",
5261 "1.00 Azerbaijani Manat random",
5262 "1.00 Azerbaijani manat (1993\\u20132006) random",
5263 "1.00 Azerbaijani manat random",
5264 "1.00 Azerbaijani manats (1993\\u20132006) random",
5265 "1.00 Azerbaijani manats random",
5266 "1.00 Bahamian Dollar random",
5267 "1.00 Bahamian dollar random",
5268 "1.00 Bahamian dollars random",
5269 "1.00 Bahraini Dinar random",
5270 "1.00 Bahraini dinar random",
5271 "1.00 Bahraini dinars random",
5272 "1.00 Bangladeshi Taka random",
5273 "1.00 Bangladeshi taka random",
5274 "1.00 Bangladeshi takas random",
5275 "1.00 Barbadian Dollar random",
5276 "1.00 Barbadian dollar random",
5277 "1.00 Barbadian dollars random",
5278 "1.00 Belarusian Ruble (1994\\u20131999) random",
5279 "1.00 Belarusian Ruble random",
5280 "1.00 Belarusian ruble (1994\\u20131999) random",
5281 "1.00 Belarusian rubles (1994\\u20131999) random",
5282 "1.00 Belarusian ruble random",
5283 "1.00 Belarusian rubles random",
5284 "1.00 Belgian Franc (convertible) random",
5285 "1.00 Belgian Franc (financial) random",
5286 "1.00 Belgian Franc random",
5287 "1.00 Belgian franc (convertible) random",
5288 "1.00 Belgian franc (financial) random",
5289 "1.00 Belgian franc random",
5290 "1.00 Belgian francs (convertible) random",
5291 "1.00 Belgian francs (financial) random",
5292 "1.00 Belgian francs random",
5293 "1.00 Belize Dollar random",
5294 "1.00 Belize dollar random",
5295 "1.00 Belize dollars random",
5296 "1.00 Bermudan Dollar random",
5297 "1.00 Bermudan dollar random",
5298 "1.00 Bermudan dollars random",
5299 "1.00 Bhutanese Ngultrum random",
5300 "1.00 Bhutanese ngultrum random",
5301 "1.00 Bhutanese ngultrums random",
5302 "1.00 Bolivian Mvdol random",
5303 "1.00 Bolivian Peso random",
5304 "1.00 Bolivian mvdol random",
5305 "1.00 Bolivian mvdols random",
5306 "1.00 Bolivian peso random",
5307 "1.00 Bolivian pesos random",
5308 "1.00 Bolivian Boliviano random",
5309 "1.00 Bolivian Boliviano random",
5310 "1.00 Bolivian Bolivianos random",
5311 "1.00 Bosnia-Herzegovina Convertible Mark random",
5312 "1.00 Bosnia-Herzegovina Dinar (1992\\u20131994) random",
5313 "1.00 Bosnia-Herzegovina convertible mark random",
5314 "1.00 Bosnia-Herzegovina convertible marks random",
5315 "1.00 Bosnia-Herzegovina dinar (1992\\u20131994) random",
5316 "1.00 Bosnia-Herzegovina dinars (1992\\u20131994) random",
5317 "1.00 Botswanan Pula random",
5318 "1.00 Botswanan pula random",
5319 "1.00 Botswanan pulas random",
5320 "1.00 Brazilian New Cruzado (1989\\u20131990) random",
5321 "1.00 Brazilian Cruzado (1986\\u20131989) random",
5322 "1.00 Brazilian Cruzeiro (1990\\u20131993) random",
5323 "1.00 Brazilian New Cruzeiro (1967\\u20131986) random",
5324 "1.00 Brazilian Cruzeiro (1993\\u20131994) random",
5325 "1.00 Brazilian Real random",
5326 "1.00 Brazilian new cruzado (1989\\u20131990) random",
5327 "1.00 Brazilian new cruzados (1989\\u20131990) random",
5328 "1.00 Brazilian cruzado (1986\\u20131989) random",
5329 "1.00 Brazilian cruzados (1986\\u20131989) random",
5330 "1.00 Brazilian cruzeiro (1990\\u20131993) random",
5331 "1.00 Brazilian new cruzeiro (1967\\u20131986) random",
5332 "1.00 Brazilian cruzeiro (1993\\u20131994) random",
5333 "1.00 Brazilian cruzeiros (1990\\u20131993) random",
5334 "1.00 Brazilian new cruzeiros (1967\\u20131986) random",
5335 "1.00 Brazilian cruzeiros (1993\\u20131994) random",
5336 "1.00 Brazilian real random",
5337 "1.00 Brazilian reals random",
5338 "1.00 British Pound random",
5339 "1.00 British pound random",
5340 "1.00 British pounds random",
5341 "1.00 Brunei Dollar random",
5342 "1.00 Brunei dollar random",
5343 "1.00 Brunei dollars random",
5344 "1.00 Bulgarian Hard Lev random",
5345 "1.00 Bulgarian Lev random",
5346 "1.00 Bulgarian Leva random",
5347 "1.00 Bulgarian hard lev random",
5348 "1.00 Bulgarian hard leva random",
5349 "1.00 Bulgarian lev random",
5350 "1.00 Burmese Kyat random",
5351 "1.00 Burmese kyat random",
5352 "1.00 Burmese kyats random",
5353 "1.00 Burundian Franc random",
5354 "1.00 Burundian franc random",
5355 "1.00 Burundian francs random",
5356 "1.00 Cambodian Riel random",
5357 "1.00 Cambodian riel random",
5358 "1.00 Cambodian riels random",
5359 "1.00 Canadian Dollar random",
5360 "1.00 Canadian dollar random",
5361 "1.00 Canadian dollars random",
5362 "1.00 Cape Verdean Escudo random",
5363 "1.00 Cape Verdean escudo random",
5364 "1.00 Cape Verdean escudos random",
5365 "1.00 Cayman Islands Dollar random",
5366 "1.00 Cayman Islands dollar random",
5367 "1.00 Cayman Islands dollars random",
5368 "1.00 Chilean Peso random",
5369 "1.00 Chilean Unit of Account (UF) random",
5370 "1.00 Chilean peso random",
5371 "1.00 Chilean pesos random",
5372 "1.00 Chilean unit of account (UF) random",
5373 "1.00 Chilean units of account (UF) random",
5374 "1.00 Chinese Yuan random",
5375 "1.00 Chinese yuan random",
5376 "1.00 Colombian Peso random",
5377 "1.00 Colombian peso random",
5378 "1.00 Colombian pesos random",
5379 "1.00 Comorian Franc random",
5380 "1.00 Comorian franc random",
5381 "1.00 Comorian francs random",
5382 "1.00 Congolese Franc Congolais random",
5383 "1.00 Congolese franc Congolais random",
5384 "1.00 Congolese francs Congolais random",
5385 "1.00 Costa Rican Col\\u00f3n random",
5386 "1.00 Costa Rican col\\u00f3n random",
5387 "1.00 Costa Rican col\\u00f3ns random",
5388 "1.00 Croatian Dinar random",
5389 "1.00 Croatian Kuna random",
5390 "1.00 Croatian dinar random",
5391 "1.00 Croatian dinars random",
5392 "1.00 Croatian kuna random",
5393 "1.00 Croatian kunas random",
5394 "1.00 Cuban Peso random",
5395 "1.00 Cuban peso random",
5396 "1.00 Cuban pesos random",
5397 "1.00 Cypriot Pound random",
5398 "1.00 Cypriot pound random",
5399 "1.00 Cypriot pounds random",
5400 "1.00 Czech Koruna random",
5401 "1.00 Czech koruna random",
5402 "1.00 Czech korunas random",
5403 "1.00 Czechoslovak Hard Koruna random",
5404 "1.00 Czechoslovak hard koruna random",
5405 "1.00 Czechoslovak hard korunas random",
5406 "1.00 Danish Krone random",
5407 "1.00 Danish krone random",
5408 "1.00 Danish kroner random",
5409 "1.00 German Mark random",
5410 "1.00 German mark random",
5411 "1.00 German marks random",
5412 "1.00 Djiboutian Franc random",
5413 "1.00 Djiboutian franc random",
5414 "1.00 Djiboutian francs random",
5415 "1.00 Dominican Peso random",
5416 "1.00 Dominican peso random",
5417 "1.00 Dominican pesos random",
5418 "1.00 East Caribbean Dollar random",
5419 "1.00 East Caribbean dollar random",
5420 "1.00 East Caribbean dollars random",
5421 "1.00 East German Mark random",
5422 "1.00 East German mark random",
5423 "1.00 East German marks random",
5424 "1.00 Ecuadorian Sucre random",
5425 "1.00 Ecuadorian Unit of Constant Value random",
5426 "1.00 Ecuadorian sucre random",
5427 "1.00 Ecuadorian sucres random",
5428 "1.00 Ecuadorian unit of constant value random",
5429 "1.00 Ecuadorian units of constant value random",
5430 "1.00 Egyptian Pound random",
5431 "1.00 Egyptian pound random",
5432 "1.00 Egyptian pounds random",
5433 "1.00 Salvadoran Col\\u00f3n random",
5434 "1.00 Salvadoran col\\u00f3n random",
5435 "1.00 Salvadoran colones random",
5436 "1.00 Equatorial Guinean Ekwele random",
5437 "1.00 Equatorial Guinean ekwele random",
5438 "1.00 Eritrean Nakfa random",
5439 "1.00 Eritrean nakfa random",
5440 "1.00 Eritrean nakfas random",
5441 "1.00 Estonian Kroon random",
5442 "1.00 Estonian kroon random",
5443 "1.00 Estonian kroons random",
5444 "1.00 Ethiopian Birr random",
5445 "1.00 Ethiopian birr random",
5446 "1.00 Ethiopian birrs random",
5447 "1.00 European Composite Unit random",
5448 "1.00 European Currency Unit random",
5449 "1.00 European Monetary Unit random",
5450 "1.00 European Unit of Account (XBC) random",
5451 "1.00 European Unit of Account (XBD) random",
5452 "1.00 European composite unit random",
5453 "1.00 European composite units random",
5454 "1.00 European currency unit random",
5455 "1.00 European currency units random",
5456 "1.00 European monetary unit random",
5457 "1.00 European monetary units random",
5458 "1.00 European unit of account (XBC) random",
5459 "1.00 European unit of account (XBD) random",
5460 "1.00 European units of account (XBC) random",
5461 "1.00 European units of account (XBD) random",
5462 "1.00 Falkland Islands Pound random",
5463 "1.00 Falkland Islands pound random",
5464 "1.00 Falkland Islands pounds random",
5465 "1.00 Fijian Dollar random",
5466 "1.00 Fijian dollar random",
5467 "1.00 Fijian dollars random",
5468 "1.00 Finnish Markka random",
5469 "1.00 Finnish markka random",
5470 "1.00 Finnish markkas random",
5471 "1.00 French Franc random",
5472 "1.00 French Gold Franc random",
5473 "1.00 French UIC-Franc random",
5474 "1.00 French UIC-franc random",
5475 "1.00 French UIC-francs random",
5476 "1.00 French franc random",
5477 "1.00 French francs random",
5478 "1.00 French gold franc random",
5479 "1.00 French gold francs random",
5480 "1.00 Gambian Dalasi random",
5481 "1.00 Gambian dalasi random",
5482 "1.00 Gambian dalasis random",
5483 "1.00 Georgian Kupon Larit random",
5484 "1.00 Georgian Lari random",
5485 "1.00 Georgian kupon larit random",
5486 "1.00 Georgian kupon larits random",
5487 "1.00 Georgian lari random",
5488 "1.00 Georgian laris random",
5489 "1.00 Ghanaian Cedi (1979\\u20132007) random",
5490 "1.00 Ghanaian Cedi random",
5491 "1.00 Ghanaian cedi (1979\\u20132007) random",
5492 "1.00 Ghanaian cedi random",
5493 "1.00 Ghanaian cedis (1979\\u20132007) random",
5494 "1.00 Ghanaian cedis random",
5495 "1.00 Gibraltar Pound random",
5496 "1.00 Gibraltar pound random",
5497 "1.00 Gibraltar pounds random",
5500 "1.00 Greek Drachma random",
5501 "1.00 Greek drachma random",
5502 "1.00 Greek drachmas random",
5503 "1.00 Guatemalan Quetzal random",
5504 "1.00 Guatemalan quetzal random",
5505 "1.00 Guatemalan quetzals random",
5506 "1.00 Guinean Franc random",
5507 "1.00 Guinean Syli random",
5508 "1.00 Guinean franc random",
5509 "1.00 Guinean francs random",
5510 "1.00 Guinean syli random",
5511 "1.00 Guinean sylis random",
5512 "1.00 Guinea-Bissau Peso random",
5513 "1.00 Guinea-Bissau peso random",
5514 "1.00 Guinea-Bissau pesos random",
5515 "1.00 Guyanaese Dollar random",
5516 "1.00 Guyanaese dollar random",
5517 "1.00 Guyanaese dollars random",
5518 "1.00 Haitian Gourde random",
5519 "1.00 Haitian gourde random",
5520 "1.00 Haitian gourdes random",
5521 "1.00 Honduran Lempira random",
5522 "1.00 Honduran lempira random",
5523 "1.00 Honduran lempiras random",
5524 "1.00 Hong Kong Dollar random",
5525 "1.00 Hong Kong dollar random",
5526 "1.00 Hong Kong dollars random",
5527 "1.00 Hungarian Forint random",
5528 "1.00 Hungarian forint random",
5529 "1.00 Hungarian forints random",
5530 "1.00 Icelandic Kr\\u00f3na random",
5531 "1.00 Icelandic kr\\u00f3na random",
5532 "1.00 Icelandic kr\\u00f3nur random",
5533 "1.00 Indian Rupee random",
5534 "1.00 Indian rupee random",
5535 "1.00 Indian rupees random",
5536 "1.00 Indonesian Rupiah random",
5537 "1.00 Indonesian rupiah random",
5538 "1.00 Indonesian rupiahs random",
5539 "1.00 Iranian Rial random",
5540 "1.00 Iranian rial random",
5541 "1.00 Iranian rials random",
5542 "1.00 Iraqi Dinar random",
5543 "1.00 Iraqi dinar random",
5544 "1.00 Iraqi dinars random",
5545 "1.00 Irish Pound random",
5546 "1.00 Irish pound random",
5547 "1.00 Irish pounds random",
5548 "1.00 Israeli Pound random",
5549 "1.00 Israeli new shekel random",
5550 "1.00 Israeli pound random",
5551 "1.00 Israeli pounds random",
5552 "1.00 Italian Lira random",
5553 "1.00 Italian lira random",
5554 "1.00 Italian liras random",
5555 "1.00 Jamaican Dollar random",
5556 "1.00 Jamaican dollar random",
5557 "1.00 Jamaican dollars random",
5558 "1.00 Japanese Yen random",
5559 "1.00 Japanese yen random",
5560 "1.00 Jordanian Dinar random",
5561 "1.00 Jordanian dinar random",
5562 "1.00 Jordanian dinars random",
5563 "1.00 Kazakhstani Tenge random",
5564 "1.00 Kazakhstani tenge random",
5565 "1.00 Kazakhstani tenges random",
5566 "1.00 Kenyan Shilling random",
5567 "1.00 Kenyan shilling random",
5568 "1.00 Kenyan shillings random",
5569 "1.00 Kuwaiti Dinar random",
5570 "1.00 Kuwaiti dinar random",
5571 "1.00 Kuwaiti dinars random",
5572 "1.00 Kyrgystani Som random",
5573 "1.00 Kyrgystani som random",
5574 "1.00 Kyrgystani soms random",
5575 "1.00 Laotian Kip random",
5576 "1.00 Laotian kip random",
5577 "1.00 Laotian kips random",
5578 "1.00 Latvian Lats random",
5579 "1.00 Latvian Ruble random",
5580 "1.00 Latvian lats random",
5581 "1.00 Latvian lati random",
5582 "1.00 Latvian ruble random",
5583 "1.00 Latvian rubles random",
5584 "1.00 Lebanese Pound random",
5585 "1.00 Lebanese pound random",
5586 "1.00 Lebanese pounds random",
5587 "1.00 Lesotho Loti random",
5588 "1.00 Lesotho loti random",
5589 "1.00 Lesotho lotis random",
5590 "1.00 Liberian Dollar random",
5591 "1.00 Liberian dollar random",
5592 "1.00 Liberian dollars random",
5593 "1.00 Libyan Dinar random",
5594 "1.00 Libyan dinar random",
5595 "1.00 Libyan dinars random",
5596 "1.00 Lithuanian Litas random",
5597 "1.00 Lithuanian Talonas random",
5598 "1.00 Lithuanian litas random",
5599 "1.00 Lithuanian litai random",
5600 "1.00 Lithuanian talonas random",
5601 "1.00 Lithuanian talonases random",
5602 "1.00 Luxembourgian Convertible Franc random",
5603 "1.00 Luxembourg Financial Franc random",
5604 "1.00 Luxembourgian Franc random",
5605 "1.00 Luxembourgian convertible franc random",
5606 "1.00 Luxembourgian convertible francs random",
5607 "1.00 Luxembourg financial franc random",
5608 "1.00 Luxembourg financial francs random",
5609 "1.00 Luxembourgian franc random",
5610 "1.00 Luxembourgian francs random",
5611 "1.00 Macanese Pataca random",
5612 "1.00 Macanese pataca random",
5613 "1.00 Macanese patacas random",
5614 "1.00 Macedonian Denar random",
5615 "1.00 Macedonian denar random",
5616 "1.00 Macedonian denari random",
5617 "1.00 Malagasy Ariaries random",
5618 "1.00 Malagasy Ariary random",
5619 "1.00 Malagasy Ariary random",
5620 "1.00 Malagasy Franc random",
5621 "1.00 Malagasy franc random",
5622 "1.00 Malagasy francs random",
5623 "1.00 Malawian Kwacha random",
5624 "1.00 Malawian Kwacha random",
5625 "1.00 Malawian Kwachas random",
5626 "1.00 Malaysian Ringgit random",
5627 "1.00 Malaysian ringgit random",
5628 "1.00 Malaysian ringgits random",
5629 "1.00 Maldivian Rufiyaa random",
5630 "1.00 Maldivian rufiyaa random",
5631 "1.00 Maldivian rufiyaas random",
5632 "1.00 Malian Franc random",
5633 "1.00 Malian franc random",
5634 "1.00 Malian francs random",
5635 "1.00 Maltese Lira random",
5636 "1.00 Maltese Pound random",
5637 "1.00 Maltese lira random",
5638 "1.00 Maltese liras random",
5639 "1.00 Maltese pound random",
5640 "1.00 Maltese pounds random",
5641 "1.00 Mauritanian Ouguiya random",
5642 "1.00 Mauritanian ouguiya random",
5643 "1.00 Mauritanian ouguiyas random",
5644 "1.00 Mauritian Rupee random",
5645 "1.00 Mauritian rupee random",
5646 "1.00 Mauritian rupees random",
5647 "1.00 Mexican Peso random",
5648 "1.00 Mexican Silver Peso (1861\\u20131992) random",
5649 "1.00 Mexican Investment Unit random",
5650 "1.00 Mexican peso random",
5651 "1.00 Mexican pesos random",
5652 "1.00 Mexican silver peso (1861\\u20131992) random",
5653 "1.00 Mexican silver pesos (1861\\u20131992) random",
5654 "1.00 Mexican investment unit random",
5655 "1.00 Mexican investment units random",
5656 "1.00 Moldovan Leu random",
5657 "1.00 Moldovan leu random",
5658 "1.00 Moldovan lei random",
5659 "1.00 Mongolian Tugrik random",
5660 "1.00 Mongolian tugrik random",
5661 "1.00 Mongolian tugriks random",
5662 "1.00 Moroccan Dirham random",
5663 "1.00 Moroccan Franc random",
5664 "1.00 Moroccan dirham random",
5665 "1.00 Moroccan dirhams random",
5666 "1.00 Moroccan franc random",
5667 "1.00 Moroccan francs random",
5668 "1.00 Mozambican Escudo random",
5669 "1.00 Mozambican Metical random",
5670 "1.00 Mozambican escudo random",
5671 "1.00 Mozambican escudos random",
5672 "1.00 Mozambican metical random",
5673 "1.00 Mozambican meticals random",
5674 "1.00 Myanmar Kyat random",
5675 "1.00 Myanmar kyat random",
5676 "1.00 Myanmar kyats random",
5677 "1.00 Namibian Dollar random",
5678 "1.00 Namibian dollar random",
5679 "1.00 Namibian dollars random",
5680 "1.00 Nepalese Rupee random",
5681 "1.00 Nepalese rupee random",
5682 "1.00 Nepalese rupees random",
5683 "1.00 Netherlands Antillean Guilder random",
5684 "1.00 Netherlands Antillean guilder random",
5685 "1.00 Netherlands Antillean guilders random",
5686 "1.00 Dutch Guilder random",
5687 "1.00 Dutch guilder random",
5688 "1.00 Dutch guilders random",
5689 "1.00 Israeli New Shekel random",
5690 "1.00 Israeli new shekels random",
5691 "1.00 New Zealand Dollar random",
5692 "1.00 New Zealand dollar random",
5693 "1.00 New Zealand dollars random",
5694 "1.00 Nicaraguan C\\u00f3rdoba random",
5695 "1.00 Nicaraguan C\\u00f3rdoba (1988\\u20131991) random",
5696 "1.00 Nicaraguan c\\u00f3rdoba random",
5697 "1.00 Nicaraguan c\\u00f3rdoba random",
5698 "1.00 Nicaraguan c\\u00f3rdoba (1988\\u20131991) random",
5699 "1.00 Nicaraguan c\\u00f3rdobas (1988\\u20131991) random",
5700 "1.00 Nigerian Naira random",
5701 "1.00 Nigerian naira random",
5702 "1.00 Nigerian nairas random",
5703 "1.00 North Korean Won random",
5704 "1.00 North Korean won random",
5705 "1.00 North Korean won random",
5706 "1.00 Norwegian Krone random",
5707 "1.00 Norwegian krone random",
5708 "1.00 Norwegian kroner random",
5709 "1.00 Mozambican Metical (1980\\u20132006) random",
5710 "1.00 Mozambican metical (1980\\u20132006) random",
5711 "1.00 Mozambican meticals (1980\\u20132006) random",
5712 "1.00 Romanian Lei (1952\\u20132006) random",
5713 "1.00 Romanian Leu (1952\\u20132006) random",
5714 "1.00 Romanian leu (1952\\u20132006) random",
5715 "1.00 Serbian Dinar (2002\\u20132006) random",
5716 "1.00 Serbian dinar (2002\\u20132006) random",
5717 "1.00 Serbian dinars (2002\\u20132006) random",
5718 "1.00 Sudanese Dinar (1992\\u20132007) random",
5719 "1.00 Sudanese Pound (1957\\u20131998) random",
5720 "1.00 Sudanese dinar (1992\\u20132007) random",
5721 "1.00 Sudanese dinars (1992\\u20132007) random",
5722 "1.00 Sudanese pound (1957\\u20131998) random",
5723 "1.00 Sudanese pounds (1957\\u20131998) random",
5724 "1.00 Turkish Lira (1922\\u20132005) random",
5725 "1.00 Turkish Lira (1922\\u20132005) random",
5726 "1.00 Omani Rial random",
5727 "1.00 Omani rial random",
5728 "1.00 Omani rials random",
5729 "1.00 Pakistani Rupee random",
5730 "1.00 Pakistani rupee random",
5731 "1.00 Pakistani rupees random",
5732 "1.00 Palladium random",
5733 "1.00 Palladium random",
5734 "1.00 Panamanian Balboa random",
5735 "1.00 Panamanian balboa random",
5736 "1.00 Panamanian balboas random",
5737 "1.00 Papua New Guinean Kina random",
5738 "1.00 Papua New Guinean kina random",
5739 "1.00 Papua New Guinean kina random",
5740 "1.00 Paraguayan Guarani random",
5741 "1.00 Paraguayan guarani random",
5742 "1.00 Paraguayan guaranis random",
5743 "1.00 Peruvian Inti random",
5744 "1.00 Peruvian Sol random",
5745 "1.00 Peruvian Sol (1863\\u20131965) random",
5746 "1.00 Peruvian inti random",
5747 "1.00 Peruvian intis random",
5748 "1.00 Peruvian sol random",
5749 "1.00 Peruvian soles random",
5750 "1.00 Peruvian sol (1863\\u20131965) random",
5751 "1.00 Peruvian soles (1863\\u20131965) random",
5752 "1.00 Philippine Piso random",
5753 "1.00 Philippine piso random",
5754 "1.00 Philippine pisos random",
5755 "1.00 Platinum random",
5756 "1.00 Platinum random",
5757 "1.00 Polish Zloty (1950\\u20131995) random",
5758 "1.00 Polish Zloty random",
5759 "1.00 Polish zlotys random",
5760 "1.00 Polish zloty (PLZ) random",
5761 "1.00 Polish zloty random",
5762 "1.00 Polish zlotys (PLZ) random",
5763 "1.00 Portuguese Escudo random",
5764 "1.00 Portuguese Guinea Escudo random",
5765 "1.00 Portuguese Guinea escudo random",
5766 "1.00 Portuguese Guinea escudos random",
5767 "1.00 Portuguese escudo random",
5768 "1.00 Portuguese escudos random",
5769 "1.00 Qatari Rial random",
5770 "1.00 Qatari rial random",
5771 "1.00 Qatari rials random",
5772 "1.00 RINET Funds random",
5773 "1.00 RINET Funds random",
5774 "1.00 Rhodesian Dollar random",
5775 "1.00 Rhodesian dollar random",
5776 "1.00 Rhodesian dollars random",
5777 "1.00 Romanian Leu random",
5778 "1.00 Romanian lei random",
5779 "1.00 Romanian leu random",
5780 "1.00 Russian Ruble (1991\\u20131998) random",
5781 "1.00 Russian Ruble random",
5782 "1.00 Russian ruble (1991\\u20131998) random",
5783 "1.00 Russian ruble random",
5784 "1.00 Russian rubles (1991\\u20131998) random",
5785 "1.00 Russian rubles random",
5786 "1.00 Rwandan Franc random",
5787 "1.00 Rwandan franc random",
5788 "1.00 Rwandan francs random",
5789 "1.00 St. Helena Pound random",
5790 "1.00 St. Helena pound random",
5791 "1.00 St. Helena pounds random",
5792 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobra random",
5793 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobra random",
5794 "1.00 S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe dobras random",
5795 "1.00 Saudi Riyal random",
5796 "1.00 Saudi riyal random",
5797 "1.00 Saudi riyals random",
5798 "1.00 Serbian Dinar random",
5799 "1.00 Serbian dinar random",
5800 "1.00 Serbian dinars random",
5801 "1.00 Seychellois Rupee random",
5802 "1.00 Seychellois rupee random",
5803 "1.00 Seychellois rupees random",
5804 "1.00 Sierra Leonean Leone random",
5805 "1.00 Sierra Leonean leone random",
5806 "1.00 Sierra Leonean leones random",
5807 "1.00 Singapore Dollar random",
5808 "1.00 Singapore dollar random",
5809 "1.00 Singapore dollars random",
5810 "1.00 Slovak Koruna random",
5811 "1.00 Slovak koruna random",
5812 "1.00 Slovak korunas random",
5813 "1.00 Slovenian Tolar random",
5814 "1.00 Slovenian tolar random",
5815 "1.00 Slovenian tolars random",
5816 "1.00 Solomon Islands Dollar random",
5817 "1.00 Solomon Islands dollar random",
5818 "1.00 Solomon Islands dollars random",
5819 "1.00 Somali Shilling random",
5820 "1.00 Somali shilling random",
5821 "1.00 Somali shillings random",
5822 "1.00 South African Rand (financial) random",
5823 "1.00 South African Rand random",
5824 "1.00 South African rand (financial) random",
5825 "1.00 South African rand random",
5826 "1.00 South African rands (financial) random",
5827 "1.00 South African rand random",
5828 "1.00 South Korean Won random",
5829 "1.00 South Korean won random",
5830 "1.00 South Korean won random",
5831 "1.00 Soviet Rouble random",
5832 "1.00 Soviet rouble random",
5833 "1.00 Soviet roubles random",
5834 "1.00 Spanish Peseta (A account) random",
5835 "1.00 Spanish Peseta (convertible account) random",
5836 "1.00 Spanish Peseta random",
5837 "1.00 Spanish peseta (A account) random",
5838 "1.00 Spanish peseta (convertible account) random",
5839 "1.00 Spanish peseta random",
5840 "1.00 Spanish pesetas (A account) random",
5841 "1.00 Spanish pesetas (convertible account) random",
5842 "1.00 Spanish pesetas random",
5843 "1.00 Special Drawing Rights random",
5844 "1.00 Sri Lankan Rupee random",
5845 "1.00 Sri Lankan rupee random",
5846 "1.00 Sri Lankan rupees random",
5847 "1.00 Sudanese Pound random",
5848 "1.00 Sudanese pound random",
5849 "1.00 Sudanese pounds random",
5850 "1.00 Surinamese Dollar random",
5851 "1.00 Surinamese dollar random",
5852 "1.00 Surinamese dollars random",
5853 "1.00 Surinamese Guilder random",
5854 "1.00 Surinamese guilder random",
5855 "1.00 Surinamese guilders random",
5856 "1.00 Swazi Lilangeni random",
5857 "1.00 Swazi lilangeni random",
5858 "1.00 Swazi emalangeni random",
5859 "1.00 Swedish Krona random",
5860 "1.00 Swedish krona random",
5861 "1.00 Swedish kronor random",
5862 "1.00 Swiss Franc random",
5863 "1.00 Swiss franc random",
5864 "1.00 Swiss francs random",
5865 "1.00 Syrian Pound random",
5866 "1.00 Syrian pound random",
5867 "1.00 Syrian pounds random",
5868 "1.00 New Taiwan Dollar random",
5869 "1.00 New Taiwan dollar random",
5870 "1.00 New Taiwan dollars random",
5871 "1.00 Tajikistani Ruble random",
5872 "1.00 Tajikistani Somoni random",
5873 "1.00 Tajikistani ruble random",
5874 "1.00 Tajikistani rubles random",
5875 "1.00 Tajikistani somoni random",
5876 "1.00 Tajikistani somonis random",
5877 "1.00 Tanzanian Shilling random",
5878 "1.00 Tanzanian shilling random",
5879 "1.00 Tanzanian shillings random",
5880 "1.00 Testing Currency Code random",
5881 "1.00 Testing Currency Code random",
5882 "1.00 Thai Baht random",
5883 "1.00 Thai baht random",
5884 "1.00 Thai baht random",
5885 "1.00 Timorese Escudo random",
5886 "1.00 Timorese escudo random",
5887 "1.00 Timorese escudos random",
5888 "1.00 Trinidad & Tobago Dollar random",
5889 "1.00 Trinidad & Tobago dollar random",
5890 "1.00 Trinidad & Tobago dollars random",
5891 "1.00 Tunisian Dinar random",
5892 "1.00 Tunisian dinar random",
5893 "1.00 Tunisian dinars random",
5894 "1.00 Turkish Lira random",
5895 "1.00 Turkish Lira random",
5896 "1.00 Turkish lira random",
5897 "1.00 Turkmenistani Manat random",
5898 "1.00 Turkmenistani manat random",
5899 "1.00 Turkmenistani manat random",
5900 "1.00 US Dollar (Next day) random",
5901 "1.00 US Dollar (Same day) random",
5902 "1.00 US Dollar random",
5903 "1.00 US dollar (next day) random",
5904 "1.00 US dollar (same day) random",
5905 "1.00 US dollar random",
5906 "1.00 US dollars (next day) random",
5907 "1.00 US dollars (same day) random",
5908 "1.00 US dollars random",
5909 "1.00 Ugandan Shilling (1966\\u20131987) random",
5910 "1.00 Ugandan Shilling random",
5911 "1.00 Ugandan shilling (1966\\u20131987) random",
5912 "1.00 Ugandan shilling random",
5913 "1.00 Ugandan shillings (1966\\u20131987) random",
5914 "1.00 Ugandan shillings random",
5915 "1.00 Ukrainian Hryvnia random",
5916 "1.00 Ukrainian Karbovanets random",
5917 "1.00 Ukrainian hryvnia random",
5918 "1.00 Ukrainian hryvnias random",
5919 "1.00 Ukrainian karbovanets random",
5920 "1.00 Ukrainian karbovantsiv random",
5921 "1.00 Colombian Real Value Unit random",
5922 "1.00 United Arab Emirates Dirham random",
5923 "1.00 Unknown Currency random",
5924 "1.00 Uruguayan Peso (1975\\u20131993) random",
5925 "1.00 Uruguayan Peso random",
5926 "1.00 Uruguayan Peso (Indexed Units) random",
5927 "1.00 Uruguayan peso (1975\\u20131993) random",
5928 "1.00 Uruguayan peso (indexed units) random",
5929 "1.00 Uruguayan peso random",
5930 "1.00 Uruguayan pesos (1975\\u20131993) random",
5931 "1.00 Uruguayan pesos (indexed units) random",
5932 "1.00 Uzbekistani Som random",
5933 "1.00 Uzbekistani som random",
5934 "1.00 Uzbekistani som random",
5935 "1.00 Vanuatu Vatu random",
5936 "1.00 Vanuatu vatu random",
5937 "1.00 Vanuatu vatus random",
5938 "1.00 Venezuelan Bol\\u00edvar random",
5939 "1.00 Venezuelan Bol\\u00edvar (1871\\u20132008) random",
5940 "1.00 Venezuelan bol\\u00edvar random",
5941 "1.00 Venezuelan bol\\u00edvars random",
5942 "1.00 Venezuelan bol\\u00edvar (1871\\u20132008) random",
5943 "1.00 Venezuelan bol\\u00edvars (1871\\u20132008) random",
5944 "1.00 Vietnamese Dong random",
5945 "1.00 Vietnamese dong random",
5946 "1.00 Vietnamese dong random",
5947 "1.00 WIR Euro random",
5948 "1.00 WIR Franc random",
5949 "1.00 WIR euro random",
5950 "1.00 WIR euros random",
5951 "1.00 WIR franc random",
5952 "1.00 WIR francs random",
5953 "1.00 Samoan Tala random",
5954 "1.00 Samoan tala random",
5955 "1.00 Samoan tala random",
5956 "1.00 Yemeni Dinar random",
5957 "1.00 Yemeni Rial random",
5958 "1.00 Yemeni dinar random",
5959 "1.00 Yemeni dinars random",
5960 "1.00 Yemeni rial random",
5961 "1.00 Yemeni rials random",
5962 "1.00 Yugoslavian Convertible Dinar (1990\\u20131992) random",
5963 "1.00 Yugoslavian Hard Dinar (1966\\u20131990) random",
5964 "1.00 Yugoslavian New Dinar (1994\\u20132002) random",
5965 "1.00 Yugoslavian convertible dinar (1990\\u20131992) random",
5966 "1.00 Yugoslavian convertible dinars (1990\\u20131992) random",
5967 "1.00 Yugoslavian hard dinar (1966\\u20131990) random",
5968 "1.00 Yugoslavian hard dinars (1966\\u20131990) random",
5969 "1.00 Yugoslavian new dinar (1994\\u20132002) random",
5970 "1.00 Yugoslavian new dinars (1994\\u20132002) random",
5971 "1.00 Zairean New Zaire (1993\\u20131998) random",
5972 "1.00 Zairean Zaire (1971\\u20131993) random",
5973 "1.00 Zairean new zaire (1993\\u20131998) random",
5974 "1.00 Zairean new zaires (1993\\u20131998) random",
5975 "1.00 Zairean zaire (1971\\u20131993) random",
5976 "1.00 Zairean zaires (1971\\u20131993) random",
5977 "1.00 Zambian Kwacha random",
5978 "1.00 Zambian kwacha random",
5979 "1.00 Zambian kwachas random",
5980 "1.00 Zimbabwean Dollar (1980\\u20132008) random",
5981 "1.00 Zimbabwean dollar (1980\\u20132008) random",
5982 "1.00 Zimbabwean dollars (1980\\u20132008) random",
5984 "1.00 euros random",
5985 "1.00 Turkish lira (1922\\u20132005) random",
5986 "1.00 special drawing rights random",
5987 "1.00 Colombian real value unit random",
5988 "1.00 Colombian real value units random",
5989 "1.00 unknown currency random",
5992 const char* WRONG_DATA
[] = {
5993 // Following are missing one last char in the currency name
5994 "1.00 Nicaraguan Cordob",
5995 "1.00 Namibian Dolla",
5996 "1.00 Namibian dolla",
5997 "1.00 Nepalese Rupe",
5998 "1.00 Nepalese rupe",
5999 "1.00 Netherlands Antillean Guilde",
6000 "1.00 Netherlands Antillean guilde",
6001 "1.00 Dutch Guilde",
6002 "1.00 Dutch guilde",
6003 "1.00 Israeli New Sheqe",
6004 "1.00 New Zealand Dolla",
6005 "1.00 New Zealand dolla",
6006 "1.00 Nicaraguan cordob",
6007 "1.00 Nigerian Nair",
6008 "1.00 Nigerian nair",
6009 "1.00 North Korean Wo",
6010 "1.00 North Korean wo",
6011 "1.00 Norwegian Kron",
6012 "1.00 Norwegian kron",
6028 "Afghan Afghan1.00",
6029 "Afghan Afghani (1927\\u201320021.00",
6032 "Algerian Dina1.00",
6033 "Andorran Peset1.00",
6034 "Angolan Kwanz1.00",
6035 "Angolan Kwanza (1977\\u201319901.00",
6036 "Angolan Readjusted Kwanza (1995\\u201319991.00",
6037 "Angolan New Kwanza (1990\\u201320001.00",
6038 "Argentine Austra1.00",
6039 "Argentine Pes1.00",
6040 "Argentine Peso (1983\\u201319851.00",
6043 "Australian Dolla1.00",
6044 "Austrian Schillin1.00",
6045 "Azerbaijani Mana1.00",
6046 "Azerbaijani Manat (1993\\u201320061.00",
6064 "Bahamian Dolla1.00",
6065 "Bahraini Dina1.00",
6066 "Bangladeshi Tak1.00",
6067 "Barbadian Dolla1.00",
6069 "Belarusian Ruble (1994\\u201319991.00",
6070 "Belarusian Rubl1.00",
6072 "Belgian Franc (convertible1.00",
6073 "Belgian Franc (financial1.00",
6075 "Bermudan Dolla1.00",
6076 "Bhutanese Ngultru1.00",
6077 "Bolivian Mvdo1.00",
6079 "Bolivian Bolivian1.00",
6080 "Bosnia-Herzegovina Convertible Mar1.00",
6081 "Bosnia-Herzegovina Dina1.00",
6082 "Botswanan Pul1.00",
6083 "Brazilian Cruzad1.00",
6084 "Brazilian Cruzado Nov1.00",
6085 "Brazilian Cruzeir1.00",
6086 "Brazilian Cruzeiro (1990\\u201319931.00",
6087 "Brazilian New Cruzeiro (1967\\u201319861.00",
6088 "Brazilian Rea1.00",
6089 "British Pound Sterlin1.00",
6091 "Bulgarian Hard Le1.00",
6094 "Burundian Fran1.00",
6109 "Cambodian Rie1.00",
6110 "Canadian Dolla1.00",
6111 "Cape Verdean Escud1.00",
6112 "Cayman Islands Dolla1.00",
6114 "Chilean Unit of Accoun1.00",
6116 "Colombian Pes1.00",
6118 "Congolese Fran1.00",
6119 "Costa Rican Col\\u00f31.00",
6120 "Croatian Dina1.00",
6124 "Czech Republic Korun1.00",
6125 "Czechoslovak Hard Korun1.00",
6135 "Djiboutian Fran1.00",
6137 "Dominican Pes1.00",
6146 "East Caribbean Dolla1.00",
6147 "East German Ostmar1.00",
6148 "Ecuadorian Sucr1.00",
6149 "Ecuadorian Unit of Constant Valu1.00",
6150 "Egyptian Poun1.00",
6152 "Salvadoran Col\\u00f31.00",
6153 "Equatorial Guinean Ekwel1.00",
6154 "Eritrean Nakf1.00",
6156 "Estonian Kroo1.00",
6157 "Ethiopian Bir1.00",
6159 "European Composite Uni1.00",
6160 "European Currency Uni1.00",
6161 "European Monetary Uni1.00",
6162 "European Unit of Account (XBC1.00",
6163 "European Unit of Account (XBD1.00",
6170 "Falkland Islands Poun1.00",
6173 "Finnish Markk1.00",
6176 "French Gold Fran1.00",
6177 "French UIC-Fran1.00",
6190 "Gambian Dalas1.00",
6191 "Georgian Kupon Lari1.00",
6194 "Ghanaian Cedi (1979\\u201320071.00",
6195 "Gibraltar Poun1.00",
6198 "Guatemalan Quetza1.00",
6201 "Guinea-Bissau Pes1.00",
6202 "Guyanaese Dolla1.00",
6208 "Haitian Gourd1.00",
6209 "Honduran Lempir1.00",
6210 "Hong Kong Dolla1.00",
6211 "Hungarian Forin1.00",
6220 "Icelandic Kron1.00",
6222 "Indonesian Rupia1.00",
6232 "Jamaican Dolla1.00",
6234 "Jordanian Dina1.00",
6245 "Kazakhstani Teng1.00",
6246 "Kenyan Shillin1.00",
6248 "Kyrgystani So1.00",
6260 "Lebanese Poun1.00",
6262 "Liberian Dolla1.00",
6264 "Lithuanian Lit1.00",
6265 "Lithuanian Talona1.00",
6266 "Luxembourgian Convertible Fran1.00",
6267 "Luxembourg Financial Fran1.00",
6268 "Luxembourgian Fran1.00",
6286 "Macanese Patac1.00",
6287 "Macedonian Dena1.00",
6288 "Malagasy Ariar1.00",
6289 "Malagasy Fran1.00",
6290 "Malawian Kwach1.00",
6291 "Malaysian Ringgi1.00",
6292 "Maldivian Rufiya1.00",
6297 "Mauritanian Ouguiy1.00",
6298 "Mauritian Rupe1.00",
6300 "Mexican Silver Peso (1861\\u201319921.00",
6301 "Mexican Investment Uni1.00",
6303 "Mongolian Tugri1.00",
6304 "Moroccan Dirha1.00",
6305 "Moroccan Fran1.00",
6306 "Mozambican Escud1.00",
6307 "Mozambican Metica1.00",
6319 "Namibian Dolla1.00",
6320 "Nepalese Rupe1.00",
6321 "Netherlands Antillean Guilde1.00",
6323 "Israeli New Sheqe1.00",
6324 "New Zealand Dolla1.00",
6325 "Nicaraguan C\\u00f3rdoba (1988\\u201319911.00",
6326 "Nicaraguan C\\u00f3rdob1.00",
6327 "Nigerian Nair1.00",
6328 "North Korean Wo1.00",
6329 "Norwegian Kron1.00",
6332 "Old Mozambican Metica1.00",
6333 "Romanian Leu (1952\\u201320061.00",
6334 "Serbian Dinar (2002\\u201320061.00",
6335 "Sudanese Dinar (1992\\u201320071.00",
6336 "Sudanese Pound (1957\\u201319981.00",
6337 "Turkish Lira (1922\\u201320051.00",
6347 "Pakistani Rupe1.00",
6349 "Panamanian Balbo1.00",
6350 "Papua New Guinean Kin1.00",
6351 "Paraguayan Guaran1.00",
6353 "Peruvian Sol (1863\\u201319651.00",
6354 "Peruvian Sol Nuev1.00",
6355 "Philippine Pes1.00",
6358 "Polish Zloty (1950\\u201319951.00",
6359 "Portuguese Escud1.00",
6360 "Portuguese Guinea Escud1.00",
6371 "Rhodesian Dolla1.00",
6374 "Russian Ruble (1991\\u201319981.00",
6394 "St. Helena Poun1.00",
6395 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobr1.00",
6398 "Seychellois Rupe1.00",
6400 "Sierra Leonean Leon1.00",
6402 "Singapore Dolla1.00",
6404 "Slovenian Tola1.00",
6405 "Solomon Islands Dolla1.00",
6406 "Somali Shillin1.00",
6407 "South African Ran1.00",
6408 "South African Rand (financial1.00",
6409 "South Korean Wo1.00",
6411 "Spanish Peset1.00",
6412 "Spanish Peseta (A account1.00",
6413 "Spanish Peseta (convertible account1.00",
6414 "Special Drawing Right1.00",
6415 "Sri Lankan Rupe1.00",
6416 "Sudanese Poun1.00",
6417 "Surinamese Dolla1.00",
6418 "Surinamese Guilde1.00",
6419 "Swazi Lilangen1.00",
6434 "New Taiwan Dolla1.00",
6435 "Tajikistani Rubl1.00",
6436 "Tajikistani Somon1.00",
6437 "Tanzanian Shillin1.00",
6438 "Testing Currency Cod1.00",
6440 "Timorese Escud1.00",
6441 "Tongan Pa\\u20bbang1.00",
6442 "Trinidad & Tobago Dolla1.00",
6443 "Tunisian Dina1.00",
6445 "Turkmenistani Mana1.00",
6451 "US Dollar (Next day1.00",
6452 "US Dollar (Same day1.00",
6456 "Ugandan Shillin1.00",
6457 "Ugandan Shilling (1966\\u201319871.00",
6458 "Ukrainian Hryvni1.00",
6459 "Ukrainian Karbovanet1.00",
6460 "Colombian Real Value Uni1.00",
6461 "United Arab Emirates Dirha1.00",
6462 "Unknown Currenc1.00",
6464 "Uruguay Peso (1975\\u201319931.00",
6465 "Uruguay Peso Uruguay1.00",
6466 "Uruguay Peso (Indexed Units1.00",
6467 "Uzbekistani So1.00",
6473 "Venezuelan Bol\\u00edva1.00",
6474 "Venezuelan Bol\\u00edvar Fuert1.00",
6475 "Vietnamese Don1.00",
6476 "West African CFA Fran1.00",
6477 "Central African CFA Fran1.00",
6498 "Yugoslavian Convertible Dina1.00",
6499 "Yugoslavian Hard Dinar (1966\\u201319901.00",
6500 "Yugoslavian New Dina1.00",
6506 "Zairean New Zaire (1993\\u201319981.00",
6508 "Zambian Kwach1.00",
6509 "Zimbabwean Dollar (1980\\u201320081.00",
6517 Locale
locale("en_US");
6518 for (uint32_t i
=0; i
<UPRV_LENGTHOF(DATA
); ++i
) {
6519 UnicodeString formatted
= ctou(DATA
[i
]);
6520 UErrorCode status
= U_ZERO_ERROR
;
6521 LocalPointer
<NumberFormat
> numFmt(NumberFormat::createInstance(locale
, UNUM_CURRENCY
, status
), status
);
6522 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) {
6525 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
6526 numFmt
->setLenient(TRUE
);
6527 ParsePosition parsePos
;
6528 LocalPointer
<CurrencyAmount
> currAmt(numFmt
->parseCurrency(formatted
, parsePos
));
6529 if (parsePos
.getIndex() > 0) {
6530 double doubleVal
= currAmt
->getNumber().getDouble(status
);
6531 if ( doubleVal
!= 1.0 ) {
6532 errln("Parsed as currency value other than 1.0: " + formatted
+ " -> " + doubleVal
);
6535 errln("Failed to parse as currency: " + formatted
);
6539 for (uint32_t i
=0; i
<UPRV_LENGTHOF(WRONG_DATA
); ++i
) {
6540 UnicodeString formatted
= ctou(WRONG_DATA
[i
]);
6541 UErrorCode status
= U_ZERO_ERROR
;
6542 NumberFormat
* numFmt
= NumberFormat::createInstance(locale
, UNUM_CURRENCY
, status
);
6543 if (numFmt
!= NULL
&& U_SUCCESS(status
)) {
6544 ParsePosition parsePos
;
6545 LocalPointer
<CurrencyAmount
> currAmt(numFmt
->parseCurrency(formatted
, parsePos
));
6546 if (parsePos
.getIndex() > 0) {
6547 double doubleVal
= currAmt
->getNumber().getDouble(status
);
6548 errln("Parsed as currency, should not have: " + formatted
+ " -> " + doubleVal
);
6551 dataerrln("Unable to create NumberFormat. - %s", u_errorName(status
));
6559 const char* attrString(int32_t);
6563 // std::cout << s.toUTF8String(ss)
6564 void NumberFormatTest::expectPositions(FieldPositionIterator
& iter
, int32_t *values
, int32_t tupleCount
,
6565 const UnicodeString
& str
) {
6569 if (tupleCount
> 10) {
6570 assertTrue("internal error, tupleCount too large", FALSE
);
6572 for (int i
= 0; i
< tupleCount
; ++i
) {
6578 while (iter
.next(fp
)) {
6580 int32_t id
= fp
.getField();
6581 int32_t start
= fp
.getBeginIndex();
6582 int32_t limit
= fp
.getEndIndex();
6584 // is there a logln using printf?
6586 sprintf(buf
, "%24s %3d %3d %3d", attrString(id
), id
, start
, limit
);
6589 for (int i
= 0; i
< tupleCount
; ++i
) {
6593 if (values
[i
*3] == id
&&
6594 values
[i
*3+1] == start
&&
6595 values
[i
*3+2] == limit
) {
6596 found
[i
] = ok
= TRUE
;
6601 assertTrue((UnicodeString
)"found [" + id
+ "," + start
+ "," + limit
+ "]", ok
);
6604 // check that all were found
6606 for (int i
= 0; i
< tupleCount
; ++i
) {
6609 assertTrue((UnicodeString
) "missing [" + values
[i
*3] + "," + values
[i
*3+1] + "," + values
[i
*3+2] + "]", found
[i
]);
6612 assertTrue("no expected values were missing", ok
);
6615 void NumberFormatTest::expectPosition(FieldPosition
& pos
, int32_t id
, int32_t start
, int32_t limit
,
6616 const UnicodeString
& str
) {
6618 assertTrue((UnicodeString
)"id " + id
+ " == " + pos
.getField(), id
== pos
.getField());
6619 assertTrue((UnicodeString
)"begin " + start
+ " == " + pos
.getBeginIndex(), start
== pos
.getBeginIndex());
6620 assertTrue((UnicodeString
)"end " + limit
+ " == " + pos
.getEndIndex(), limit
== pos
.getEndIndex());
6623 void NumberFormatTest::TestFieldPositionIterator() {
6625 UErrorCode status
= U_ZERO_ERROR
;
6626 FieldPositionIterator iter1
;
6627 FieldPositionIterator iter2
;
6630 DecimalFormat
*decFmt
= (DecimalFormat
*) NumberFormat::createInstance(status
);
6631 if (failure(status
, "NumberFormat::createInstance", TRUE
)) return;
6633 double num
= 1234.56;
6637 assertTrue((UnicodeString
)"self==", iter1
== iter1
);
6638 assertTrue((UnicodeString
)"iter1==iter2", iter1
== iter2
);
6640 decFmt
->format(num
, str1
, &iter1
, status
);
6641 assertTrue((UnicodeString
)"iter1 != iter2", iter1
!= iter2
);
6642 decFmt
->format(num
, str2
, &iter2
, status
);
6643 assertTrue((UnicodeString
)"iter1 == iter2 (2)", iter1
== iter2
);
6645 assertTrue((UnicodeString
)"iter1 != iter2 (2)", iter1
!= iter2
);
6647 assertTrue((UnicodeString
)"iter1 == iter2 (3)", iter1
== iter2
);
6649 // should format ok with no iterator
6651 decFmt
->format(num
, str2
, NULL
, status
);
6652 assertEquals("null fpiter", str1
, str2
);
6657 void NumberFormatTest::TestFormatAttributes() {
6658 Locale
locale("en_US");
6659 UErrorCode status
= U_ZERO_ERROR
;
6660 DecimalFormat
*decFmt
= (DecimalFormat
*) NumberFormat::createInstance(locale
, UNUM_CURRENCY
, status
);
6661 if (failure(status
, "NumberFormat::createInstance", TRUE
)) return;
6662 double val
= 12345.67;
6665 int32_t expected
[] = {
6666 UNUM_CURRENCY_FIELD
, 0, 1,
6667 UNUM_GROUPING_SEPARATOR_FIELD
, 3, 4,
6668 UNUM_INTEGER_FIELD
, 1, 7,
6669 UNUM_DECIMAL_SEPARATOR_FIELD
, 7, 8,
6670 UNUM_FRACTION_FIELD
, 8, 10,
6672 int32_t tupleCount
= UPRV_LENGTHOF(expected
)/3;
6674 FieldPositionIterator posIter
;
6675 UnicodeString result
;
6676 decFmt
->format(val
, result
, &posIter
, status
);
6677 expectPositions(posIter
, expected
, tupleCount
, result
);
6680 FieldPosition
fp(UNUM_INTEGER_FIELD
);
6681 UnicodeString result
;
6682 decFmt
->format(val
, result
, fp
);
6683 expectPosition(fp
, UNUM_INTEGER_FIELD
, 1, 7, result
);
6686 FieldPosition
fp(UNUM_FRACTION_FIELD
);
6687 UnicodeString result
;
6688 decFmt
->format(val
, result
, fp
);
6689 expectPosition(fp
, UNUM_FRACTION_FIELD
, 8, 10, result
);
6693 decFmt
= (DecimalFormat
*) NumberFormat::createInstance(locale
, UNUM_SCIENTIFIC
, status
);
6696 int32_t expected
[] = {
6697 UNUM_SIGN_FIELD
, 0, 1,
6698 UNUM_INTEGER_FIELD
, 1, 2,
6699 UNUM_DECIMAL_SEPARATOR_FIELD
, 2, 3,
6700 UNUM_FRACTION_FIELD
, 3, 5,
6701 UNUM_EXPONENT_SYMBOL_FIELD
, 5, 6,
6702 UNUM_EXPONENT_SIGN_FIELD
, 6, 7,
6703 UNUM_EXPONENT_FIELD
, 7, 8
6705 int32_t tupleCount
= UPRV_LENGTHOF(expected
)/3;
6707 FieldPositionIterator posIter
;
6708 UnicodeString result
;
6709 decFmt
->format(val
, result
, &posIter
, status
);
6710 expectPositions(posIter
, expected
, tupleCount
, result
);
6713 FieldPosition
fp(UNUM_INTEGER_FIELD
);
6714 UnicodeString result
;
6715 decFmt
->format(val
, result
, fp
);
6716 expectPosition(fp
, UNUM_INTEGER_FIELD
, 1, 2, result
);
6719 FieldPosition
fp(UNUM_FRACTION_FIELD
);
6720 UnicodeString result
;
6721 decFmt
->format(val
, result
, fp
);
6722 expectPosition(fp
, UNUM_FRACTION_FIELD
, 3, 5, result
);
6729 const char* attrString(int32_t attrId
) {
6731 case UNUM_INTEGER_FIELD
: return "integer";
6732 case UNUM_FRACTION_FIELD
: return "fraction";
6733 case UNUM_DECIMAL_SEPARATOR_FIELD
: return "decimal separator";
6734 case UNUM_EXPONENT_SYMBOL_FIELD
: return "exponent symbol";
6735 case UNUM_EXPONENT_SIGN_FIELD
: return "exponent sign";
6736 case UNUM_EXPONENT_FIELD
: return "exponent";
6737 case UNUM_GROUPING_SEPARATOR_FIELD
: return "grouping separator";
6738 case UNUM_CURRENCY_FIELD
: return "currency";
6739 case UNUM_PERCENT_FIELD
: return "percent";
6740 case UNUM_PERMILL_FIELD
: return "permille";
6741 case UNUM_SIGN_FIELD
: return "sign";
6747 // Test formatting & parsing of big decimals.
6748 // API test, not a comprehensive test.
6749 // See DecimalFormatTest/DataDrivenTests
6751 #define ASSERT_SUCCESS(status) { \
6752 assertSuccess(UnicodeString("file ") + __FILE__ + ", line " + __LINE__, (status)); \
6754 #define ASSERT_EQUALS(expected, actual) { \
6755 assertEquals(UnicodeString("file ") + __FILE__ + ", line " + __LINE__, (expected), (actual)); \
6758 void NumberFormatTest::TestDecimal() {
6760 UErrorCode status
= U_ZERO_ERROR
;
6761 Formattable
f("12.345678999987654321E666", status
);
6762 ASSERT_SUCCESS(status
);
6763 StringPiece s
= f
.getDecimalNumber(status
);
6764 ASSERT_SUCCESS(status
);
6765 ASSERT_EQUALS("1.2345678999987654321E+667", s
.data());
6766 //printf("%s\n", s.data());
6770 UErrorCode status
= U_ZERO_ERROR
;
6771 Formattable
f1("this is not a number", status
);
6772 ASSERT_EQUALS(U_DECIMAL_NUMBER_SYNTAX_ERROR
, status
);
6776 UErrorCode status
= U_ZERO_ERROR
;
6778 f
.setDecimalNumber("123.45", status
);
6779 ASSERT_SUCCESS(status
);
6780 ASSERT_EQUALS( Formattable::kDouble
, f
.getType());
6781 ASSERT_EQUALS(123.45, f
.getDouble());
6782 ASSERT_EQUALS(123.45, f
.getDouble(status
));
6783 ASSERT_SUCCESS(status
);
6784 ASSERT_EQUALS("123.45", f
.getDecimalNumber(status
).data());
6785 ASSERT_SUCCESS(status
);
6787 f
.setDecimalNumber("4.5678E7", status
);
6790 ASSERT_EQUALS(45678000, n
);
6792 status
= U_ZERO_ERROR
;
6793 f
.setDecimalNumber("-123", status
);
6794 ASSERT_SUCCESS(status
);
6795 ASSERT_EQUALS( Formattable::kLong
, f
.getType());
6796 ASSERT_EQUALS(-123, f
.getLong());
6797 ASSERT_EQUALS(-123, f
.getLong(status
));
6798 ASSERT_SUCCESS(status
);
6799 ASSERT_EQUALS("-123", f
.getDecimalNumber(status
).data());
6800 ASSERT_SUCCESS(status
);
6802 status
= U_ZERO_ERROR
;
6803 f
.setDecimalNumber("1234567890123", status
); // Number too big for 32 bits
6804 ASSERT_SUCCESS(status
);
6805 ASSERT_EQUALS( Formattable::kInt64
, f
.getType());
6806 ASSERT_EQUALS(1234567890123LL, f
.getInt64());
6807 ASSERT_EQUALS(1234567890123LL, f
.getInt64(status
));
6808 ASSERT_SUCCESS(status
);
6809 ASSERT_EQUALS("1234567890123", f
.getDecimalNumber(status
).data());
6810 ASSERT_SUCCESS(status
);
6814 UErrorCode status
= U_ZERO_ERROR
;
6815 NumberFormat
*fmtr
= NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL
, status
);
6816 if (U_FAILURE(status
) || fmtr
== NULL
) {
6817 dataerrln("Unable to create NumberFormat");
6819 UnicodeString formattedResult
;
6820 StringPiece
num("244444444444444444444444444444444444446.4");
6821 fmtr
->format(num
, formattedResult
, NULL
, status
);
6822 ASSERT_SUCCESS(status
);
6823 ASSERT_EQUALS("244,444,444,444,444,444,444,444,444,444,444,444,446.4", formattedResult
);
6824 //std::string ss; std::cout << formattedResult.toUTF8String(ss);
6830 // Check formatting a DigitList. DigitList is internal, but this is
6831 // a critical interface that must work.
6832 UErrorCode status
= U_ZERO_ERROR
;
6833 NumberFormat
*fmtr
= NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL
, status
);
6834 if (U_FAILURE(status
) || fmtr
== NULL
) {
6835 dataerrln("Unable to create NumberFormat");
6837 UnicodeString formattedResult
;
6839 StringPiece
num("123.4566666666666666666666666666666666621E+40");
6840 dl
.setToDecNumber(num
, status
);
6841 ASSERT_SUCCESS(status
);
6842 fmtr
->format(dl
, formattedResult
, NULL
, status
);
6843 ASSERT_SUCCESS(status
);
6844 ASSERT_EQUALS("1,234,566,666,666,666,666,666,666,666,666,666,666,621,000", formattedResult
);
6846 status
= U_ZERO_ERROR
;
6848 dl
.setToDecNumber(num
, status
);
6849 FieldPosition
pos(NumberFormat::FRACTION_FIELD
);
6850 ASSERT_SUCCESS(status
);
6851 formattedResult
.remove();
6852 fmtr
->format(dl
, formattedResult
, pos
, status
);
6853 ASSERT_SUCCESS(status
);
6854 ASSERT_EQUALS("666.666", formattedResult
);
6855 ASSERT_EQUALS(4, pos
.getBeginIndex());
6856 ASSERT_EQUALS(7, pos
.getEndIndex());
6862 // Check a parse with a formatter with a multiplier.
6863 UErrorCode status
= U_ZERO_ERROR
;
6864 NumberFormat
*fmtr
= NumberFormat::createInstance(Locale::getUS(), UNUM_PERCENT
, status
);
6865 if (U_FAILURE(status
) || fmtr
== NULL
) {
6866 dataerrln("Unable to create NumberFormat");
6868 UnicodeString input
= "1.84%";
6870 fmtr
->parse(input
, result
, status
);
6871 ASSERT_SUCCESS(status
);
6872 ASSERT_EQUALS("0.0184", result
.getDecimalNumber(status
).data());
6873 //std::cout << result.getDecimalNumber(status).data();
6878 #if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC)
6880 * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod().
6884 // Check that a parse returns a decimal number with full accuracy
6885 UErrorCode status
= U_ZERO_ERROR
;
6886 NumberFormat
*fmtr
= NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL
, status
);
6887 if (U_FAILURE(status
) || fmtr
== NULL
) {
6888 dataerrln("Unable to create NumberFormat");
6890 UnicodeString input
= "1.002200044400088880000070000";
6892 fmtr
->parse(input
, result
, status
);
6893 ASSERT_SUCCESS(status
);
6894 ASSERT_EQUALS(0, strcmp("1.00220004440008888000007", result
.getDecimalNumber(status
).data()));
6895 ASSERT_EQUALS(1.00220004440008888, result
.getDouble());
6896 //std::cout << result.getDecimalNumber(status).data();
6904 void NumberFormatTest::TestCurrencyFractionDigits() {
6905 UErrorCode status
= U_ZERO_ERROR
;
6906 UnicodeString text1
, text2
;
6907 double value
= 99.12345;
6909 // Create currenct instance
6910 NumberFormat
* fmt
= NumberFormat::createCurrencyInstance("ja_JP", status
);
6911 if (U_FAILURE(status
) || fmt
== NULL
) {
6912 dataerrln("Unable to create NumberFormat");
6914 fmt
->format(value
, text1
);
6916 // Reset the same currency and format the test value again
6917 fmt
->setCurrency(fmt
->getCurrency(), status
);
6918 ASSERT_SUCCESS(status
);
6919 fmt
->format(value
, text2
);
6921 if (text1
!= text2
) {
6922 errln((UnicodeString
)"NumberFormat::format() should return the same result - text1="
6923 + text1
+ " text2=" + text2
);
6929 void NumberFormatTest::TestExponentParse() {
6931 UErrorCode status
= U_ZERO_ERROR
;
6933 ParsePosition
parsePos(0);
6935 // set the exponent symbol
6936 status
= U_ZERO_ERROR
;
6937 DecimalFormatSymbols
symbols(Locale::getDefault(), status
);
6938 if(U_FAILURE(status
)) {
6939 dataerrln((UnicodeString
)"ERROR: Could not create DecimalFormatSymbols (Default)");
6943 // create format instance
6944 status
= U_ZERO_ERROR
;
6945 DecimalFormat
fmt(u
"#####", symbols
, status
);
6946 if(U_FAILURE(status
)) {
6947 errln((UnicodeString
)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
6951 fmt
.parse("5.06e-27", result
, parsePos
);
6952 if(result
.getType() != Formattable::kDouble
&&
6953 result
.getDouble() != 5.06E-27 &&
6954 parsePos
.getIndex() != 8
6957 errln("ERROR: parse failed - expected 5.06E-27, 8 - returned %d, %i",
6958 result
.getDouble(), parsePos
.getIndex());
6962 void NumberFormatTest::TestExplicitParents() {
6964 /* Test that number formats are properly inherited from es_419 */
6965 /* These could be subject to change if the CLDR data changes */
6966 static const char* parentLocaleTests
[][2]= {
6967 /* locale ID */ /* expected */
6968 {"es_CO", "1250,75" },
6969 {"es_ES", "1250,75" },
6970 {"es_GQ", "1250,75" },
6971 {"es_MX", "1250.75" },
6972 {"es_US", "1250.75" },
6973 {"es_VE", "1250,75" },
6978 for(int i
=0; i
< UPRV_LENGTHOF(parentLocaleTests
); i
++){
6979 UErrorCode status
= U_ZERO_ERROR
;
6980 const char *localeID
= parentLocaleTests
[i
][0];
6981 UnicodeString
expected(parentLocaleTests
[i
][1], -1, US_INV
);
6982 expected
= expected
.unescape();
6984 uloc_canonicalize(localeID
, loc
, 256, &status
);
6985 NumberFormat
*fmt
= NumberFormat::createInstance(Locale(loc
), status
);
6986 if(U_FAILURE(status
)){
6987 dataerrln("Could not create number formatter for locale %s - %s",localeID
, u_errorName(status
));
6991 fmt
->format(1250.75, s
);
6993 errln(UnicodeString("FAIL: Expected: ")+expected
6994 + UnicodeString(" Got: ") + s
6995 + UnicodeString( " for locale: ")+ UnicodeString(localeID
) );
6997 if (U_FAILURE(status
)){
6998 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
7006 * Test available numbering systems API.
7008 void NumberFormatTest::TestAvailableNumberingSystems() {
7009 IcuTestErrorCode
status(*this, "TestAvailableNumberingSystems");
7010 StringEnumeration
*availableNumberingSystems
= NumberingSystem::getAvailableNames(status
);
7011 CHECK_DATA(status
, "NumberingSystem::getAvailableNames()")
7013 int32_t nsCount
= availableNumberingSystems
->count(status
);
7014 if ( nsCount
< 74 ) {
7015 errln("FAIL: Didn't get as many numbering systems as we had hoped for. Need at least 74, got %d",nsCount
);
7018 /* A relatively simple test of the API. We call getAvailableNames() and cycle through */
7019 /* each name returned, attempting to create a numbering system based on that name and */
7020 /* verifying that the name returned from the resulting numbering system is the same */
7021 /* one that we initially thought. */
7024 const char* prevName
= nullptr;
7025 for ( int32_t i
= 0 ; i
< nsCount
; i
++ ) {
7026 const char *nsname
= availableNumberingSystems
->next(&len
,status
);
7027 NumberingSystem
* ns
= NumberingSystem::createInstanceByName(nsname
,status
);
7028 logln("OK for ns = %s",nsname
);
7029 if ( uprv_strcmp(nsname
,ns
->getName()) ) {
7030 errln("FAIL: Numbering system name didn't match for name = %s\n",nsname
);
7032 if (prevName
!= nullptr) {
7033 int comp
= uprv_strcmp(prevName
, nsname
);
7035 UnicodeString(u
"NS names should be in alphabetical order: ")
7036 + prevName
+ u
" vs " + nsname
,
7037 // TODO: Why are there duplicates? This doesn't work if comp < 0
7045 LocalPointer
<NumberingSystem
> dummy(NumberingSystem::createInstanceByName("dummy", status
), status
);
7046 status
.expectErrorAndReset(U_UNSUPPORTED_ERROR
);
7047 assertTrue("Non-existent numbering system should return null", dummy
.isNull());
7049 delete availableNumberingSystems
;
7053 NumberFormatTest::Test9087(void)
7055 U_STRING_DECL(pattern
,"#",1);
7056 U_STRING_INIT(pattern
,"#",1);
7058 U_STRING_DECL(infstr
,"INF",3);
7059 U_STRING_INIT(infstr
,"INF",3);
7061 U_STRING_DECL(nanstr
,"NAN",3);
7062 U_STRING_INIT(nanstr
,"NAN",3);
7064 UChar outputbuf
[50] = {0};
7065 UErrorCode status
= U_ZERO_ERROR
;
7066 UNumberFormat
* fmt
= unum_open(UNUM_PATTERN_DECIMAL
,pattern
,1,NULL
,NULL
,&status
);
7067 if ( U_FAILURE(status
) ) {
7068 dataerrln("FAIL: error in unum_open() - %s", u_errorName(status
));
7072 unum_setSymbol(fmt
,UNUM_INFINITY_SYMBOL
,infstr
,3,&status
);
7073 unum_setSymbol(fmt
,UNUM_NAN_SYMBOL
,nanstr
,3,&status
);
7074 if ( U_FAILURE(status
) ) {
7075 errln("FAIL: error setting symbols");
7078 double inf
= uprv_getInfinity();
7080 unum_setAttribute(fmt
,UNUM_ROUNDING_MODE
,UNUM_ROUND_HALFEVEN
);
7081 unum_setDoubleAttribute(fmt
,UNUM_ROUNDING_INCREMENT
,0);
7083 UFieldPosition position
= { 0, 0, 0};
7084 unum_formatDouble(fmt
,inf
,outputbuf
,50,&position
,&status
);
7086 if ( u_strcmp(infstr
, outputbuf
)) {
7087 errln((UnicodeString
)"FAIL: unexpected result for infinity - expected " + infstr
+ " got " + outputbuf
);
7093 void NumberFormatTest::TestFormatFastpaths() {
7094 // get some additional case
7096 UErrorCode status
=U_ZERO_ERROR
;
7097 DecimalFormat
df(UnicodeString(u
"0000"),status
);
7098 if (U_FAILURE(status
)) {
7099 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
7101 int64_t long_number
= 1;
7102 UnicodeString expect
= "0001";
7103 UnicodeString result
;
7105 df
.format(long_number
, result
, pos
);
7106 if(U_FAILURE(status
)||expect
!=result
) {
7107 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s",
7108 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7110 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),""));
7115 UErrorCode status
=U_ZERO_ERROR
;
7116 DecimalFormat
df(UnicodeString(u
"0000000000000000000"),status
);
7117 if (U_FAILURE(status
)) {
7118 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
7120 int64_t long_number
= U_INT64_MIN
; // -9223372036854775808L;
7122 // memcpy(bits,&long_number,8);
7123 // for(int i=0;i<8;i++) {
7124 // logln("bits: %02X", (unsigned int)bits[i]);
7126 UnicodeString expect
= "-9223372036854775808";
7127 UnicodeString result
;
7129 df
.format(long_number
, result
, pos
);
7130 if(U_FAILURE(status
)||expect
!=result
) {
7131 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on -9223372036854775808",
7132 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7134 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),"")+" on -9223372036854775808");
7139 UErrorCode status
=U_ZERO_ERROR
;
7140 DecimalFormat
df(UnicodeString(u
"0000000000000000000"),status
);
7141 if (U_FAILURE(status
)) {
7142 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
7144 int64_t long_number
= U_INT64_MAX
; // -9223372036854775808L;
7146 // memcpy(bits,&long_number,8);
7147 // for(int i=0;i<8;i++) {
7148 // logln("bits: %02X", (unsigned int)bits[i]);
7150 UnicodeString expect
= "9223372036854775807";
7151 UnicodeString result
;
7153 df
.format(long_number
, result
, pos
);
7154 if(U_FAILURE(status
)||expect
!=result
) {
7155 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on U_INT64_MAX",
7156 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7158 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),"")+" on U_INT64_MAX");
7163 UErrorCode status
=U_ZERO_ERROR
;
7164 DecimalFormat
df(UnicodeString("0000000000000000000",""),status
);
7165 if (U_FAILURE(status
)) {
7166 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
7168 int64_t long_number
= 0;
7170 // memcpy(bits,&long_number,8);
7171 // for(int i=0;i<8;i++) {
7172 // logln("bits: %02X", (unsigned int)bits[i]);
7174 UnicodeString expect
= "0000000000000000000";
7175 UnicodeString result
;
7177 df
.format(long_number
, result
, pos
);
7178 if(U_FAILURE(status
)||expect
!=result
) {
7179 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on 0",
7180 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7182 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),"")+" on 0");
7187 UErrorCode status
=U_ZERO_ERROR
;
7188 DecimalFormat
df(UnicodeString("0000000000000000000",""),status
);
7189 if (U_FAILURE(status
)) {
7190 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
7192 int64_t long_number
= U_INT64_MIN
+ 1;
7193 UnicodeString expect
= "-9223372036854775807";
7194 UnicodeString result
;
7196 df
.format(long_number
, result
, pos
);
7197 if(U_FAILURE(status
)||expect
!=result
) {
7198 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on -9223372036854775807",
7199 __FILE__
, __LINE__
, CStr(expect
)(), CStr(result
)(), u_errorName(status
));
7201 logln("OK: got expected '"+result
+"' status "+UnicodeString(u_errorName(status
),"")+" on -9223372036854775807");
7208 void NumberFormatTest::TestFormattableSize(void) {
7209 if(sizeof(Formattable
) > 112) {
7210 errln("Error: sizeof(Formattable)=%d, 112=%d\n",
7211 sizeof(Formattable
), 112);
7212 } else if(sizeof(Formattable
) < 112) {
7213 logln("Warning: sizeof(Formattable)=%d, 112=%d\n",
7214 sizeof(Formattable
), 112);
7216 logln("sizeof(Formattable)=%d, 112=%d\n",
7217 sizeof(Formattable
), 112);
7221 UBool
NumberFormatTest::testFormattableAsUFormattable(const char *file
, int line
, Formattable
&f
) {
7222 UnicodeString fileLine
= UnicodeString(file
)+UnicodeString(":")+line
+UnicodeString(": ");
7224 UFormattable
*u
= f
.toUFormattable();
7227 errln("%s:%d: Error: f.toUFormattable() retuned NULL.");
7230 logln("%s:%d: comparing Formattable with UFormattable", file
, line
);
7231 logln(fileLine
+ toString(f
));
7233 UErrorCode status
= U_ZERO_ERROR
;
7234 UErrorCode valueStatus
= U_ZERO_ERROR
;
7235 UFormattableType expectUType
= UFMT_COUNT
; // invalid
7237 UBool triedExact
= FALSE
; // did we attempt an exact comparison?
7238 UBool exactMatch
= FALSE
; // was the exact comparison true?
7240 switch( f
.getType() ) {
7241 case Formattable::kDate
:
7242 expectUType
= UFMT_DATE
;
7243 exactMatch
= (f
.getDate()==ufmt_getDate(u
, &valueStatus
));
7246 case Formattable::kDouble
:
7247 expectUType
= UFMT_DOUBLE
;
7248 exactMatch
= (f
.getDouble()==ufmt_getDouble(u
, &valueStatus
));
7251 case Formattable::kLong
:
7252 expectUType
= UFMT_LONG
;
7253 exactMatch
= (f
.getLong()==ufmt_getLong(u
, &valueStatus
));
7256 case Formattable::kString
:
7257 expectUType
= UFMT_STRING
;
7262 const UChar
* uch
= ufmt_getUChars(u
, &len
, &valueStatus
);
7263 if(U_SUCCESS(valueStatus
)) {
7264 UnicodeString
str2(uch
, len
);
7265 assertTrue("UChar* NULL-terminated", uch
[len
]==0);
7266 exactMatch
= (str
== str2
);
7271 case Formattable::kArray
:
7272 expectUType
= UFMT_ARRAY
;
7275 int32_t count
= ufmt_getArrayLength(u
, &valueStatus
);
7277 const Formattable
*array2
= f
.getArray(count2
);
7278 exactMatch
= assertEquals(fileLine
+ " array count", count
, count2
);
7281 for(int i
=0;U_SUCCESS(valueStatus
) && i
<count
;i
++) {
7282 UFormattable
*uu
= ufmt_getArrayItemByIndex(u
, i
, &valueStatus
);
7283 if(*Formattable::fromUFormattable(uu
) != (array2
[i
])) {
7284 errln("%s:%d: operator== did not match at index[%d] - %p vs %p", file
, line
, i
,
7285 (const void*)Formattable::fromUFormattable(uu
), (const void*)&(array2
[i
]));
7288 if(!testFormattableAsUFormattable("(sub item)",i
,*Formattable::fromUFormattable(uu
))) {
7296 case Formattable::kInt64
:
7297 expectUType
= UFMT_INT64
;
7298 exactMatch
= (f
.getInt64()==ufmt_getInt64(u
, &valueStatus
));
7301 case Formattable::kObject
:
7302 expectUType
= UFMT_OBJECT
;
7303 exactMatch
= (f
.getObject()==ufmt_getObject(u
, &valueStatus
));
7307 UFormattableType uType
= ufmt_getType(u
, &status
);
7309 if(U_FAILURE(status
)) {
7310 errln("%s:%d: Error calling ufmt_getType - %s", file
, line
, u_errorName(status
));
7314 if(uType
!= expectUType
) {
7315 errln("%s:%d: got type (%d) expected (%d) from ufmt_getType", file
, line
, (int) uType
, (int) expectUType
);
7319 if(U_FAILURE(valueStatus
)) {
7320 errln("%s:%d: got err %s trying to ufmt_get...() for exact match check", file
, line
, u_errorName(valueStatus
));
7321 } else if(!exactMatch
) {
7322 errln("%s:%d: failed exact match for the Formattable type", file
, line
);
7324 logln("%s:%d: exact match OK", file
, line
);
7327 logln("%s:%d: note, did not attempt exact match for this formattable type", file
, line
);
7330 if( assertEquals(fileLine
+ " isNumeric()", f
.isNumeric(), ufmt_isNumeric(u
))
7332 UErrorCode convStatus
= U_ZERO_ERROR
;
7334 if(uType
!= UFMT_INT64
) { // may fail to compare
7335 assertTrue(fileLine
+ " as doubles ==", f
.getDouble(convStatus
)==ufmt_getDouble(u
, &convStatus
));
7338 if( assertSuccess(fileLine
+ " (numeric conversion status)", convStatus
) ) {
7339 StringPiece fDecNum
= f
.getDecimalNumber(convStatus
);
7342 const char *decNumChars
= ufmt_getDecNumChars(u
, &len
, &convStatus
);
7345 char decNumChars
[200];
7346 int32_t len
= ufmt_getDecNumChars(u
, decNumChars
, 200, &convStatus
);
7349 if( assertSuccess(fileLine
+ " (decNumbers conversion)", convStatus
) ) {
7350 logln(fileLine
+ decNumChars
);
7351 assertEquals(fileLine
+ " decNumChars length==", len
, fDecNum
.length());
7352 assertEquals(fileLine
+ " decNumChars digits", decNumChars
, fDecNum
.data());
7355 UErrorCode int64ConversionF
= U_ZERO_ERROR
;
7356 int64_t l
= f
.getInt64(int64ConversionF
);
7357 UErrorCode int64ConversionU
= U_ZERO_ERROR
;
7358 int64_t r
= ufmt_getInt64(u
, &int64ConversionU
);
7361 && ( uType
!= UFMT_INT64
) // int64 better not overflow
7362 && (U_INVALID_FORMAT_ERROR
==int64ConversionU
)
7363 && (U_INVALID_FORMAT_ERROR
==int64ConversionF
) ) {
7364 logln("%s:%d: OK: 64 bit overflow", file
, line
);
7366 assertEquals(fileLine
+ " as int64 ==", l
, r
);
7367 assertSuccess(fileLine
+ " Formattable.getnt64()", int64ConversionF
);
7368 assertSuccess(fileLine
+ " ufmt_getInt64()", int64ConversionU
);
7372 return exactMatch
|| !triedExact
;
7375 void NumberFormatTest::TestUFormattable(void) {
7377 // test that a default formattable is equal to Formattable()
7378 UErrorCode status
= U_ZERO_ERROR
;
7379 LocalUFormattablePointer
defaultUFormattable(ufmt_open(&status
));
7380 assertSuccess("calling umt_open", status
);
7381 Formattable defaultFormattable
;
7382 assertTrue((UnicodeString
)"comparing ufmt_open() with Formattable()",
7384 == *(Formattable::fromUFormattable(defaultUFormattable
.getAlias()))));
7385 assertTrue((UnicodeString
)"comparing ufmt_open() with Formattable()",
7387 == *(Formattable::fromUFormattable(defaultUFormattable
.getAlias()))));
7388 assertTrue((UnicodeString
)"comparing Formattable() round tripped through UFormattable",
7390 == *(Formattable::fromUFormattable(defaultFormattable
.toUFormattable()))));
7391 assertTrue((UnicodeString
)"comparing &Formattable() round tripped through UFormattable",
7392 ((&defaultFormattable
)
7393 == Formattable::fromUFormattable(defaultFormattable
.toUFormattable())));
7394 assertFalse((UnicodeString
)"comparing &Formattable() with ufmt_open()",
7395 ((&defaultFormattable
)
7396 == Formattable::fromUFormattable(defaultUFormattable
.getAlias())));
7397 testFormattableAsUFormattable(__FILE__
, __LINE__
, defaultFormattable
);
7399 // test some random Formattables
7401 Formattable
f(ucal_getNow(), Formattable::kIsDate
);
7402 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7405 Formattable
f((double)1.61803398874989484820); // golden ratio
7406 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7409 Formattable
f((int64_t)80994231587905127LL); // weight of the moon, in kilotons http://solarsystem.nasa.gov/planets/profile.cfm?Display=Facts&Object=Moon
7410 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7413 Formattable
f((int32_t)4); // random number, source: http://www.xkcd.com/221/
7414 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7417 Formattable
f("Hello world."); // should be invariant?
7418 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7421 UErrorCode status2
= U_ZERO_ERROR
;
7422 Formattable
f(StringPiece("73476730924573500000000.0"), status2
); // weight of the moon, kg
7423 assertSuccess("Constructing a StringPiece", status2
);
7424 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7427 UErrorCode status2
= U_ZERO_ERROR
;
7428 UObject
*obj
= new Locale();
7430 assertSuccess("Constructing a Formattable from a default constructed Locale()", status2
);
7431 testFormattableAsUFormattable(__FILE__
, __LINE__
, f
);
7434 const Formattable array
[] = {
7435 Formattable(ucal_getNow(), Formattable::kIsDate
),
7436 Formattable((int32_t)4),
7437 Formattable((double)1.234),
7440 Formattable
fa(array
, 3);
7441 testFormattableAsUFormattable(__FILE__
, __LINE__
, fa
);
7445 void NumberFormatTest::TestSignificantDigits(void) {
7452 123.44501, -123.44501,
7453 0.001234, -0.001234,
7454 0.00000000123, -0.00000000123,
7455 0.0000000000000000000123, -0.0000000000000000000123,
7457 0.0000000012344501, -0.0000000012344501,
7458 123445.01, -123445.01,
7459 12344501000000000000000000000000000.0, -12344501000000000000000000000000000.0,
7461 const char* expected
[] = {
7466 "123.45", "-123.45",
7467 "123.45", "-123.45",
7468 "0.001234", "-0.001234",
7469 "0.00000000123", "-0.00000000123",
7470 "0.0000000000000000000123", "-0.0000000000000000000123",
7472 "0.0000000012345", "-0.0000000012345",
7473 "123450", "-123450",
7474 "12345000000000000000000000000000000", "-12345000000000000000000000000000000",
7477 UErrorCode status
= U_ZERO_ERROR
;
7478 Locale
locale("en_US");
7479 LocalPointer
<DecimalFormat
> numberFormat(static_cast<DecimalFormat
*>(
7480 NumberFormat::createInstance(locale
, status
)));
7481 CHECK_DATA(status
,"NumberFormat::createInstance")
7483 numberFormat
->setSignificantDigitsUsed(TRUE
);
7484 numberFormat
->setMinimumSignificantDigits(3);
7485 numberFormat
->setMaximumSignificantDigits(5);
7486 numberFormat
->setGroupingUsed(false);
7488 UnicodeString result
;
7489 UnicodeString expectedResult
;
7490 for (unsigned int i
= 0; i
< UPRV_LENGTHOF(input
); ++i
) {
7491 numberFormat
->format(input
[i
], result
);
7492 UnicodeString
expectedResult(expected
[i
]);
7493 if (result
!= expectedResult
) {
7494 errln((UnicodeString
)"Expected: '" + expectedResult
+ "' got '" + result
);
7499 // Test for ICU-20063
7501 DecimalFormat
df({"en-us", status
}, status
);
7502 df
.setSignificantDigitsUsed(TRUE
);
7503 expect(df
, 9.87654321, u
"9.87654");
7504 df
.setMaximumSignificantDigits(3);
7505 expect(df
, 9.87654321, u
"9.88");
7506 // setSignificantDigitsUsed with maxSig only
7507 df
.setSignificantDigitsUsed(TRUE
);
7508 expect(df
, 9.87654321, u
"9.88");
7509 df
.setMinimumSignificantDigits(2);
7510 expect(df
, 9, u
"9.0");
7511 // setSignificantDigitsUsed with both minSig and maxSig
7512 df
.setSignificantDigitsUsed(TRUE
);
7513 expect(df
, 9, u
"9.0");
7514 // setSignificantDigitsUsed to false: should revert to fraction rounding
7515 df
.setSignificantDigitsUsed(FALSE
);
7516 expect(df
, 9.87654321, u
"9.876543");
7517 expect(df
, 9, u
"9");
7518 df
.setSignificantDigitsUsed(TRUE
);
7519 df
.setMinimumSignificantDigits(2);
7520 expect(df
, 9.87654321, u
"9.87654");
7521 expect(df
, 9, u
"9.0");
7522 // setSignificantDigitsUsed with minSig only
7523 df
.setSignificantDigitsUsed(TRUE
);
7524 expect(df
, 9.87654321, u
"9.87654");
7525 expect(df
, 9, u
"9.0");
7529 void NumberFormatTest::TestShowZero() {
7530 UErrorCode status
= U_ZERO_ERROR
;
7531 Locale
locale("en_US");
7532 LocalPointer
<DecimalFormat
> numberFormat(static_cast<DecimalFormat
*>(
7533 NumberFormat::createInstance(locale
, status
)));
7534 CHECK_DATA(status
, "NumberFormat::createInstance")
7536 numberFormat
->setSignificantDigitsUsed(TRUE
);
7537 numberFormat
->setMaximumSignificantDigits(3);
7539 UnicodeString result
;
7540 numberFormat
->format(0.0, result
);
7541 if (result
!= "0") {
7542 errln((UnicodeString
)"Expected: 0, got " + result
);
7546 void NumberFormatTest::TestBug9936() {
7547 UErrorCode status
= U_ZERO_ERROR
;
7548 Locale
locale("en_US");
7549 LocalPointer
<DecimalFormat
> numberFormat(static_cast<DecimalFormat
*>(
7550 NumberFormat::createInstance(locale
, status
)));
7551 if (U_FAILURE(status
)) {
7552 dataerrln("File %s, Line %d: status = %s.\n", __FILE__
, __LINE__
, u_errorName(status
));
7556 if (numberFormat
->areSignificantDigitsUsed() == TRUE
) {
7557 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__
, __LINE__
);
7559 numberFormat
->setSignificantDigitsUsed(TRUE
);
7560 if (numberFormat
->areSignificantDigitsUsed() == FALSE
) {
7561 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__
, __LINE__
);
7564 numberFormat
->setSignificantDigitsUsed(FALSE
);
7565 if (numberFormat
->areSignificantDigitsUsed() == TRUE
) {
7566 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__
, __LINE__
);
7569 numberFormat
->setMinimumSignificantDigits(3);
7570 if (numberFormat
->areSignificantDigitsUsed() == FALSE
) {
7571 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__
, __LINE__
);
7574 numberFormat
->setSignificantDigitsUsed(FALSE
);
7575 numberFormat
->setMaximumSignificantDigits(6);
7576 if (numberFormat
->areSignificantDigitsUsed() == FALSE
) {
7577 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__
, __LINE__
);
7582 void NumberFormatTest::TestParseNegativeWithFaLocale() {
7583 UErrorCode status
= U_ZERO_ERROR
;
7584 DecimalFormat
*test
= (DecimalFormat
*) NumberFormat::createInstance("fa", status
);
7585 CHECK_DATA(status
, "NumberFormat::createInstance")
7586 test
->setLenient(TRUE
);
7589 UnicodeString
value("\\u200e-0,5");
7590 value
= value
.unescape();
7591 test
->parse(value
, af
, ppos
);
7592 if (ppos
.getIndex() == 0) {
7593 errln("Expected -0,5 to parse for Farsi.");
7598 void NumberFormatTest::TestParseNegativeWithAlternateMinusSign() {
7599 UErrorCode status
= U_ZERO_ERROR
;
7600 DecimalFormat
*test
= (DecimalFormat
*) NumberFormat::createInstance("en", status
);
7601 CHECK_DATA(status
, "NumberFormat::createInstance")
7602 test
->setLenient(TRUE
);
7605 UnicodeString
value("\\u208B0.5");
7606 value
= value
.unescape();
7607 test
->parse(value
, af
, ppos
);
7608 if (ppos
.getIndex() == 0) {
7609 errln(UnicodeString("Expected ") + value
+ UnicodeString(" to parse."));
7614 void NumberFormatTest::TestCustomCurrencySignAndSeparator() {
7615 UErrorCode status
= U_ZERO_ERROR
;
7616 DecimalFormatSymbols
custom(Locale::getUS(), status
);
7617 CHECK(status
, "DecimalFormatSymbols constructor");
7619 custom
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "*");
7620 custom
.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
, "^");
7621 custom
.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, ":");
7623 UnicodeString
pat(" #,##0.00");
7624 pat
.insert(0, (UChar
)0x00A4);
7626 DecimalFormat
fmt(pat
, custom
, status
);
7627 CHECK(status
, "DecimalFormat constructor");
7629 UnicodeString
numstr("* 1^234:56");
7630 expect2(fmt
, (Formattable
)((double)1234.56), numstr
);
7634 const char * locale
;
7636 UnicodeString numString
;
7638 } SignsAndMarksItem
;
7641 void NumberFormatTest::TestParseSignsAndMarks() {
7642 const SignsAndMarksItem items
[] = {
7643 // locale lenient numString value
7644 { "en", FALSE
, CharsToUnicodeString("12"), 12 },
7645 { "en", TRUE
, CharsToUnicodeString("12"), 12 },
7646 { "en", FALSE
, CharsToUnicodeString("-23"), -23 },
7647 { "en", TRUE
, CharsToUnicodeString("-23"), -23 },
7648 { "en", TRUE
, CharsToUnicodeString("- 23"), -23 },
7649 { "en", FALSE
, CharsToUnicodeString("\\u200E-23"), -23 },
7650 { "en", TRUE
, CharsToUnicodeString("\\u200E-23"), -23 },
7651 { "en", TRUE
, CharsToUnicodeString("\\u200E- 23"), -23 },
7653 { "en@numbers=arab", FALSE
, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7654 { "en@numbers=arab", TRUE
, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7655 { "en@numbers=arab", FALSE
, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7656 { "en@numbers=arab", TRUE
, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7657 { "en@numbers=arab", TRUE
, CharsToUnicodeString("- \\u0664\\u0665"), -45 },
7658 { "en@numbers=arab", FALSE
, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7659 { "en@numbers=arab", TRUE
, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7660 { "en@numbers=arab", TRUE
, CharsToUnicodeString("\\u200F- \\u0664\\u0665"), -45 },
7662 { "en@numbers=arabext", FALSE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7663 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7664 { "en@numbers=arabext", FALSE
, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7665 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7666 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("- \\u06F6\\u06F7"), -67 },
7667 { "en@numbers=arabext", FALSE
, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7668 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7669 { "en@numbers=arabext", TRUE
, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 },
7671 { "he", FALSE
, CharsToUnicodeString("12"), 12 },
7672 { "he", TRUE
, CharsToUnicodeString("12"), 12 },
7673 { "he", FALSE
, CharsToUnicodeString("-23"), -23 },
7674 { "he", TRUE
, CharsToUnicodeString("-23"), -23 },
7675 { "he", TRUE
, CharsToUnicodeString("- 23"), -23 },
7676 { "he", FALSE
, CharsToUnicodeString("\\u200E-23"), -23 },
7677 { "he", TRUE
, CharsToUnicodeString("\\u200E-23"), -23 },
7678 { "he", TRUE
, CharsToUnicodeString("\\u200E- 23"), -23 },
7680 { "ar", FALSE
, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7681 { "ar", TRUE
, CharsToUnicodeString("\\u0663\\u0664"), 34 },
7682 { "ar", FALSE
, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7683 { "ar", TRUE
, CharsToUnicodeString("-\\u0664\\u0665"), -45 },
7684 { "ar", TRUE
, CharsToUnicodeString("- \\u0664\\u0665"), -45 },
7685 { "ar", FALSE
, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7686 { "ar", TRUE
, CharsToUnicodeString("\\u200F-\\u0664\\u0665"), -45 },
7687 { "ar", TRUE
, CharsToUnicodeString("\\u200F- \\u0664\\u0665"), -45 },
7689 { "ar_MA", FALSE
, CharsToUnicodeString("12"), 12 },
7690 { "ar_MA", TRUE
, CharsToUnicodeString("12"), 12 },
7691 { "ar_MA", FALSE
, CharsToUnicodeString("-23"), -23 },
7692 { "ar_MA", TRUE
, CharsToUnicodeString("-23"), -23 },
7693 { "ar_MA", TRUE
, CharsToUnicodeString("- 23"), -23 },
7694 { "ar_MA", FALSE
, CharsToUnicodeString("\\u200E-23"), -23 },
7695 { "ar_MA", TRUE
, CharsToUnicodeString("\\u200E-23"), -23 },
7696 { "ar_MA", TRUE
, CharsToUnicodeString("\\u200E- 23"), -23 },
7698 { "fa", FALSE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7699 { "fa", TRUE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7700 { "fa", FALSE
, CharsToUnicodeString("\\u2212\\u06F6\\u06F7"), -67 },
7701 { "fa", TRUE
, CharsToUnicodeString("\\u2212\\u06F6\\u06F7"), -67 },
7702 { "fa", TRUE
, CharsToUnicodeString("\\u2212 \\u06F6\\u06F7"), -67 },
7703 { "fa", FALSE
, CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"), -67 },
7704 { "fa", TRUE
, CharsToUnicodeString("\\u200E\\u2212\\u200E\\u06F6\\u06F7"), -67 },
7705 { "fa", TRUE
, CharsToUnicodeString("\\u200E\\u2212\\u200E \\u06F6\\u06F7"), -67 },
7707 { "ps", FALSE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7708 { "ps", TRUE
, CharsToUnicodeString("\\u06F5\\u06F6"), 56 },
7709 { "ps", FALSE
, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7710 { "ps", TRUE
, CharsToUnicodeString("-\\u06F6\\u06F7"), -67 },
7711 { "ps", TRUE
, CharsToUnicodeString("- \\u06F6\\u06F7"), -67 },
7712 { "ps", FALSE
, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7713 { "ps", TRUE
, CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"), -67 },
7714 { "ps", TRUE
, CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"), -67 },
7715 { "ps", FALSE
, CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"), -67 },
7716 { "ps", TRUE
, CharsToUnicodeString("-\\u200E\\u06F6\\u06F7"), -67 },
7717 { "ps", TRUE
, CharsToUnicodeString("-\\u200E \\u06F6\\u06F7"), -67 },
7719 { NULL
, 0, UnicodeString(""), 0 },
7722 const SignsAndMarksItem
* itemPtr
;
7723 for (itemPtr
= items
; itemPtr
->locale
!= NULL
; itemPtr
++ ) {
7724 UErrorCode status
= U_ZERO_ERROR
;
7725 NumberFormat
*numfmt
= NumberFormat::createInstance(Locale(itemPtr
->locale
), status
);
7726 if (U_SUCCESS(status
)) {
7727 numfmt
->setLenient(itemPtr
->lenient
);
7730 numfmt
->parse(itemPtr
->numString
, fmtobj
, ppos
);
7731 if (ppos
.getIndex() == itemPtr
->numString
.length()) {
7732 double parsedValue
= fmtobj
.getDouble(status
);
7733 if (U_FAILURE(status
) || parsedValue
!= itemPtr
->value
) {
7734 errln((UnicodeString
)"FAIL: locale " + itemPtr
->locale
+ ", lenient " + itemPtr
->lenient
+ ", parse of \"" + itemPtr
->numString
+ "\" gives value " + parsedValue
);
7737 errln((UnicodeString
)"FAIL: locale " + itemPtr
->locale
+ ", lenient " + itemPtr
->lenient
+ ", parse of \"" + itemPtr
->numString
+ "\" gives position " + ppos
.getIndex());
7740 dataerrln("FAIL: NumberFormat::createInstance for locale % gives error %s", itemPtr
->locale
, u_errorName(status
));
7747 DecimalFormat::ERoundingMode mode
;
7749 UnicodeString expected
;
7753 // Tests that rounding works right when fractional digits is set to 0.
7754 void NumberFormatTest::Test10419RoundingWith0FractionDigits() {
7755 const Test10419Data items
[] = {
7756 { DecimalFormat::kRoundCeiling
, 1.488, "2"},
7757 { DecimalFormat::kRoundDown
, 1.588, "1"},
7758 { DecimalFormat::kRoundFloor
, 1.888, "1"},
7759 { DecimalFormat::kRoundHalfDown
, 1.5, "1"},
7760 { DecimalFormat::kRoundHalfEven
, 2.5, "2"},
7761 { DecimalFormat::kRoundHalfUp
, 2.5, "3"},
7762 { DecimalFormat::kRoundUp
, 1.5, "2"},
7764 UErrorCode status
= U_ZERO_ERROR
;
7765 LocalPointer
<DecimalFormat
> decfmt((DecimalFormat
*) NumberFormat::createInstance(Locale("en_US"), status
));
7766 if (U_FAILURE(status
)) {
7767 dataerrln("Failure creating DecimalFormat %s", u_errorName(status
));
7770 for (int32_t i
= 0; i
< UPRV_LENGTHOF(items
); ++i
) {
7771 decfmt
->setRoundingMode(items
[i
].mode
);
7772 decfmt
->setMaximumFractionDigits(0);
7773 UnicodeString actual
;
7774 if (items
[i
].expected
!= decfmt
->format(items
[i
].value
, actual
)) {
7775 errln("Expected " + items
[i
].expected
+ ", got " + actual
);
7780 void NumberFormatTest::Test10468ApplyPattern() {
7781 // Padding char of fmt is now 'a'
7782 UErrorCode status
= U_ZERO_ERROR
;
7783 DecimalFormat
fmt("'I''ll'*a###.##", status
);
7785 if (U_FAILURE(status
)) {
7786 errcheckln(status
, "DecimalFormat constructor failed - %s", u_errorName(status
));
7790 assertEquals("Padding character should be 'a'.", u
"a", fmt
.getPadCharacterString());
7792 // Padding char of fmt ought to be '*' since that is the default and no
7793 // explicit padding char is specified in the new pattern.
7794 fmt
.applyPattern("AA#,##0.00ZZ", status
);
7796 // Oops this still prints 'a' even though we changed the pattern.
7797 assertEquals("applyPattern did not clear padding character.", u
" ", fmt
.getPadCharacterString());
7800 void NumberFormatTest::TestRoundingScientific10542() {
7801 UErrorCode status
= U_ZERO_ERROR
;
7802 DecimalFormat
format("0.00E0", status
);
7803 if (U_FAILURE(status
)) {
7804 errcheckln(status
, "DecimalFormat constructor failed - %s", u_errorName(status
));
7808 DecimalFormat::ERoundingMode roundingModes
[] = {
7809 DecimalFormat::kRoundCeiling
,
7810 DecimalFormat::kRoundDown
,
7811 DecimalFormat::kRoundFloor
,
7812 DecimalFormat::kRoundHalfDown
,
7813 DecimalFormat::kRoundHalfEven
,
7814 DecimalFormat::kRoundHalfUp
,
7815 DecimalFormat::kRoundUp
};
7816 const char *descriptions
[] = {
7826 double values
[] = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016};
7827 // The order of these expected values correspond to the order of roundingModes and the order of values.
7828 const char *expected
[] = {
7829 "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.02E-3", "3.02E-3", "3.02E-3",
7830 "-3.00E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.01E-3",
7831 "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.01E-3", "3.01E-3", "3.01E-3",
7832 "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.02E-3",
7833 "-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3",
7834 "-3.01E-3", "-3.01E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3",
7835 "-3.01E-3", "-3.01E-3", "-3.01E-3", "3.02E-3", "3.02E-3", "3.02E-3"};
7842 UPRV_LENGTHOF(values
),
7843 UPRV_LENGTHOF(roundingModes
));
7846 double values
[] = {-3006.0, -3005, -3004, 3014, 3015, 3016};
7847 // The order of these expected values correspond to the order of roundingModes and the order of values.
7848 const char *expected
[] = {
7849 "-3.00E3", "-3.00E3", "-3.00E3", "3.02E3", "3.02E3", "3.02E3",
7850 "-3.00E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.01E3",
7851 "-3.01E3", "-3.01E3", "-3.01E3", "3.01E3", "3.01E3", "3.01E3",
7852 "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.02E3",
7853 "-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3",
7854 "-3.01E3", "-3.01E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3",
7855 "-3.01E3", "-3.01E3", "-3.01E3", "3.02E3", "3.02E3", "3.02E3"};
7862 UPRV_LENGTHOF(values
),
7863 UPRV_LENGTHOF(roundingModes
));
7865 /* Commented out for now until we decide how rounding to zero should work, +0 vs. -0
7867 double values[] = {0.0, -0.0};
7868 // The order of these expected values correspond to the order of roundingModes and the order of values.
7869 const char *expected[] = {
7870 "0.00E0", "-0.00E0",
7871 "0.00E0", "-0.00E0",
7872 "0.00E0", "-0.00E0",
7873 "0.00E0", "-0.00E0",
7874 "0.00E0", "-0.00E0",
7875 "0.00E0", "-0.00E0",
7876 "0.00E0", "-0.00E0"};
7883 UPRV_LENGTHOF(values),
7884 UPRV_LENGTHOF(roundingModes));
7889 double values
[] = {1e25
, 1e25
+ 1e15
, 1e25
- 1e15
};
7890 // The order of these expected values correspond to the order of roundingModes and the order of values.
7891 const char *expected
[] = {
7892 "1.00E25", "1.01E25", "1.00E25",
7893 "1.00E25", "1.00E25", "9.99E24",
7894 "1.00E25", "1.00E25", "9.99E24",
7895 "1.00E25", "1.00E25", "1.00E25",
7896 "1.00E25", "1.00E25", "1.00E25",
7897 "1.00E25", "1.00E25", "1.00E25",
7898 "1.00E25", "1.01E25", "1.00E25"};
7905 UPRV_LENGTHOF(values
),
7906 UPRV_LENGTHOF(roundingModes
));
7909 double values
[] = {-1e25
, -1e25
+ 1e15
, -1e25
- 1e15
};
7910 // The order of these expected values correspond to the order of roundingModes and the order of values.
7911 const char *expected
[] = {
7912 "-1.00E25", "-9.99E24", "-1.00E25",
7913 "-1.00E25", "-9.99E24", "-1.00E25",
7914 "-1.00E25", "-1.00E25", "-1.01E25",
7915 "-1.00E25", "-1.00E25", "-1.00E25",
7916 "-1.00E25", "-1.00E25", "-1.00E25",
7917 "-1.00E25", "-1.00E25", "-1.00E25",
7918 "-1.00E25", "-1.00E25", "-1.01E25"};
7925 UPRV_LENGTHOF(values
),
7926 UPRV_LENGTHOF(roundingModes
));
7929 double values
[] = {1e-25, 1e-25 + 1e-35, 1e-25 - 1e-35};
7930 // The order of these expected values correspond to the order of roundingModes and the order of values.
7931 const char *expected
[] = {
7932 "1.00E-25", "1.01E-25", "1.00E-25",
7933 "1.00E-25", "1.00E-25", "9.99E-26",
7934 "1.00E-25", "1.00E-25", "9.99E-26",
7935 "1.00E-25", "1.00E-25", "1.00E-25",
7936 "1.00E-25", "1.00E-25", "1.00E-25",
7937 "1.00E-25", "1.00E-25", "1.00E-25",
7938 "1.00E-25", "1.01E-25", "1.00E-25"};
7945 UPRV_LENGTHOF(values
),
7946 UPRV_LENGTHOF(roundingModes
));
7949 double values
[] = {-1e-25, -1e-25 + 1e-35, -1e-25 - 1e-35};
7950 // The order of these expected values correspond to the order of roundingModes and the order of values.
7951 const char *expected
[] = {
7952 "-1.00E-25", "-9.99E-26", "-1.00E-25",
7953 "-1.00E-25", "-9.99E-26", "-1.00E-25",
7954 "-1.00E-25", "-1.00E-25", "-1.01E-25",
7955 "-1.00E-25", "-1.00E-25", "-1.00E-25",
7956 "-1.00E-25", "-1.00E-25", "-1.00E-25",
7957 "-1.00E-25", "-1.00E-25", "-1.00E-25",
7958 "-1.00E-25", "-1.00E-25", "-1.01E-25"};
7965 UPRV_LENGTHOF(values
),
7966 UPRV_LENGTHOF(roundingModes
));
7970 void NumberFormatTest::TestZeroScientific10547() {
7971 UErrorCode status
= U_ZERO_ERROR
;
7972 DecimalFormat
fmt("0.00E0", status
);
7973 if (!assertSuccess("Format creation", status
)) {
7977 fmt
.format(-0.0, out
);
7978 assertEquals("format", "-0.00E0", out
, true);
7981 void NumberFormatTest::verifyRounding(
7982 DecimalFormat
& format
,
7983 const double *values
,
7984 const char * const *expected
,
7985 const DecimalFormat::ERoundingMode
*roundingModes
,
7986 const char * const *descriptions
,
7988 int32_t roundingModeSize
) {
7989 for (int32_t i
= 0; i
< roundingModeSize
; ++i
) {
7990 format
.setRoundingMode(roundingModes
[i
]);
7991 for (int32_t j
= 0; j
< valueSize
; j
++) {
7992 UnicodeString
currentExpected(expected
[i
* valueSize
+ j
]);
7993 currentExpected
= currentExpected
.unescape();
7994 UnicodeString actual
;
7995 format
.format(values
[j
], actual
);
7996 if (currentExpected
!= actual
) {
7997 dataerrln("For %s value %f, expected '%s', got '%s'",
7998 descriptions
[i
], values
[j
], CStr(currentExpected
)(), CStr(actual
)());
8004 void NumberFormatTest::TestAccountingCurrency() {
8005 UErrorCode status
= U_ZERO_ERROR
;
8006 UNumberFormatStyle style
= UNUM_CURRENCY_ACCOUNTING
;
8008 expect(NumberFormat::createInstance("en_US", style
, status
),
8009 (Formattable
)(double)1234.5, "$1,234.50", TRUE
, status
);
8010 expect(NumberFormat::createInstance("en_US", style
, status
),
8011 (Formattable
)(double)-1234.5, "($1,234.50)", TRUE
, status
);
8012 expect(NumberFormat::createInstance("en_US", style
, status
),
8013 (Formattable
)(double)0, "$0.00", TRUE
, status
);
8014 expect(NumberFormat::createInstance("en_US", style
, status
),
8015 (Formattable
)(double)-0.2, "($0.20)", TRUE
, status
);
8016 expect(NumberFormat::createInstance("ja_JP", style
, status
),
8017 (Formattable
)10000, UnicodeString("\\u00A510,000").unescape(), TRUE
, status
);
8018 expect(NumberFormat::createInstance("ja_JP", style
, status
),
8019 (Formattable
)-1000.5, UnicodeString("(\\u00A51,000)").unescape(), FALSE
, status
);
8020 expect(NumberFormat::createInstance("de_DE", style
, status
),
8021 (Formattable
)(double)-23456.7, UnicodeString("-23.456,70\\u00A0\\u20AC").unescape(), TRUE
, status
);
8025 void NumberFormatTest::TestEquality() {
8026 UErrorCode status
= U_ZERO_ERROR
;
8027 DecimalFormatSymbols
symbols(Locale("root"), status
);
8028 if (U_FAILURE(status
)) {
8029 dataerrln("Fail: can't create DecimalFormatSymbols for root");
8032 UnicodeString
pattern("#,##0.###");
8033 DecimalFormat
fmtBase(pattern
, symbols
, status
);
8034 if (U_FAILURE(status
)) {
8035 dataerrln("Fail: can't create DecimalFormat using root symbols");
8039 DecimalFormat
* fmtClone
= (DecimalFormat
*)fmtBase
.clone();
8040 fmtClone
->setFormatWidth(fmtBase
.getFormatWidth() + 32);
8041 if (*fmtClone
== fmtBase
) {
8042 errln("Error: DecimalFormat == does not distinguish objects that differ only in FormatWidth");
8047 void NumberFormatTest::TestCurrencyUsage() {
8048 double agent
= 123.567;
8053 // compare the Currency and Currency Cash Digits
8054 // Note that as of CLDR 26:
8055 // * TWD and PKR switched from 0 decimals to 2; ISK still has 0, so change test to that.
8056 // * (PKR must have switched back again, because it switched from 0 to 2 again in CLDR 34;
8057 // Apple ICU-64243 restores it to 0 again)
8058 // * CAD rounds to .05 in cash mode only
8059 // 1st time for getter/setter, 2nd time for factory method
8060 Locale
enUS_ISK("en_US@currency=ISK");
8062 for(int i
=0; i
<2; i
++){
8063 status
= U_ZERO_ERROR
;
8065 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_ISK
, UNUM_CURRENCY
, status
);
8066 if (assertSuccess("en_US@currency=ISK/CURRENCY", status
, TRUE
) == FALSE
) {
8070 UnicodeString original
;
8071 fmt
->format(agent
,original
);
8072 assertEquals("Test Currency Usage 1", u
"ISK\u00A0124", original
);
8074 // test the getter here
8075 UCurrencyUsage curUsage
= fmt
->getCurrencyUsage();
8076 assertEquals("Test usage getter - standard", (int32_t)curUsage
, (int32_t)UCURR_USAGE_STANDARD
);
8078 fmt
->setCurrencyUsage(UCURR_USAGE_CASH
, &status
);
8080 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_ISK
, UNUM_CASH_CURRENCY
, status
);
8081 if (assertSuccess("en_US@currency=ISK/CASH", status
, TRUE
) == FALSE
) {
8086 // must be usage = cash
8087 UCurrencyUsage curUsage
= fmt
->getCurrencyUsage();
8088 assertEquals("Test usage getter - cash", (int32_t)curUsage
, (int32_t)UCURR_USAGE_CASH
);
8090 UnicodeString cash_currency
;
8091 fmt
->format(agent
,cash_currency
);
8092 assertEquals("Test Currency Usage 2", u
"ISK\u00A0124", cash_currency
);
8096 // compare the Currency and Currency Cash Rounding
8097 // 1st time for getter/setter, 2nd time for factory method
8098 Locale
enUS_CAD("en_US@currency=CAD");
8099 for(int i
=0; i
<2; i
++){
8100 status
= U_ZERO_ERROR
;
8102 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_CAD
, UNUM_CURRENCY
, status
);
8103 if (assertSuccess("en_US@currency=CAD/CURRENCY", status
, TRUE
) == FALSE
) {
8107 UnicodeString original_rounding
;
8108 fmt
->format(agent
, original_rounding
);
8109 assertEquals("Test Currency Usage 3", u
"CA$123.57", original_rounding
);
8110 fmt
->setCurrencyUsage(UCURR_USAGE_CASH
, &status
);
8112 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_CAD
, UNUM_CASH_CURRENCY
, status
);
8113 if (assertSuccess("en_US@currency=CAD/CASH", status
, TRUE
) == FALSE
) {
8118 UnicodeString cash_rounding_currency
;
8119 fmt
->format(agent
, cash_rounding_currency
);
8120 assertEquals("Test Currency Usage 4", u
"CA$123.55", cash_rounding_currency
);
8124 // Test the currency change
8125 // 1st time for getter/setter, 2nd time for factory method
8126 const UChar CUR_PKR
[] = {0x50, 0x4B, 0x52, 0};
8127 for(int i
=0; i
<2; i
++){
8128 status
= U_ZERO_ERROR
;
8130 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_CAD
, UNUM_CURRENCY
, status
);
8131 if (assertSuccess("en_US@currency=CAD/CURRENCY", status
, TRUE
) == FALSE
) {
8134 fmt
->setCurrencyUsage(UCURR_USAGE_CASH
, &status
);
8136 fmt
= (DecimalFormat
*) NumberFormat::createInstance(enUS_CAD
, UNUM_CASH_CURRENCY
, status
);
8137 if (assertSuccess("en_US@currency=CAD/CASH", status
, TRUE
) == FALSE
) {
8142 UnicodeString cur_original
;
8143 fmt
->setCurrencyUsage(UCURR_USAGE_STANDARD
, &status
);
8144 fmt
->format(agent
, cur_original
);
8145 assertEquals("Test Currency Usage 5", u
"CA$123.57", cur_original
);
8147 fmt
->setCurrency(CUR_PKR
, status
);
8148 assertSuccess("Set currency to PKR", status
);
8150 UnicodeString PKR_changed
;
8151 fmt
->format(agent
, PKR_changed
);
8152 assertEquals("Test Currency Usage 6", u
"PKR\u00A0124", PKR_changed
);
8158 // Check the constant MAX_INT64_IN_DOUBLE.
8159 // The value should convert to a double with no loss of precision.
8160 // A failure may indicate a platform with a different double format, requiring
8161 // a revision to the constant.
8163 // Note that this is actually hard to test, because the language standard gives
8164 // compilers considerable flexibility to do unexpected things with rounding and
8165 // with overflow in simple int to/from float conversions. Some compilers will completely optimize
8166 // away a simple round-trip conversion from int64_t -> double -> int64_t.
8168 void NumberFormatTest::TestDoubleLimit11439() {
8170 for (int64_t num
= MAX_INT64_IN_DOUBLE
-10; num
<=MAX_INT64_IN_DOUBLE
; num
++) {
8171 sprintf(buf
, "%lld", (long long)num
);
8173 sscanf(buf
, "%lf", &fNum
);
8174 int64_t rtNum
= static_cast<int64_t>(fNum
);
8176 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__
, __LINE__
, (long long)num
, (long long)rtNum
);
8180 for (int64_t num
= -MAX_INT64_IN_DOUBLE
+10; num
>=-MAX_INT64_IN_DOUBLE
; num
--) {
8181 sprintf(buf
, "%lld", (long long)num
);
8183 sscanf(buf
, "%lf", &fNum
);
8184 int64_t rtNum
= static_cast<int64_t>(fNum
);
8186 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__
, __LINE__
, (long long)num
, (long long)rtNum
);
8192 void NumberFormatTest::TestGetAffixes() {
8193 UErrorCode status
= U_ZERO_ERROR
;
8194 DecimalFormatSymbols
sym("en_US", status
);
8195 UnicodeString
pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
8196 pattern
= pattern
.unescape();
8197 DecimalFormat
fmt(pattern
, sym
, status
);
8198 if (U_FAILURE(status
)) {
8199 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
8202 UnicodeString affixStr
;
8203 assertEquals("", "US dollars ", fmt
.getPositivePrefix(affixStr
));
8204 assertEquals("", " %USD", fmt
.getPositiveSuffix(affixStr
));
8205 assertEquals("", "-US dollars ", fmt
.getNegativePrefix(affixStr
));
8206 assertEquals("", " %USD", fmt
.getNegativeSuffix(affixStr
));
8208 // Test equality with affixes. set affix methods can't capture special
8209 // characters which is why equality should fail.
8211 DecimalFormat
fmtCopy(fmt
);
8212 assertTrue("", fmt
== fmtCopy
);
8213 UnicodeString someAffix
;
8214 fmtCopy
.setPositivePrefix(fmtCopy
.getPositivePrefix(someAffix
));
8215 assertTrue("", fmt
!= fmtCopy
);
8218 DecimalFormat
fmtCopy(fmt
);
8219 assertTrue("", fmt
== fmtCopy
);
8220 UnicodeString someAffix
;
8221 fmtCopy
.setPositiveSuffix(fmtCopy
.getPositiveSuffix(someAffix
));
8222 assertTrue("", fmt
!= fmtCopy
);
8225 DecimalFormat
fmtCopy(fmt
);
8226 assertTrue("", fmt
== fmtCopy
);
8227 UnicodeString someAffix
;
8228 fmtCopy
.setNegativePrefix(fmtCopy
.getNegativePrefix(someAffix
));
8229 assertTrue("", fmt
!= fmtCopy
);
8232 DecimalFormat
fmtCopy(fmt
);
8233 assertTrue("", fmt
== fmtCopy
);
8234 UnicodeString someAffix
;
8235 fmtCopy
.setNegativeSuffix(fmtCopy
.getNegativeSuffix(someAffix
));
8236 assertTrue("", fmt
!= fmtCopy
);
8238 fmt
.setPositivePrefix("Don't");
8239 fmt
.setPositiveSuffix("do");
8240 UnicodeString
someAffix("be''eet\\u00a4\\u00a4\\u00a4 it.");
8241 someAffix
= someAffix
.unescape();
8242 fmt
.setNegativePrefix(someAffix
);
8243 fmt
.setNegativeSuffix("%");
8244 assertEquals("", "Don't", fmt
.getPositivePrefix(affixStr
));
8245 assertEquals("", "do", fmt
.getPositiveSuffix(affixStr
));
8246 assertEquals("", someAffix
, fmt
.getNegativePrefix(affixStr
));
8247 assertEquals("", "%", fmt
.getNegativeSuffix(affixStr
));
8250 void NumberFormatTest::TestToPatternScientific11648() {
8251 UErrorCode status
= U_ZERO_ERROR
;
8253 DecimalFormatSymbols
sym(en
, status
);
8254 DecimalFormat
fmt("0.00", sym
, status
);
8255 if (U_FAILURE(status
)) {
8256 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
8259 fmt
.setScientificNotation(TRUE
);
8260 UnicodeString pattern
;
8261 assertEquals("", "0.00E0", fmt
.toPattern(pattern
));
8262 DecimalFormat
fmt2(pattern
, sym
, status
);
8263 assertSuccess("", status
);
8266 void NumberFormatTest::TestBenchmark() {
8268 UErrorCode status = U_ZERO_ERROR;
8270 DecimalFormatSymbols sym(en, status);
8271 DecimalFormat fmt("0.0000000", new DecimalFormatSymbols(sym), status);
8272 // DecimalFormat fmt("0.00000E0", new DecimalFormatSymbols(sym), status);
8273 // DecimalFormat fmt("0", new DecimalFormatSymbols(sym), status);
8274 FieldPosition fpos(FieldPosition::DONT_CARE);
8275 clock_t start = clock();
8276 for (int32_t i = 0; i < 1000000; ++i) {
8277 UnicodeString append;
8278 fmt.format(3.0, append, fpos, status);
8279 // fmt.format(4.6692016, append, fpos, status);
8280 // fmt.format(1234567.8901, append, fpos, status);
8281 // fmt.format(2.99792458E8, append, fpos, status);
8282 // fmt.format(31, append);
8284 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8285 assertSuccess("", status);
8287 UErrorCode status = U_ZERO_ERROR;
8288 MessageFormat fmt("{0, plural, one {I have # friend.} other {I have # friends.}}", status);
8289 FieldPosition fpos(FieldPosition::DONT_CARE);
8290 Formattable one(1.0);
8291 Formattable three(3.0);
8292 clock_t start = clock();
8293 for (int32_t i = 0; i < 500000; ++i) {
8294 UnicodeString append;
8295 fmt.format(&one, 1, append, fpos, status);
8296 UnicodeString append2;
8297 fmt.format(&three, 1, append2, fpos, status);
8299 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8300 assertSuccess("", status);
8302 UErrorCode status = U_ZERO_ERROR;
8304 Measure measureC(23, MeasureUnit::createCelsius(status), status);
8305 MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status);
8306 FieldPosition fpos(FieldPosition::DONT_CARE);
8307 clock_t start = clock();
8308 for (int32_t i = 0; i < 1000000; ++i) {
8309 UnicodeString appendTo;
8311 &measureC, 1, appendTo, fpos, status);
8313 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8314 assertSuccess("", status);
8318 void NumberFormatTest::TestFractionalDigitsForCurrency() {
8319 UErrorCode status
= U_ZERO_ERROR
;
8320 LocalPointer
<NumberFormat
> fmt(NumberFormat::createCurrencyInstance("en", status
));
8321 if (U_FAILURE(status
)) {
8322 dataerrln("Error creating NumberFormat - %s", u_errorName(status
));
8325 UChar JPY
[] = {0x4A, 0x50, 0x59, 0x0};
8326 fmt
->setCurrency(JPY
, status
);
8327 if (!assertSuccess("", status
)) {
8330 assertEquals("", 0, fmt
->getMaximumFractionDigits());
8334 void NumberFormatTest::TestFormatCurrencyPlural() {
8335 UErrorCode status
= U_ZERO_ERROR
;
8336 Locale locale
= Locale::createCanonical("en_US");
8337 NumberFormat
*fmt
= NumberFormat::createInstance(locale
, UNUM_CURRENCY_PLURAL
, status
);
8338 if (U_FAILURE(status
)) {
8339 dataerrln("Error creating NumberFormat - %s", u_errorName(status
));
8342 UnicodeString formattedNum
;
8343 fmt
->format(11234.567, formattedNum
, NULL
, status
);
8344 assertEquals("", "11,234.57 US dollars", formattedNum
);
8348 void NumberFormatTest::TestCtorApplyPatternDifference() {
8349 UErrorCode status
= U_ZERO_ERROR
;
8350 DecimalFormatSymbols
sym("en_US", status
);
8351 UnicodeString
pattern("\\u00a40");
8352 DecimalFormat
fmt(pattern
.unescape(), sym
, status
);
8353 if (U_FAILURE(status
)) {
8354 dataerrln("Error creating DecimalFormat - %s", u_errorName(status
));
8357 UnicodeString result
;
8359 "ctor favors precision of currency",
8361 fmt
.format((double)5, result
));
8363 fmt
.applyPattern(pattern
.unescape(), status
);
8365 "applyPattern favors precision of pattern",
8367 fmt
.format((double)5, result
));
8370 void NumberFormatTest::Test11868() {
8371 double posAmt
= 34.567;
8372 double negAmt
= -9876.543;
8374 Locale
selectedLocale("en_US");
8375 UErrorCode status
= U_ZERO_ERROR
;
8377 UnicodeString result
;
8378 FieldPosition
fpCurr(UNUM_CURRENCY_FIELD
);
8379 LocalPointer
<NumberFormat
> fmt(
8380 NumberFormat::createInstance(
8381 selectedLocale
, UNUM_CURRENCY_PLURAL
, status
));
8382 if (!assertSuccess("Format creation", status
)) {
8385 fmt
->format(posAmt
, result
, fpCurr
, status
);
8386 assertEquals("", "34.57 US dollars", result
);
8387 assertEquals("begin index", 6, fpCurr
.getBeginIndex());
8388 assertEquals("end index", 16, fpCurr
.getEndIndex());
8390 // Test field position iterator
8392 NumberFormatTest_Attributes attributes
[] = {
8393 {UNUM_INTEGER_FIELD
, 0, 2},
8394 {UNUM_DECIMAL_SEPARATOR_FIELD
, 2, 3},
8395 {UNUM_FRACTION_FIELD
, 3, 5},
8396 {UNUM_CURRENCY_FIELD
, 6, 16},
8398 UnicodeString result
;
8399 FieldPositionIterator iter
;
8400 fmt
->format(posAmt
, result
, &iter
, status
);
8401 assertEquals("", "34.57 US dollars", result
);
8402 verifyFieldPositionIterator(attributes
, iter
);
8406 fmt
->format(negAmt
, result
, fpCurr
, status
);
8407 assertEquals("", "-9,876.54 US dollars", result
);
8408 assertEquals("begin index", 10, fpCurr
.getBeginIndex());
8409 assertEquals("end index", 20, fpCurr
.getEndIndex());
8411 // Test field position iterator
8413 NumberFormatTest_Attributes attributes
[] = {
8414 {UNUM_SIGN_FIELD
, 0, 1},
8415 {UNUM_GROUPING_SEPARATOR_FIELD
, 2, 3},
8416 {UNUM_INTEGER_FIELD
, 1, 6},
8417 {UNUM_DECIMAL_SEPARATOR_FIELD
, 6, 7},
8418 {UNUM_FRACTION_FIELD
, 7, 9},
8419 {UNUM_CURRENCY_FIELD
, 10, 20},
8421 UnicodeString result
;
8422 FieldPositionIterator iter
;
8423 fmt
->format(negAmt
, result
, &iter
, status
);
8424 assertEquals("", "-9,876.54 US dollars", result
);
8425 verifyFieldPositionIterator(attributes
, iter
);
8429 void NumberFormatTest::Test10727_RoundingZero() {
8430 IcuTestErrorCode
status(*this, "Test10727_RoundingZero");
8432 dq
.setToDouble(-0.0);
8433 assertTrue("", dq
.isNegative());
8434 dq
.roundToMagnitude(0, UNUM_ROUND_HALFEVEN
, status
);
8435 assertTrue("", dq
.isNegative());
8438 void NumberFormatTest::Test11739_ParseLongCurrency() {
8439 IcuTestErrorCode
status(*this, "Test11739_ParseLongCurrency");
8440 LocalPointer
<NumberFormat
> nf(NumberFormat::createCurrencyInstance("sr_BA", status
));
8441 if (status
.errDataIfFailureAndReset()) { return; }
8442 ((DecimalFormat
*) nf
.getAlias())->applyPattern(u
"#,##0.0 ¤¤¤", status
);
8443 ParsePosition
ppos(0);
8444 LocalPointer
<CurrencyAmount
> result(nf
->parseCurrency(u
"1.500 амерички долар", ppos
));
8445 assertEquals("Should parse to 1500 USD", -1, ppos
.getErrorIndex());
8446 if (ppos
.getErrorIndex() != -1) {
8449 assertEquals("Should parse to 1500 USD", 1500LL, result
->getNumber().getInt64(status
));
8450 assertEquals("Should parse to 1500 USD", u
"USD", result
->getISOCurrency());
8453 void NumberFormatTest::Test13035_MultiCodePointPaddingInPattern() {
8454 IcuTestErrorCode
status(*this, "Test13035_MultiCodePointPaddingInPattern");
8455 DecimalFormat
df(u
"a*'நி'###0b", status
);
8456 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8457 UnicodeString result
;
8458 df
.format(12, result
.remove());
8459 // TODO(13034): Re-enable this test when support is added in ICU4C.
8460 //assertEquals("Multi-codepoint padding should not be split", u"aநிநி12b", result);
8461 df
= DecimalFormat(u
"a*\U0001F601###0b", status
);
8462 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8463 result
= df
.format(12, result
.remove());
8464 assertEquals("Single-codepoint padding should not be split", u
"a\U0001F601\U0001F60112b", result
, true);
8465 df
= DecimalFormat(u
"a*''###0b", status
);
8466 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8467 result
= df
.format(12, result
.remove());
8468 assertEquals("Quote should be escapable in padding syntax", "a''12b", result
, true);
8471 void NumberFormatTest::Test13737_ParseScientificStrict() {
8472 IcuTestErrorCode
status(*this, "Test13737_ParseScientificStrict");
8473 LocalPointer
<NumberFormat
> df(NumberFormat::createScientificInstance("en", status
), status
);
8474 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) {return;}
8475 df
->setLenient(FALSE
);
8477 expect(*df
, u
"1.2", 1.2);
8480 void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
8482 const UChar USD
[] = {0x55, 0x53, 0x44, 0x0};
8483 UErrorCode status
= U_ZERO_ERROR
;
8484 LocalPointer
<NumberFormat
> fmt(
8485 NumberFormat::createCurrencyInstance("en", status
));
8486 if (!assertSuccess("", status
)) {
8489 DecimalFormat
*dfmt
= (DecimalFormat
*) fmt
.getAlias();
8490 dfmt
->setCurrency(USD
);
8491 UnicodeString result
;
8493 // This line should be a no-op. I am setting the positive prefix
8494 // to be the same thing it was before.
8495 dfmt
->setPositivePrefix(dfmt
->getPositivePrefix(result
));
8497 UnicodeString appendTo
;
8498 assertEquals("", "$3.78", dfmt
->format(3.78, appendTo
, status
));
8499 assertSuccess("", status
);
8502 const UChar USD
[] = {0x55, 0x53, 0x44, 0x0};
8503 UErrorCode status
= U_ZERO_ERROR
;
8504 LocalPointer
<NumberFormat
> fmt(
8505 NumberFormat::createInstance("en", UNUM_CURRENCY_PLURAL
, status
));
8506 if (!assertSuccess("", status
)) {
8509 DecimalFormat
*dfmt
= (DecimalFormat
*) fmt
.getAlias();
8510 UnicodeString result
;
8511 assertEquals("", u
" (unknown currency)", dfmt
->getPositiveSuffix(result
));
8512 dfmt
->setCurrency(USD
);
8514 // getPositiveSuffix() always returns the suffix for the
8515 // "other" plural category
8516 assertEquals("", " US dollars", dfmt
->getPositiveSuffix(result
));
8517 UnicodeString appendTo
;
8518 assertEquals("", "3.78 US dollars", dfmt
->format(3.78, appendTo
, status
));
8519 assertEquals("", " US dollars", dfmt
->getPositiveSuffix(result
));
8520 dfmt
->setPositiveSuffix("booya");
8522 assertEquals("", "3.78booya", dfmt
->format(3.78, appendTo
, status
));
8523 assertEquals("", "booya", dfmt
->getPositiveSuffix(result
));
8527 void NumberFormatTest::Test11475_signRecognition() {
8528 UErrorCode status
= U_ZERO_ERROR
;
8529 DecimalFormatSymbols
sym("en", status
);
8530 UnicodeString result
;
8532 DecimalFormat
fmt("+0.00", sym
, status
);
8533 if (!assertSuccess("", status
)) {
8536 NumberFormatTest_Attributes attributes
[] = {
8537 {UNUM_SIGN_FIELD
, 0, 1},
8538 {UNUM_INTEGER_FIELD
, 1, 2},
8539 {UNUM_DECIMAL_SEPARATOR_FIELD
, 2, 3},
8540 {UNUM_FRACTION_FIELD
, 3, 5},
8542 UnicodeString result
;
8543 FieldPositionIterator iter
;
8544 fmt
.format(2.3, result
, &iter
, status
);
8545 assertEquals("", "+2.30", result
);
8546 verifyFieldPositionIterator(attributes
, iter
);
8549 DecimalFormat
fmt("++0.00+;-(#)--", sym
, status
);
8550 if (!assertSuccess("", status
)) {
8554 NumberFormatTest_Attributes attributes
[] = {
8555 {UNUM_SIGN_FIELD
, 0, 2},
8556 {UNUM_INTEGER_FIELD
, 2, 3},
8557 {UNUM_DECIMAL_SEPARATOR_FIELD
, 3, 4},
8558 {UNUM_FRACTION_FIELD
, 4, 6},
8559 {UNUM_SIGN_FIELD
, 6, 7},
8561 UnicodeString result
;
8562 FieldPositionIterator iter
;
8563 fmt
.format(2.3, result
, &iter
, status
);
8564 assertEquals("", "++2.30+", result
);
8565 verifyFieldPositionIterator(attributes
, iter
);
8568 NumberFormatTest_Attributes attributes
[] = {
8569 {UNUM_SIGN_FIELD
, 0, 1},
8570 {UNUM_INTEGER_FIELD
, 2, 3},
8571 {UNUM_DECIMAL_SEPARATOR_FIELD
, 3, 4},
8572 {UNUM_FRACTION_FIELD
, 4, 6},
8573 {UNUM_SIGN_FIELD
, 7, 9},
8575 UnicodeString result
;
8576 FieldPositionIterator iter
;
8577 fmt
.format(-2.3, result
, &iter
, status
);
8578 assertEquals("", "-(2.30)--", result
);
8579 verifyFieldPositionIterator(attributes
, iter
);
8584 void NumberFormatTest::Test11640_getAffixes() {
8585 UErrorCode status
= U_ZERO_ERROR
;
8586 DecimalFormatSymbols
symbols("en_US", status
);
8587 if (!assertSuccess("", status
)) {
8590 UnicodeString
pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
8591 pattern
= pattern
.unescape();
8592 DecimalFormat
fmt(pattern
, symbols
, status
);
8593 if (!assertSuccess("", status
)) {
8596 UnicodeString affixStr
;
8597 assertEquals("", "US dollars ", fmt
.getPositivePrefix(affixStr
));
8598 assertEquals("", " %USD", fmt
.getPositiveSuffix(affixStr
));
8599 assertEquals("", "-US dollars ", fmt
.getNegativePrefix(affixStr
));
8600 assertEquals("", " %USD", fmt
.getNegativeSuffix(affixStr
));
8603 void NumberFormatTest::Test11649_toPatternWithMultiCurrency() {
8604 UnicodeString
pattern("\\u00a4\\u00a4\\u00a4 0.00");
8605 pattern
= pattern
.unescape();
8606 UErrorCode status
= U_ZERO_ERROR
;
8607 DecimalFormat
fmt(pattern
, status
);
8608 if (!assertSuccess("", status
)) {
8611 static UChar USD
[] = {0x55, 0x53, 0x44, 0x0};
8612 fmt
.setCurrency(USD
);
8613 UnicodeString appendTo
;
8615 assertEquals("", "US dollars 12.34", fmt
.format(12.34, appendTo
));
8617 UnicodeString topattern
;
8618 fmt
.toPattern(topattern
);
8619 DecimalFormat
fmt2(topattern
, status
);
8620 if (!assertSuccess("", status
)) {
8623 fmt2
.setCurrency(USD
);
8626 assertEquals("", "US dollars 12.34", fmt2
.format(12.34, appendTo
));
8629 void NumberFormatTest::Test13327_numberingSystemBufferOverflow() {
8630 UErrorCode status
= U_ZERO_ERROR
;
8631 for (int runId
= 0; runId
< 2; runId
++) {
8632 // Construct a locale string with a very long "numbers" value.
8633 // The first time, make the value length exactly equal to ULOC_KEYWORDS_CAPACITY.
8634 // The second time, make it exceed ULOC_KEYWORDS_CAPACITY.
8635 int extraLength
= (runId
== 0) ? 0 : 5;
8637 CharString
localeId("en@numbers=", status
);
8638 for (int i
= 0; i
< ULOC_KEYWORDS_CAPACITY
+ extraLength
; i
++) {
8639 localeId
.append('x', status
);
8641 assertSuccess("Constructing locale string", status
);
8642 Locale
locale(localeId
.data());
8644 LocalPointer
<NumberingSystem
> ns(NumberingSystem::createInstance(locale
, status
));
8645 assertFalse("Should not be null", ns
.getAlias() == nullptr);
8646 assertSuccess("Should create with no error", status
);
8650 void NumberFormatTest::Test13391_chakmaParsing() {
8651 UErrorCode status
= U_ZERO_ERROR
;
8652 LocalPointer
<DecimalFormat
> df(dynamic_cast<DecimalFormat
*>(
8653 NumberFormat::createInstance(Locale("ccp"), status
)));
8654 if (df
== nullptr) {
8655 dataerrln("%s %d Chakma df is null", __FILE__
, __LINE__
);
8658 const UChar
* expected
= u
"\U00011137\U00011138,\U00011139\U0001113A\U0001113B";
8659 UnicodeString actual
;
8660 df
->format(12345, actual
, status
);
8661 assertSuccess("Should not fail when formatting in ccp", status
);
8662 assertEquals("Should produce expected output in ccp", expected
, actual
);
8665 df
->parse(expected
, result
, status
);
8666 assertSuccess("Should not fail when parsing in ccp", status
);
8667 assertEquals("Should parse to 12345 in ccp", 12345, result
);
8669 const UChar
* expectedScientific
= u
"\U00011137.\U00011139E\U00011138";
8670 UnicodeString actualScientific
;
8671 df
.adoptInstead(static_cast<DecimalFormat
*>(
8672 NumberFormat::createScientificInstance(Locale("ccp"), status
)));
8673 df
->format(130, actualScientific
, status
);
8674 assertSuccess("Should not fail when formatting scientific in ccp", status
);
8675 assertEquals("Should produce expected scientific output in ccp",
8676 expectedScientific
, actualScientific
);
8678 Formattable resultScientific
;
8679 df
->parse(expectedScientific
, resultScientific
, status
);
8680 assertSuccess("Should not fail when parsing scientific in ccp", status
);
8681 assertEquals("Should parse scientific to 130 in ccp", 130, resultScientific
);
8685 void NumberFormatTest::verifyFieldPositionIterator(
8686 NumberFormatTest_Attributes
*expected
, FieldPositionIterator
&iter
) {
8689 while (iter
.next(fp
)) {
8690 if (expected
[idx
].spos
== -1) {
8691 errln("Iterator should have ended. got %d", fp
.getField());
8694 assertEquals("id", expected
[idx
].id
, fp
.getField());
8695 assertEquals("start", expected
[idx
].spos
, fp
.getBeginIndex());
8696 assertEquals("end", expected
[idx
].epos
, fp
.getEndIndex());
8699 if (expected
[idx
].spos
!= -1) {
8700 errln("Premature end of iterator. expected %d", expected
[idx
].id
);
8704 void NumberFormatTest::Test11735_ExceptionIssue() {
8705 IcuTestErrorCode
status(*this, "Test11735_ExceptionIssue");
8706 Locale
enLocale("en");
8707 DecimalFormatSymbols
symbols(enLocale
, status
);
8708 if (status
.isSuccess()) {
8709 DecimalFormat
fmt("0", symbols
, status
);
8710 assertSuccess("Fail: Construct DecimalFormat formatter", status
, true, __FILE__
, __LINE__
);
8711 ParsePosition
ppos(0);
8712 fmt
.parseCurrency("53.45", ppos
); // NPE thrown here in ICU4J.
8713 assertEquals("Issue11735 ppos", 0, ppos
.getIndex());
8717 void NumberFormatTest::Test11035_FormatCurrencyAmount() {
8718 UErrorCode status
= U_ZERO_ERROR
;
8719 double amount
= 12345.67;
8720 const char16_t* expected
= u
"12,345$67 ";
8722 // Test two ways to set a currency via API
8724 Locale loc1
= Locale("pt_PT");
8725 LocalPointer
<NumberFormat
> fmt1(NumberFormat::createCurrencyInstance("loc1", status
),
8727 if (U_FAILURE(status
)) {
8728 dataerrln("%s %d NumberFormat instance fmt1 is null", __FILE__
, __LINE__
);
8731 fmt1
->setCurrency(u
"PTE", status
);
8732 assertSuccess("Setting currency on fmt1", status
);
8733 UnicodeString actualSetCurrency
;
8734 fmt1
->format(amount
, actualSetCurrency
);
8736 Locale loc2
= Locale("pt_PT@currency=PTE");
8737 LocalPointer
<NumberFormat
> fmt2(NumberFormat::createCurrencyInstance(loc2
, status
));
8738 assertSuccess("Creating fmt2", status
);
8739 UnicodeString actualLocaleString
;
8740 fmt2
->format(amount
, actualLocaleString
);
8742 // TODO: The following test will fail until DecimalFormat wraps NumberFormatter.
8743 if (!logKnownIssue("13574")) {
8744 assertEquals("Custom Currency Pattern, Set Currency", expected
, actualSetCurrency
);
8748 void NumberFormatTest::Test11318_DoubleConversion() {
8749 IcuTestErrorCode
status(*this, "Test11318_DoubleConversion");
8750 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance("en", status
), status
);
8751 if (U_FAILURE(status
)) {
8752 dataerrln("%s %d Error in NumberFormat instance creation", __FILE__
, __LINE__
);
8755 nf
->setMaximumFractionDigits(40);
8756 nf
->setMaximumIntegerDigits(40);
8758 // Apple addition for <rdar://problem/39240173>
8759 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
.getAlias());
8761 UErrorCode status
= U_ZERO_ERROR
;
8762 df
->setAttribute(UNUM_FORMAT_WITH_FULL_PRECISION
, TRUE
, status
);
8765 UnicodeString appendTo
;
8766 nf
->format(999999999999999.9, appendTo
);
8767 assertEquals("Should render all digits", u
"999,999,999,999,999.9", appendTo
);
8770 void NumberFormatTest::TestParsePercentRegression() {
8771 IcuTestErrorCode
status(*this, "TestParsePercentRegression");
8772 LocalPointer
<DecimalFormat
> df1((DecimalFormat
*) NumberFormat::createInstance("en", status
), status
);
8773 LocalPointer
<DecimalFormat
> df2((DecimalFormat
*) NumberFormat::createPercentInstance("en", status
), status
);
8774 if (status
.isFailure()) {return; }
8775 df1
->setLenient(TRUE
);
8776 df2
->setLenient(TRUE
);
8781 df1
->parse("50%", result
, ppos
);
8782 assertEquals("df1 should accept a number but not the percent sign", 2, ppos
.getIndex());
8783 assertEquals("df1 should return the number as 50", 50.0, result
.getDouble(status
));
8788 df2
->parse("50%", result
, ppos
);
8789 assertEquals("df2 should accept the percent sign", 3, ppos
.getIndex());
8790 assertEquals("df2 should return the number as 0.5", 0.5, result
.getDouble(status
));
8795 df2
->parse("50", result
, ppos
);
8796 assertEquals("df2 should return the number as 0.5 even though the percent sign is missing",
8798 result
.getDouble(status
));
8802 void NumberFormatTest::TestMultiplierWithScale() {
8803 IcuTestErrorCode
status(*this, "TestMultiplierWithScale");
8805 // Test magnitude combined with multiplier, as shown in API docs
8806 DecimalFormat
df("0", {"en", status
}, status
);
8807 if (status
.isSuccess()) {
8808 df
.setMultiplier(5);
8809 df
.setMultiplierScale(-1);
8810 expect2(df
, 100, u
"50"); // round-trip test
8814 void NumberFormatTest::TestFastFormatInt32() {
8815 IcuTestErrorCode
status(*this, "TestFastFormatInt32");
8817 // The two simplest formatters, old API and new API.
8818 // Old API should use the fastpath for ints.
8819 LocalizedNumberFormatter lnf
= NumberFormatter::withLocale("en");
8820 LocalPointer
<NumberFormat
> df(NumberFormat::createInstance("en", status
), status
);
8821 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) {return;}
8845 static_cast<double>(INT32_MAX
) - 1,
8846 static_cast<double>(INT32_MAX
),
8847 static_cast<double>(INT32_MAX
) + 1,
8848 static_cast<double>(INT32_MIN
) - 1,
8849 static_cast<double>(INT32_MIN
),
8850 static_cast<double>(INT32_MIN
) + 1};
8852 for (auto num
: nums
) {
8853 UnicodeString expected
= lnf
.formatDouble(num
, status
).toString(status
);
8854 UnicodeString actual
;
8855 df
->format(num
, actual
);
8856 assertEquals(UnicodeString("d = ") + num
, expected
, actual
);
8860 void NumberFormatTest::Test11646_Equality() {
8861 UErrorCode status
= U_ZERO_ERROR
;
8862 DecimalFormatSymbols
symbols(Locale::getEnglish(), status
);
8863 UnicodeString
pattern(u
"\u00a4\u00a4\u00a4 0.00 %\u00a4\u00a4");
8864 DecimalFormat
fmt(pattern
, symbols
, status
);
8865 if (!assertSuccess("", status
)) return;
8867 // Test equality with affixes. set affix methods can't capture special
8868 // characters which is why equality should fail.
8870 DecimalFormat
fmtCopy(fmt
);
8871 assertTrue("", fmt
== fmtCopy
);
8872 UnicodeString positivePrefix
;
8873 fmtCopy
.setPositivePrefix(fmtCopy
.getPositivePrefix(positivePrefix
));
8874 assertFalse("", fmt
== fmtCopy
);
8877 DecimalFormat fmtCopy
= DecimalFormat(fmt
);
8878 assertTrue("", fmt
== fmtCopy
);
8879 UnicodeString positivePrefix
;
8880 fmtCopy
.setPositiveSuffix(fmtCopy
.getPositiveSuffix(positivePrefix
));
8881 assertFalse("", fmt
== fmtCopy
);
8884 DecimalFormat
fmtCopy(fmt
);
8885 assertTrue("", fmt
== fmtCopy
);
8886 UnicodeString negativePrefix
;
8887 fmtCopy
.setNegativePrefix(fmtCopy
.getNegativePrefix(negativePrefix
));
8888 assertFalse("", fmt
== fmtCopy
);
8891 DecimalFormat
fmtCopy(fmt
);
8892 assertTrue("", fmt
== fmtCopy
);
8893 UnicodeString negativePrefix
;
8894 fmtCopy
.setNegativeSuffix(fmtCopy
.getNegativeSuffix(negativePrefix
));
8895 assertFalse("", fmt
== fmtCopy
);
8899 void NumberFormatTest::TestParseNaN() {
8900 IcuTestErrorCode
status(*this, "TestParseNaN");
8902 DecimalFormat
df("0", { "en", status
}, status
);
8903 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
8904 Formattable parseResult
;
8905 df
.parse(u
"NaN", parseResult
, status
);
8906 assertEquals("NaN should parse successfully", NAN
, parseResult
.getDouble());
8907 assertFalse("Result NaN should be positive", std::signbit(parseResult
.getDouble()));
8908 UnicodeString formatResult
;
8909 df
.format(parseResult
.getDouble(), formatResult
);
8910 assertEquals("NaN should round-trip", u
"NaN", formatResult
);
8913 void NumberFormatTest::TestFormatFailIfMoreThanMaxDigits() {
8914 IcuTestErrorCode
status(*this, "TestFormatFailIfMoreThanMaxDigits");
8916 DecimalFormat
df("0", {"en-US", status
}, status
);
8917 if (status
.errDataIfFailureAndReset()) {
8920 assertEquals("Coverage for getter 1", (UBool
) FALSE
, df
.isFormatFailIfMoreThanMaxDigits());
8921 df
.setFormatFailIfMoreThanMaxDigits(TRUE
);
8922 assertEquals("Coverage for getter 2", (UBool
) TRUE
, df
.isFormatFailIfMoreThanMaxDigits());
8923 df
.setMaximumIntegerDigits(2);
8924 UnicodeString result
;
8925 df
.format(1234, result
, status
);
8926 status
.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR
);
8929 void NumberFormatTest::TestParseCaseSensitive() {
8930 IcuTestErrorCode
status(*this, "TestParseCaseSensitive");
8932 DecimalFormat
df(u
"0", {"en-US", status
}, status
);
8933 if (status
.errDataIfFailureAndReset()) {
8936 assertEquals("Coverage for getter 1", (UBool
) FALSE
, df
.isParseCaseSensitive());
8937 df
.setParseCaseSensitive(TRUE
);
8938 assertEquals("Coverage for getter 1", (UBool
) TRUE
, df
.isParseCaseSensitive());
8941 df
.parse(u
"1e2", result
, ppos
);
8942 assertEquals("Should parse only 1 digit", 1, ppos
.getIndex());
8943 assertEquals("Result should be 1", 1.0, result
.getDouble(status
));
8946 void NumberFormatTest::TestParseNoExponent() {
8947 IcuTestErrorCode
status(*this, "TestParseNoExponent");
8949 DecimalFormat
df(u
"0", {"en-US", status
}, status
);
8950 if (status
.errDataIfFailureAndReset()) {
8953 assertEquals("Coverage for getter 1", (UBool
) FALSE
, df
.isParseNoExponent());
8954 df
.setParseNoExponent(TRUE
);
8955 assertEquals("Coverage for getter 1", (UBool
) TRUE
, df
.isParseNoExponent());
8958 df
.parse(u
"1E2", result
, ppos
);
8959 assertEquals("Should parse only 1 digit", 1, ppos
.getIndex());
8960 assertEquals("Result should be 1", 1.0, result
.getDouble(status
));
8963 void NumberFormatTest::TestSignAlwaysShown() {
8964 IcuTestErrorCode
status(*this, "TestSignAlwaysShown");
8966 DecimalFormat
df(u
"0", {"en-US", status
}, status
);
8967 if (status
.errDataIfFailureAndReset()) {
8970 assertEquals("Coverage for getter 1", (UBool
) FALSE
, df
.isSignAlwaysShown());
8971 df
.setSignAlwaysShown(TRUE
);
8972 assertEquals("Coverage for getter 1", (UBool
) TRUE
, df
.isSignAlwaysShown());
8973 UnicodeString result
;
8974 df
.format(1234, result
, status
);
8975 status
.errIfFailureAndReset();
8976 assertEquals("Should show sign on positive number", u
"+1234", result
);
8979 void NumberFormatTest::TestMinimumGroupingDigits() {
8980 IcuTestErrorCode
status(*this, "TestMinimumGroupingDigits");
8982 DecimalFormat
df(u
"#,##0", {"en-US", status
}, status
);
8983 if (status
.errDataIfFailureAndReset()) {
8986 assertEquals("Coverage for getter 1", -1, df
.getMinimumGroupingDigits());
8987 df
.setMinimumGroupingDigits(2);
8988 assertEquals("Coverage for getter 1", 2, df
.getMinimumGroupingDigits());
8989 UnicodeString result
;
8990 df
.format(1234, result
, status
);
8991 status
.errIfFailureAndReset();
8992 assertEquals("Should not have grouping", u
"1234", result
);
8993 df
.format(12345, result
.remove(), status
);
8994 status
.errIfFailureAndReset();
8995 assertEquals("Should have grouping", u
"12,345", result
);
8998 void NumberFormatTest::Test11897_LocalizedPatternSeparator() {
8999 IcuTestErrorCode
status(*this, "Test11897_LocalizedPatternSeparator");
9001 // In a locale with a different <list> symbol, like arabic,
9002 // kPatternSeparatorSymbol should still be ';'
9004 DecimalFormatSymbols
dfs("ar", status
);
9005 assertEquals("pattern separator symbol should be ;",
9007 dfs
.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
));
9010 // However, the custom symbol should be used in localized notation
9011 // when set manually via API
9013 DecimalFormatSymbols
dfs("en", status
);
9014 dfs
.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
, u
"!", FALSE
);
9015 DecimalFormat
df(u
"0", dfs
, status
);
9016 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9017 df
.applyPattern("a0;b0", status
); // should not throw
9018 UnicodeString result
;
9019 assertEquals("should apply the normal pattern",
9020 df
.getNegativePrefix(result
.remove()),
9022 df
.applyLocalizedPattern(u
"c0!d0", status
); // should not throw
9023 assertEquals("should apply the localized pattern",
9024 df
.getNegativePrefix(result
.remove()),
9029 void NumberFormatTest::Test13055_PercentageRounding() {
9030 IcuTestErrorCode
status(*this, "PercentageRounding");
9031 UnicodeString actual
;
9032 LocalPointer
<NumberFormat
>pFormat(NumberFormat::createPercentInstance("en_US", status
));
9033 if (U_FAILURE(status
)) {
9034 dataerrln("Failure creating DecimalFormat %s", u_errorName(status
));
9037 pFormat
->setMaximumFractionDigits(0);
9038 pFormat
->setRoundingMode(DecimalFormat::kRoundHalfEven
);
9039 pFormat
->format(2.155, actual
);
9040 assertEquals("Should round percent toward even number", "216%", actual
);
9043 void NumberFormatTest::Test11839() {
9044 IcuTestErrorCode
errorCode(*this, "Test11839");
9045 // Ticket #11839: DecimalFormat does not respect custom plus sign
9046 LocalPointer
<DecimalFormatSymbols
> dfs(new DecimalFormatSymbols(Locale::getEnglish(), errorCode
), errorCode
);
9047 if (!assertSuccess("", errorCode
, true, __FILE__
, __LINE__
)) { return; }
9048 dfs
->setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, u
"a∸");
9049 dfs
->setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, u
"b∔"); // ∔ U+2214 DOT PLUS
9050 DecimalFormat
df(u
"0.00+;0.00-", dfs
.orphan(), errorCode
);
9051 UnicodeString result
;
9052 df
.format(-1.234, result
, errorCode
);
9053 assertEquals("Locale-specific minus sign should be used", u
"1.23a∸", result
);
9054 df
.format(1.234, result
.remove(), errorCode
);
9055 assertEquals("Locale-specific plus sign should be used", u
"1.23b∔", result
);
9056 // Test round-trip with parse
9057 expect2(df
, -456, u
"456.00a∸");
9058 expect2(df
, 456, u
"456.00b∔");
9061 void NumberFormatTest::Test10354() {
9062 IcuTestErrorCode
errorCode(*this, "Test10354");
9063 // Ticket #10354: invalid FieldPositionIterator when formatting with empty NaN
9064 DecimalFormatSymbols
dfs(errorCode
);
9065 UnicodeString empty
;
9066 dfs
.setSymbol(DecimalFormatSymbols::kNaNSymbol
, empty
);
9067 DecimalFormat
df(errorCode
);
9068 df
.setDecimalFormatSymbols(dfs
);
9069 UnicodeString result
;
9070 FieldPositionIterator positions
;
9071 df
.format(NAN
, result
, &positions
, errorCode
);
9072 errorCode
.errIfFailureAndReset("DecimalFormat.format(NAN, FieldPositionIterator) failed");
9074 while (positions
.next(fp
)) {
9075 // Should not loop forever
9079 void NumberFormatTest::Test11645_ApplyPatternEquality() {
9080 IcuTestErrorCode
status(*this, "Test11645_ApplyPatternEquality");
9081 const char16_t* pattern
= u
"#,##0.0#";
9082 LocalPointer
<DecimalFormat
> fmt((DecimalFormat
*) NumberFormat::createInstance(status
), status
);
9083 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9084 fmt
->applyPattern(pattern
, status
);
9085 LocalPointer
<DecimalFormat
> fmtCopy
;
9087 static const int32_t newMultiplier
= 37;
9088 fmtCopy
.adoptInstead(new DecimalFormat(*fmt
));
9089 assertFalse("Value before setter", fmtCopy
->getMultiplier() == newMultiplier
);
9090 fmtCopy
->setMultiplier(newMultiplier
);
9091 assertEquals("Value after setter", fmtCopy
->getMultiplier(), newMultiplier
);
9092 fmtCopy
->applyPattern(pattern
, status
);
9093 assertEquals("Value after applyPattern", fmtCopy
->getMultiplier(), newMultiplier
);
9094 assertFalse("multiplier", *fmt
== *fmtCopy
);
9096 static const NumberFormat::ERoundingMode newRoundingMode
= NumberFormat::ERoundingMode::kRoundCeiling
;
9097 fmtCopy
.adoptInstead(new DecimalFormat(*fmt
));
9098 assertFalse("Value before setter", fmtCopy
->getRoundingMode() == newRoundingMode
);
9099 fmtCopy
->setRoundingMode(newRoundingMode
);
9100 assertEquals("Value after setter", fmtCopy
->getRoundingMode(), newRoundingMode
);
9101 fmtCopy
->applyPattern(pattern
, status
);
9102 assertEquals("Value after applyPattern", fmtCopy
->getRoundingMode(), newRoundingMode
);
9103 assertFalse("roundingMode", *fmt
== *fmtCopy
);
9105 static const char16_t *const newCurrency
= u
"EAT";
9106 fmtCopy
.adoptInstead(new DecimalFormat(*fmt
));
9107 assertFalse("Value before setter", fmtCopy
->getCurrency() == newCurrency
);
9108 fmtCopy
->setCurrency(newCurrency
);
9109 assertEquals("Value after setter", fmtCopy
->getCurrency(), newCurrency
);
9110 fmtCopy
->applyPattern(pattern
, status
);
9111 assertEquals("Value after applyPattern", fmtCopy
->getCurrency(), newCurrency
);
9112 assertFalse("currency", *fmt
== *fmtCopy
);
9114 static const UCurrencyUsage newCurrencyUsage
= UCurrencyUsage::UCURR_USAGE_CASH
;
9115 fmtCopy
.adoptInstead(new DecimalFormat(*fmt
));
9116 assertFalse("Value before setter", fmtCopy
->getCurrencyUsage() == newCurrencyUsage
);
9117 fmtCopy
->setCurrencyUsage(newCurrencyUsage
, status
);
9118 assertEquals("Value after setter", fmtCopy
->getCurrencyUsage(), newCurrencyUsage
);
9119 fmtCopy
->applyPattern(pattern
, status
);
9120 assertEquals("Value after applyPattern", fmtCopy
->getCurrencyUsage(), newCurrencyUsage
);
9121 assertFalse("currencyUsage", *fmt
== *fmtCopy
);
9124 void NumberFormatTest::Test12567() {
9125 IcuTestErrorCode
errorCode(*this, "Test12567");
9126 // Ticket #12567: DecimalFormat.equals() may not be symmetric
9127 LocalPointer
<DecimalFormat
> df1((DecimalFormat
*)
9128 NumberFormat::createInstance(Locale::getUS(), UNUM_CURRENCY
, errorCode
));
9129 LocalPointer
<DecimalFormat
> df2((DecimalFormat
*)
9130 NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL
, errorCode
));
9131 if (!assertSuccess("", errorCode
, true, __FILE__
, __LINE__
)) { return; }
9132 // NOTE: CurrencyPluralInfo equality not tested in C++ because its operator== is not defined.
9133 df1
->applyPattern(u
"0.00", errorCode
);
9134 df2
->applyPattern(u
"0.00", errorCode
);
9135 assertTrue("df1 == df2", *df1
== *df2
);
9136 assertTrue("df2 == df1", *df2
== *df1
);
9137 df2
->setPositivePrefix(u
"abc");
9138 assertTrue("df1 != df2", *df1
!= *df2
);
9139 assertTrue("df2 != df1", *df2
!= *df1
);
9142 void NumberFormatTest::Test11626_CustomizeCurrencyPluralInfo() {
9143 IcuTestErrorCode
errorCode(*this, "Test11626_CustomizeCurrencyPluralInfo");
9144 // Ticket #11626: No unit test demonstrating how to use CurrencyPluralInfo to
9145 // change formatting spelled out currencies
9146 // Use locale sr because it has interesting plural rules.
9147 Locale
locale("sr");
9148 LocalPointer
<DecimalFormatSymbols
> symbols(new DecimalFormatSymbols(locale
, errorCode
), errorCode
);
9149 CurrencyPluralInfo
info(locale
, errorCode
);
9150 if (!assertSuccess("", errorCode
, true, __FILE__
, __LINE__
)) { return; }
9151 info
.setCurrencyPluralPattern(u
"one", u
"0 qwerty", errorCode
);
9152 info
.setCurrencyPluralPattern(u
"few", u
"0 dvorak", errorCode
);
9153 DecimalFormat
df(u
"#", symbols
.orphan(), UNUM_CURRENCY_PLURAL
, errorCode
);
9154 df
.setCurrencyPluralInfo(info
);
9155 df
.setCurrency(u
"USD");
9156 df
.setMaximumFractionDigits(0);
9158 UnicodeString result
;
9159 assertEquals("Plural one", u
"1 qwerty", df
.format(1, result
, errorCode
));
9160 assertEquals("Plural few", u
"3 dvorak", df
.format(3, result
.remove(), errorCode
));
9161 assertEquals("Plural other", u
"99 америчких долара", df
.format(99, result
.remove(), errorCode
));
9163 info
.setPluralRules(u
"few: n is 1; one: n in 2..4", errorCode
);
9164 df
.setCurrencyPluralInfo(info
);
9165 assertEquals("Plural one", u
"1 dvorak", df
.format(1, result
.remove(), errorCode
));
9166 assertEquals("Plural few", u
"3 qwerty", df
.format(3, result
.remove(), errorCode
));
9167 assertEquals("Plural other", u
"99 америчких долара", df
.format(99, result
.remove(), errorCode
));
9170 void NumberFormatTest::Test20073_StrictPercentParseErrorIndex() {
9171 IcuTestErrorCode
status(*this, "Test20073_StrictPercentParseErrorIndex");
9172 ParsePosition
parsePosition(0);
9173 DecimalFormat
df(u
"0%", {"en-us", status
}, status
);
9174 if (U_FAILURE(status
)) {
9175 dataerrln("Unable to create DecimalFormat instance.");
9178 df
.setLenient(FALSE
);
9180 df
.parse(u
"%2%", result
, parsePosition
);
9181 assertEquals("", 0, parsePosition
.getIndex());
9182 assertEquals("", 0, parsePosition
.getErrorIndex());
9185 void NumberFormatTest::Test13056_GroupingSize() {
9186 UErrorCode status
= U_ZERO_ERROR
;
9187 DecimalFormat
df(u
"#,##0", status
);
9188 if (!assertSuccess("", status
)) return;
9189 assertEquals("Primary grouping should return 3", 3, df
.getGroupingSize());
9190 assertEquals("Secondary grouping should return 0", 0, df
.getSecondaryGroupingSize());
9191 df
.setSecondaryGroupingSize(3);
9192 assertEquals("Primary grouping should still return 3", 3, df
.getGroupingSize());
9193 assertEquals("Secondary grouping should round-trip", 3, df
.getSecondaryGroupingSize());
9194 df
.setGroupingSize(4);
9195 assertEquals("Primary grouping should return 4", 4, df
.getGroupingSize());
9196 assertEquals("Secondary should remember explicit setting and return 3", 3, df
.getSecondaryGroupingSize());
9200 void NumberFormatTest::Test11025_CurrencyPadding() {
9201 UErrorCode status
= U_ZERO_ERROR
;
9202 UnicodeString
pattern(u
"¤¤ **####0.00");
9203 DecimalFormatSymbols
sym(Locale::getFrance(), status
);
9204 if (!assertSuccess("", status
)) return;
9205 DecimalFormat
fmt(pattern
, sym
, status
);
9206 if (!assertSuccess("", status
)) return;
9207 UnicodeString result
;
9208 fmt
.format(433.0, result
);
9209 assertEquals("Number should be padded to 11 characters", "EUR *433,00", result
);
9212 void NumberFormatTest::Test11648_ExpDecFormatMalPattern() {
9213 UErrorCode status
= U_ZERO_ERROR
;
9215 DecimalFormat
fmt("0.00", {"en", status
}, status
);
9216 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9217 fmt
.setScientificNotation(TRUE
);
9218 UnicodeString pattern
;
9220 assertEquals("A valid scientific notation pattern should be produced",
9222 fmt
.toPattern(pattern
));
9224 DecimalFormat
fmt2(pattern
, status
);
9225 assertSuccess("", status
);
9228 void NumberFormatTest::Test11649_DecFmtCurrencies() {
9229 IcuTestErrorCode
status(*this, "Test11649_DecFmtCurrencies");
9230 UnicodeString
pattern("\\u00a4\\u00a4\\u00a4 0.00");
9231 pattern
= pattern
.unescape();
9232 DecimalFormat
fmt(pattern
, status
);
9233 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9234 static const UChar USD
[] = u
"USD";
9235 fmt
.setCurrency(USD
);
9236 UnicodeString appendTo
;
9238 assertEquals("", "US dollars 12.34", fmt
.format(12.34, appendTo
));
9239 UnicodeString topattern
;
9241 assertEquals("", pattern
, fmt
.toPattern(topattern
));
9242 DecimalFormat
fmt2(topattern
, status
);
9243 fmt2
.setCurrency(USD
);
9246 assertEquals("", "US dollars 12.34", fmt2
.format(12.34, appendTo
));
9249 void NumberFormatTest::Test13148_ParseGroupingSeparators() {
9250 IcuTestErrorCode
status(*this, "Test13148");
9251 LocalPointer
<DecimalFormat
> fmt(
9252 (DecimalFormat
*)NumberFormat::createInstance("en-ZA", status
), status
);
9253 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9255 DecimalFormatSymbols symbols
= *fmt
->getDecimalFormatSymbols();
9257 symbols
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, u
'.');
9258 symbols
.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
, u
',');
9259 fmt
->setDecimalFormatSymbols(symbols
);
9261 fmt
->parse(u
"300,000", number
, status
);
9262 assertEquals("Should parse as 300000", 300000LL, number
.getInt64(status
));
9265 void NumberFormatTest::Test12753_PatternDecimalPoint() {
9266 UErrorCode status
= U_ZERO_ERROR
;
9267 DecimalFormatSymbols
symbols(Locale::getUS(), status
);
9268 symbols
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, u
"*", false);
9269 DecimalFormat
df(u
"0.00", symbols
, status
);
9270 if (!assertSuccess("", status
)) return;
9271 df
.setDecimalPatternMatchRequired(true);
9273 df
.parse(u
"123",result
, status
);
9274 assertEquals("Parsing integer succeeded even though setDecimalPatternMatchRequired was set",
9275 U_INVALID_FORMAT_ERROR
, status
);
9278 void NumberFormatTest::Test11647_PatternCurrencySymbols() {
9279 UErrorCode status
= U_ZERO_ERROR
;
9280 DecimalFormat
df(status
);
9281 df
.applyPattern(u
"¤¤¤¤#", status
);
9282 if (!assertSuccess("", status
)) return;
9283 UnicodeString actual
;
9284 df
.format(123, actual
);
9285 assertEquals("Should replace 4 currency signs with U+FFFD", u
"\uFFFD123", actual
);
9288 void NumberFormatTest::Test11913_BigDecimal() {
9289 UErrorCode status
= U_ZERO_ERROR
;
9290 LocalPointer
<NumberFormat
> df(NumberFormat::createInstance(Locale::getEnglish(), status
), status
);
9291 if (!assertSuccess("", status
)) return;
9292 UnicodeString result
;
9293 df
->format(StringPiece("1.23456789E400"), result
, nullptr, status
);
9294 assertSuccess("", status
);
9295 assertEquals("Should format more than 309 digits", u
"12,345,678", UnicodeString(result
, 0, 10));
9296 assertEquals("Should format more than 309 digits", 534, result
.length());
9299 void NumberFormatTest::Test11020_RoundingInScientificNotation() {
9300 UErrorCode status
= U_ZERO_ERROR
;
9301 DecimalFormatSymbols
sym(Locale::getFrance(), status
);
9302 DecimalFormat
fmt(u
"0.05E0", sym
, status
);
9303 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9304 assertSuccess("", status
);
9305 UnicodeString result
;
9306 fmt
.format(12301.2, result
);
9307 assertEquals("Rounding increment should be applied after magnitude scaling", u
"1,25E4", result
);
9310 void NumberFormatTest::Test11640_TripleCurrencySymbol() {
9311 IcuTestErrorCode
status(*this, "Test11640_TripleCurrencySymbol");
9312 UnicodeString actual
;
9313 DecimalFormat
dFormat(u
"¤¤¤ 0", status
);
9314 if (U_FAILURE(status
)) {
9315 dataerrln("Failure creating DecimalFormat %s", u_errorName(status
));
9318 dFormat
.setCurrency(u
"USD");
9319 UnicodeString result
;
9320 dFormat
.getPositivePrefix(result
);
9321 assertEquals("Triple-currency should give long name on getPositivePrefix",
9322 "US dollars ", result
);
9326 void NumberFormatTest::Test13763_FieldPositionIteratorOffset() {
9327 IcuTestErrorCode
status(*this, "Test13763_FieldPositionIteratorOffset");
9328 FieldPositionIterator fpi
;
9329 UnicodeString
result(u
"foo\U0001F4FBbar"); // 8 code units
9330 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance("en", status
), status
);
9331 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9332 nf
->format(5142.3, result
, &fpi
, status
);
9334 int32_t expected
[] = {
9335 UNUM_GROUPING_SEPARATOR_FIELD
, 9, 10,
9336 UNUM_INTEGER_FIELD
, 8, 13,
9337 UNUM_DECIMAL_SEPARATOR_FIELD
, 13, 14,
9338 UNUM_FRACTION_FIELD
, 14, 15,
9340 int32_t tupleCount
= UPRV_LENGTHOF(expected
)/3;
9341 expectPositions(fpi
, expected
, tupleCount
, result
);
9344 void NumberFormatTest::Test13777_ParseLongNameNonCurrencyMode() {
9345 IcuTestErrorCode
status(*this, "Test13777_ParseLongNameNonCurrencyMode");
9347 LocalPointer
<NumberFormat
> df(
9348 NumberFormat::createInstance("en-us", UNumberFormatStyle::UNUM_CURRENCY_PLURAL
, status
), status
);
9349 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
9350 expect2(*df
, 1.5, u
"1.50 US dollars");
9353 void NumberFormatTest::Test13804_EmptyStringsWhenParsing() {
9354 IcuTestErrorCode
status(*this, "Test13804_EmptyStringsWhenParsing");
9356 DecimalFormatSymbols
dfs("en", status
);
9357 if (status
.errIfFailureAndReset()) {
9360 dfs
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, u
"", FALSE
);
9361 dfs
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, u
"", FALSE
);
9362 dfs
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, u
"", FALSE
);
9363 dfs
.setSymbol(DecimalFormatSymbols::kOneDigitSymbol
, u
"", FALSE
);
9364 dfs
.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol
, u
"", FALSE
);
9365 dfs
.setSymbol(DecimalFormatSymbols::kThreeDigitSymbol
, u
"", FALSE
);
9366 dfs
.setSymbol(DecimalFormatSymbols::kFourDigitSymbol
, u
"", FALSE
);
9367 dfs
.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol
, u
"", FALSE
);
9368 dfs
.setSymbol(DecimalFormatSymbols::kSixDigitSymbol
, u
"", FALSE
);
9369 dfs
.setSymbol(DecimalFormatSymbols::kSevenDigitSymbol
, u
"", FALSE
);
9370 dfs
.setSymbol(DecimalFormatSymbols::kEightDigitSymbol
, u
"", FALSE
);
9371 dfs
.setSymbol(DecimalFormatSymbols::kNineDigitSymbol
, u
"", FALSE
);
9372 dfs
.setSymbol(DecimalFormatSymbols::kExponentMultiplicationSymbol
, u
"", FALSE
);
9373 dfs
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, u
"", FALSE
);
9374 dfs
.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
, u
"", FALSE
);
9375 dfs
.setSymbol(DecimalFormatSymbols::kInfinitySymbol
, u
"", FALSE
);
9376 dfs
.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
, u
"", FALSE
);
9377 dfs
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, u
"", FALSE
);
9378 dfs
.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, u
"", FALSE
);
9379 dfs
.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
, u
"", FALSE
);
9380 dfs
.setSymbol(DecimalFormatSymbols::kNaNSymbol
, u
"", FALSE
);
9381 dfs
.setPatternForCurrencySpacing(UNUM_CURRENCY_INSERT
, FALSE
, u
"");
9382 dfs
.setPatternForCurrencySpacing(UNUM_CURRENCY_INSERT
, TRUE
, u
"");
9383 dfs
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, u
"", FALSE
);
9384 dfs
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, u
"", FALSE
);
9385 dfs
.setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, u
"", FALSE
);
9387 DecimalFormat
df("0", dfs
, status
);
9388 if (status
.errIfFailureAndReset()) {
9391 df
.setGroupingUsed(TRUE
);
9392 df
.setScientificNotation(TRUE
);
9393 df
.setLenient(TRUE
); // enable all matchers
9395 UnicodeString result
;
9396 df
.format(0, result
); // should not crash or hit infinite loop
9398 const char16_t* samples
[] = {
9407 for (auto& sample
: samples
) {
9408 logln(UnicodeString(u
"Attempting parse on: ") + sample
);
9409 status
.setScope(sample
);
9410 // We don't care about the results, only that we don't crash and don't loop.
9412 ParsePosition
ppos(0);
9413 df
.parse(sample
, result
, ppos
);
9414 ppos
= ParsePosition(0);
9415 LocalPointer
<CurrencyAmount
> curramt(df
.parseCurrency(sample
, ppos
));
9416 status
.errIfFailureAndReset();
9419 // Test with a nonempty exponent separator symbol to cover more code
9420 dfs
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, u
"E", FALSE
);
9421 df
.setDecimalFormatSymbols(dfs
);
9424 ParsePosition
ppos(0);
9425 df
.parse(u
"1E+2.3", result
, ppos
);
9429 void NumberFormatTest::Test20037_ScientificIntegerOverflow() {
9430 IcuTestErrorCode
status(*this, "Test20037_ScientificIntegerOverflow");
9432 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance(status
));
9433 if (U_FAILURE(status
)) {
9434 dataerrln("Unable to create NumberFormat instance.");
9439 // Test overflow of exponent
9440 nf
->parse(u
"1E-2147483648", result
, status
);
9441 StringPiece sp
= result
.getDecimalNumber(status
);
9442 assertEquals(u
"Should snap to zero",
9444 {sp
.data(), sp
.length(), US_INV
});
9446 // Test edge case overflow of exponent
9447 result
= Formattable();
9448 nf
->parse(u
"1E-2147483647E-1", result
, status
);
9449 sp
= result
.getDecimalNumber(status
);
9450 assertEquals(u
"Should not overflow and should parse only the first exponent",
9452 {sp
.data(), sp
.length(), US_INV
});
9454 // Test edge case overflow of exponent
9455 result
= Formattable();
9456 nf
->parse(u
".0003e-2147483644", result
, status
);
9457 sp
= result
.getDecimalNumber(status
);
9458 assertEquals(u
"Should not overflow",
9460 {sp
.data(), sp
.length(), US_INV
});
9462 // Test largest parseable exponent
9463 result
= Formattable();
9464 nf
->parse(u
"9876e2147483643", result
, status
);
9465 sp
= result
.getDecimalNumber(status
);
9466 assertEquals(u
"Should not overflow",
9467 u
"9.876E+2147483646",
9468 {sp
.data(), sp
.length(), US_INV
});
9470 // Test max value as well
9471 const char16_t* infinityInputs
[] = {
9479 for (const auto& input
: infinityInputs
) {
9480 result
= Formattable();
9481 nf
->parse(input
, result
, status
);
9482 sp
= result
.getDecimalNumber(status
);
9483 assertEquals(UnicodeString("Should become Infinity: ") + input
,
9485 {sp
.data(), sp
.length(), US_INV
});
9489 void NumberFormatTest::Test13840_ParseLongStringCrash() {
9490 IcuTestErrorCode
status(*this, "Test13840_ParseLongStringCrash");
9492 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance("en", status
), status
);
9493 if (status
.errIfFailureAndReset()) { return; }
9496 static const char16_t* bigString
=
9497 u
"111111111111111111111111111111111111111111111111111111111111111111111"
9498 u
"111111111111111111111111111111111111111111111111111111111111111111111"
9499 u
"111111111111111111111111111111111111111111111111111111111111111111111"
9500 u
"111111111111111111111111111111111111111111111111111111111111111111111"
9501 u
"111111111111111111111111111111111111111111111111111111111111111111111"
9502 u
"111111111111111111111111111111111111111111111111111111111111111111111";
9503 nf
->parse(bigString
, result
, status
);
9505 // Normalize the input string:
9506 CharString expectedChars
;
9507 expectedChars
.appendInvariantChars(bigString
, status
);
9508 DecimalQuantity expectedDQ
;
9509 expectedDQ
.setToDecNumber(expectedChars
.toStringPiece(), status
);
9510 UnicodeString expectedUString
= expectedDQ
.toScientificString();
9512 // Get the output string:
9513 StringPiece actualChars
= result
.getDecimalNumber(status
);
9514 UnicodeString actualUString
= UnicodeString(actualChars
.data(), actualChars
.length(), US_INV
);
9516 assertEquals("Should round-trip without crashing", expectedUString
, actualUString
);
9519 void NumberFormatTest::Test13850_EmptyStringCurrency() {
9520 IcuTestErrorCode
status(*this, "Test13840_EmptyStringCurrency");
9523 const char16_t* currencyArg
;
9524 UErrorCode expectedError
;
9526 {u
"", U_ZERO_ERROR
},
9527 {u
"U", U_ILLEGAL_ARGUMENT_ERROR
},
9528 {u
"Us", U_ILLEGAL_ARGUMENT_ERROR
},
9529 {nullptr, U_ZERO_ERROR
},
9530 {u
"U$D", U_INVARIANT_CONVERSION_ERROR
},
9531 {u
"Xxx", U_ZERO_ERROR
}
9533 for (const auto& cas
: cases
) {
9534 UnicodeString
message(u
"with currency arg: ");
9535 if (cas
.currencyArg
== nullptr) {
9536 message
+= u
"nullptr";
9538 message
+= UnicodeString(cas
.currencyArg
);
9540 status
.setScope(message
);
9541 LocalPointer
<NumberFormat
> nf(NumberFormat::createCurrencyInstance("en-US", status
), status
);
9542 if (status
.errIfFailureAndReset()) { return; }
9543 UnicodeString actual
;
9544 nf
->format(1, actual
, status
);
9545 status
.errIfFailureAndReset();
9546 assertEquals(u
"Should format with US currency " + message
, u
"$1.00", actual
);
9547 nf
->setCurrency(cas
.currencyArg
, status
);
9548 if (status
.expectErrorAndReset(cas
.expectedError
)) {
9549 // If an error occurred, do not check formatting.
9552 nf
->format(1, actual
.remove(), status
);
9553 if (cas
.currencyArg
==nullptr || cas
.currencyArg
[0]==0) {
9554 // <rdar://problem/49544607> Restore behavior in which empty/null sets locale default
9555 assertEquals(u
"Should unset the currency " + message
, u
"$1.00", actual
);
9557 assertEquals(u
"Should unset the currency " + message
, u
"\u00A41.00", actual
);
9559 status
.errIfFailureAndReset();
9563 void NumberFormatTest::Test20348_CurrencyPrefixOverride() {
9564 IcuTestErrorCode
status(*this, "Test20348_CurrencyPrefixOverride");
9565 LocalPointer
<DecimalFormat
> fmt(static_cast<DecimalFormat
*>(
9566 NumberFormat::createCurrencyInstance("en", status
)));
9567 if (status
.errIfFailureAndReset()) { return; }
9568 UnicodeString result
;
9569 assertEquals("Initial pattern",
9570 u
"¤#,##0.00", fmt
->toPattern(result
.remove()));
9571 assertEquals("Initial prefix",
9572 u
"¤", fmt
->getPositivePrefix(result
.remove()));
9573 assertEquals("Initial suffix",
9574 u
"-¤", fmt
->getNegativePrefix(result
.remove()));
9575 assertEquals("Initial format",
9576 u
"\u00A4100.00", fmt
->format(100, result
.remove(), NULL
, status
));
9578 fmt
->setPositivePrefix(u
"$");
9579 assertEquals("Set positive prefix pattern",
9580 u
"$#,##0.00;-\u00A4#,##0.00", fmt
->toPattern(result
.remove()));
9581 assertEquals("Set positive prefix prefix",
9582 u
"$", fmt
->getPositivePrefix(result
.remove()));
9583 assertEquals("Set positive prefix suffix",
9584 u
"-¤", fmt
->getNegativePrefix(result
.remove()));
9585 assertEquals("Set positive prefix format",
9586 u
"$100.00", fmt
->format(100, result
.remove(), NULL
, status
));
9588 fmt
->setNegativePrefix(u
"-$");
9589 assertEquals("Set negative prefix pattern",
9590 u
"$#,##0.00;'-'$#,##0.00", fmt
->toPattern(result
.remove()));
9591 assertEquals("Set negative prefix prefix",
9592 u
"$", fmt
->getPositivePrefix(result
.remove()));
9593 assertEquals("Set negative prefix suffix",
9594 u
"-$", fmt
->getNegativePrefix(result
.remove()));
9595 assertEquals("Set negative prefix format",
9596 u
"$100.00", fmt
->format(100, result
.remove(), NULL
, status
));
9599 void NumberFormatTest::Test20358_GroupingInPattern() {
9600 IcuTestErrorCode
status(*this, "Test20358_GroupingInPattern");
9601 LocalPointer
<DecimalFormat
> fmt(static_cast<DecimalFormat
*>(
9602 NumberFormat::createInstance("en", status
)));
9603 if (status
.errIfFailureAndReset()) { return; }
9604 UnicodeString result
;
9605 assertEquals("Initial pattern",
9606 u
"#,##0.###", fmt
->toPattern(result
.remove()));
9607 assertTrue("Initial grouping",
9608 fmt
->isGroupingUsed());
9609 assertEquals("Initial format",
9610 u
"54,321", fmt
->format(54321, result
.remove(), NULL
, status
));
9612 fmt
->setGroupingUsed(false);
9613 assertEquals("Set grouping false",
9614 u
"0.###", fmt
->toPattern(result
.remove()));
9615 assertFalse("Set grouping false grouping",
9616 fmt
->isGroupingUsed());
9617 assertEquals("Set grouping false format",
9618 u
"54321", fmt
->format(54321, result
.remove(), NULL
, status
));
9620 fmt
->setGroupingUsed(true);
9621 assertEquals("Set grouping true",
9622 u
"#,##0.###", fmt
->toPattern(result
.remove()));
9623 assertTrue("Set grouping true grouping",
9624 fmt
->isGroupingUsed());
9625 assertEquals("Set grouping true format",
9626 u
"54,321", fmt
->format(54321, result
.remove(), NULL
, status
));
9629 void NumberFormatTest::Test13731_DefaultCurrency() {
9630 IcuTestErrorCode
status(*this, "Test13731_DefaultCurrency");
9631 UnicodeString result
;
9633 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance(
9634 "en", UNumberFormatStyle::UNUM_CURRENCY
, status
), status
);
9635 if (status
.errIfFailureAndReset()) { return; }
9636 assertEquals("symbol", u
"¤1.10",
9637 nf
->format(1.1, result
.remove(), status
));
9638 assertEquals("currency", u
"", nf
->getCurrency()); // rdar://51985640
9641 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance(
9642 "en", UNumberFormatStyle::UNUM_CURRENCY_ISO
, status
), status
);
9643 if (status
.errIfFailureAndReset()) { return; }
9644 assertEquals("iso_code", u
"XXX 1.10",
9645 nf
->format(1.1, result
.remove(), status
));
9646 assertEquals("currency", u
"", nf
->getCurrency()); // rdar://51985640
9649 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance(
9650 "en", UNumberFormatStyle::UNUM_CURRENCY_PLURAL
, status
), status
);
9651 if (status
.errIfFailureAndReset()) { return; }
9652 assertEquals("plural", u
"1.10 (unknown currency)",
9653 nf
->format(1.1, result
.remove(), status
));
9654 assertEquals("currency", u
"", nf
->getCurrency()); // rdar://51985640
9658 void NumberFormatTest::Test20499_CurrencyVisibleDigitsPlural() {
9659 IcuTestErrorCode
status(*this, "Test20499_CurrencyVisibleDigitsPlural");
9660 LocalPointer
<NumberFormat
> nf(NumberFormat::createInstance(
9661 "ro-RO", UNumberFormatStyle::UNUM_CURRENCY_PLURAL
, status
), status
);
9662 const char16_t* expected
= u
"24,00 lei românești";
9663 for (int32_t i
=0; i
<5; i
++) {
9664 UnicodeString actual
;
9665 nf
->format(24, actual
, status
);
9666 assertEquals(UnicodeString(u
"iteration ") + Int64ToUnicodeString(i
),
9671 #endif /* #if !UCONFIG_NO_FORMATTING */