]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/numfmtst.cpp
ICU-64252.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / numfmtst.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
b75a7d8f 3/********************************************************************
729e4ab9 4 * COPYRIGHT:
2ca993e8 5 * Copyright (c) 1997-2016, International Business Machines Corporation and
b75a7d8f
A
6 * others. All Rights Reserved.
7 ********************************************************************/
8/* Modification History:
9* Date Name Description
10* 07/15/99 helena Ported to HPUX 10/11 CC.
11*/
12
13#include "unicode/utypes.h"
14
15#if !UCONFIG_NO_FORMATTING
16
17#include "numfmtst.h"
0f5d89e8 18#include "unicode/currpinf.h"
b75a7d8f
A
19#include "unicode/dcfmtsym.h"
20#include "unicode/decimfmt.h"
4388f060 21#include "unicode/localpointer.h"
b75a7d8f
A
22#include "unicode/ucurr.h"
23#include "unicode/ustring.h"
374ca955
A
24#include "unicode/measfmt.h"
25#include "unicode/curramt.h"
f3c0d7a5 26#include "unicode/strenum.h"
374ca955
A
27#include "textfile.h"
28#include "tokiter.h"
29#include "charstr.h"
0f5d89e8 30#include "cstr.h"
374ca955 31#include "putilimp.h"
73c04bcf 32#include "winnmtst.h"
0f5d89e8 33#include <cmath>
b75a7d8f
A
34#include <float.h>
35#include <string.h>
46f4442e 36#include <stdlib.h>
2ca993e8 37#include "cmemory.h"
46f4442e 38#include "cstring.h"
729e4ab9 39#include "unicode/numsys.h"
51004dcb 40#include "fmtableimp.h"
2ca993e8 41#include "numberformattesttuple.h"
2ca993e8 42#include "unicode/msgfmt.h"
0f5d89e8
A
43#include "number_decimalquantity.h"
44#include "unicode/numberformatter.h"
45
46#if (U_PLATFORM == U_PF_AIX) || (U_PLATFORM == U_PF_OS390)
47// These should not be macros. If they are,
48// replace them with std::isnan and std::isinf
49#if defined(isnan)
50#undef isnan
51namespace std {
52 bool isnan(double x) {
53 return _isnan(x);
54 }
2ca993e8 55}
0f5d89e8
A
56#endif
57#if defined(isinf)
58#undef isinf
59namespace std {
60 bool isinf(double x) {
61 return _isinf(x);
62 }
2ca993e8 63}
0f5d89e8
A
64#endif
65#endif
2ca993e8 66
0f5d89e8
A
67using icu::number::impl::DecimalQuantity;
68using namespace icu::number;
729e4ab9
A
69
70//#define NUMFMTST_CACHE_DEBUG 1
729e4ab9 71#include "stdio.h" /* for sprintf */
729e4ab9
A
72// #include "iostream" // for cout
73
74//#define NUMFMTST_DEBUG 1
75
b75a7d8f 76static const UChar EUR[] = {69,85,82,0}; // "EUR"
729e4ab9
A
77static const UChar ISO_CURRENCY_USD[] = {0x55, 0x53, 0x44, 0}; // "USD"
78
57a6839d 79
b75a7d8f
A
80// *****************************************************************************
81// class NumberFormatTest
82// *****************************************************************************
83
729e4ab9
A
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; }
b75a7d8f
A
86
87void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
88{
51004dcb
A
89 TESTCASE_AUTO_BEGIN;
90 TESTCASE_AUTO(TestCurrencySign);
91 TESTCASE_AUTO(TestCurrency);
92 TESTCASE_AUTO(TestParse);
93 TESTCASE_AUTO(TestRounding487);
94 TESTCASE_AUTO(TestQuotes);
95 TESTCASE_AUTO(TestExponential);
96 TESTCASE_AUTO(TestPatterns);
3d1f044b 97 TESTCASE_AUTO(Test20186_SpacesAroundSemicolon);
51004dcb
A
98
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);
107
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);
116
117 TESTCASE_AUTO(TestScientific2);
118 TESTCASE_AUTO(TestScientificGrouping);
119 TESTCASE_AUTO(TestInt64);
120
121 TESTCASE_AUTO(TestPerMill);
122 TESTCASE_AUTO(TestIllegalPatterns);
123 TESTCASE_AUTO(TestCases);
124
125 TESTCASE_AUTO(TestCurrencyNames);
3d1f044b 126 TESTCASE_AUTO(Test20484_NarrowSymbolFallback);
51004dcb
A
127 TESTCASE_AUTO(TestCurrencyAmount);
128 TESTCASE_AUTO(TestCurrencyUnit);
129 TESTCASE_AUTO(TestCoverage);
3d1f044b 130 TESTCASE_AUTO(TestLocalizedPatternSymbolCoverage);
51004dcb
A
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);
3d1f044b 141 TESTCASE_AUTO(TestMismatchedCurrencyFormatFail);
51004dcb
A
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);
0f5d89e8
A
150 TESTCASE_AUTO(TestExponentParse);
151 TESTCASE_AUTO(TestExplicitParents);
51004dcb
A
152 TESTCASE_AUTO(TestLenientParse);
153 TESTCASE_AUTO(TestAvailableNumberingSystems);
154 TESTCASE_AUTO(TestRoundingPattern);
155 TESTCASE_AUTO(Test9087);
156 TESTCASE_AUTO(TestFormatFastpaths);
157 TESTCASE_AUTO(TestFormattableSize);
57a6839d
A
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);
b331163b
A
173 TESTCASE_AUTO(TestCurrencyUsage);
174 TESTCASE_AUTO(TestDoubleLimit11439);
2ca993e8
A
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);
0f5d89e8 182 TESTCASE_AUTO(Test11739_ParseLongCurrency);
3d1f044b 183 TESTCASE_AUTO(Test13035_MultiCodePointPaddingInPattern);
0f5d89e8 184 TESTCASE_AUTO(Test13737_ParseScientificStrict);
2ca993e8
A
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);
0f5d89e8
A
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);
3d1f044b
A
200 TESTCASE_AUTO(TestFormatFailIfMoreThanMaxDigits);
201 TESTCASE_AUTO(TestParseCaseSensitive);
202 TESTCASE_AUTO(TestParseNoExponent);
203 TESTCASE_AUTO(TestSignAlwaysShown);
204 TESTCASE_AUTO(TestMinimumGroupingDigits);
0f5d89e8
A
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);
3d1f044b 212 TESTCASE_AUTO(Test20073_StrictPercentParseErrorIndex);
0f5d89e8
A
213 TESTCASE_AUTO(Test13056_GroupingSize);
214 TESTCASE_AUTO(Test11025_CurrencyPadding);
215 TESTCASE_AUTO(Test11648_ExpDecFormatMalPattern);
3d1f044b 216 TESTCASE_AUTO(Test11649_DecFmtCurrencies);
0f5d89e8
A
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);
3d1f044b
A
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);
51004dcb 233 TESTCASE_AUTO_END;
b75a7d8f 234}
729e4ab9 235
b75a7d8f
A
236// -------------------------------------
237
238// Test API (increase code coverage)
239void
240NumberFormatTest::TestAPI(void)
241{
242 logln("Test API");
243 UErrorCode status = U_ZERO_ERROR;
244 NumberFormat *test = NumberFormat::createInstance("root", status);
245 if(U_FAILURE(status)) {
729e4ab9 246 dataerrln("unable to create format object - %s", u_errorName(status));
b75a7d8f
A
247 }
248 if(test != NULL) {
249 test->setMinimumIntegerDigits(10);
0f5d89e8 250 test->setMaximumIntegerDigits(1);
b75a7d8f
A
251
252 test->setMinimumFractionDigits(10);
0f5d89e8 253 test->setMaximumFractionDigits(1);
b75a7d8f
A
254
255 UnicodeString result;
256 FieldPosition pos;
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!");
261 } else {
262 status = U_ZERO_ERROR;
263 }
264
73c04bcf
A
265 result.remove();
266 int64_t ll = 12;
267 test->format(ll, result);
0f5d89e8
A
268 assertEquals("format int64_t error", u"2.0", result);
269
270 test->setMinimumIntegerDigits(4);
271 test->setMinimumFractionDigits(4);
272
273 result.remove();
274 test->format(ll, result);
275 assertEquals("format int64_t error", u"0,012.0000", result);
73c04bcf 276
729e4ab9 277 ParsePosition ppos;
4388f060
A
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");
729e4ab9
A
282 }
283
284 delete test;
b75a7d8f 285 }
b75a7d8f
A
286}
287
57a6839d 288class StubNumberFormat :public NumberFormat{
73c04bcf 289public:
57a6839d 290 StubNumberFormat(){};
73c04bcf
A
291 virtual UnicodeString& format(double ,UnicodeString& appendTo,FieldPosition& ) const {
292 return appendTo;
293 }
294 virtual UnicodeString& format(int32_t ,UnicodeString& appendTo,FieldPosition& ) const {
295 return appendTo.append((UChar)0x0033);
296 }
297 virtual UnicodeString& format(int64_t number,UnicodeString& appendTo,FieldPosition& pos) const {
298 return NumberFormat::format(number, appendTo, pos);
299 }
300 virtual UnicodeString& format(const Formattable& , UnicodeString& appendTo, FieldPosition& , UErrorCode& ) const {
301 return appendTo;
302 }
303 virtual void parse(const UnicodeString& ,
304 Formattable& ,
305 ParsePosition& ) const {}
306 virtual void parse( const UnicodeString& ,
307 Formattable& ,
308 UErrorCode& ) const {}
309 virtual UClassID getDynamicClassID(void) const {
310 static char classID = 0;
729e4ab9 311 return (UClassID)&classID;
73c04bcf
A
312 }
313 virtual Format* clone() const {return NULL;}
314};
315
729e4ab9 316void
73c04bcf 317NumberFormatTest::TestCoverage(void){
57a6839d 318 StubNumberFormat stub;
73c04bcf
A
319 UnicodeString agent("agent");
320 FieldPosition pos;
321 int64_t num = 4;
322 if (stub.format(num, agent, pos) != UnicodeString("agent3")){
323 errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)");
324 };
325}
326
0f5d89e8
A
327void 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'⁂');
343
344 {
345 UnicodeString standardPattern(u"#,##0.05+%;#,##0.05-%");
346 UnicodeString localizedPattern(u"▰⁖▰▰໐⁘໐໕†⁜⁙▰⁖▰▰໐⁘໐໕‡⁜");
347
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);
353 UnicodeString p2;
354 assertEquals("toPattern should match on localizedPattern instance",
355 standardPattern, df2.toPattern(p2));
356 UnicodeString lp1;
357 assertEquals("toLocalizedPattern should match on standardPattern instance",
358 localizedPattern, df1.toLocalizedPattern(lp1));
359 }
360
361 {
362 UnicodeString standardPattern(u"* @@@E0‰");
363 UnicodeString localizedPattern(u"⁂ ⁕⁕⁕⁑⁑໐‱");
364
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);
370 UnicodeString p2;
371 assertEquals("toPattern should match on localizedPattern instance",
372 standardPattern, df2.toPattern(p2));
373 UnicodeString lp1;
374 assertEquals("toLocalizedPattern should match on standardPattern instance",
375 localizedPattern, df1.toLocalizedPattern(lp1));
376 }
377}
378
b75a7d8f
A
379// Test various patterns
380void
381NumberFormatTest::TestPatterns(void)
382{
383 UErrorCode status = U_ZERO_ERROR;
384 DecimalFormatSymbols sym(Locale::getUS(), status);
729e4ab9 385 if (U_FAILURE(status)) { errcheckln(status, "FAIL: Could not construct DecimalFormatSymbols - %s", u_errorName(status)); return; }
b75a7d8f
A
386
387 const char* pat[] = { "#.#", "#.", ".#", "#" };
2ca993e8 388 int32_t pat_length = UPRV_LENGTHOF(pat);
3d1f044b 389 const char* newpat[] = { "0.#", "0.", "#.0", "0" };
b75a7d8f
A
390 const char* num[] = { "0", "0.", ".0", "0" };
391 for (int32_t i=0; i<pat_length; ++i)
392 {
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");
400
401 UnicodeString s; (*(NumberFormat*)&fmt).format((int32_t)0, s);
402 if (!(s == num[i]))
403 {
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());
407 }
408 }
409}
410
3d1f044b
A
411void 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");
416
417 df = DecimalFormat(u"0.00;", {"en-us", status}, status);
418 expect2(df, 1, u"1.00");
419 expect2(df, -1, u"-1.00");
420
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
424
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 ");
428}
429
46f4442e 430/*
729e4ab9
A
431icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
432icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
433icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
46f4442e
A
434*/
435/*
729e4ab9 436void
b75a7d8f
A
437NumberFormatTest::TestDigitList(void)
438{
439 // API coverage for DigitList
b75a7d8f
A
440 DigitList list1;
441 list1.append('1');
442 list1.fDecimalAt = 1;
443 DigitList list2;
374ca955 444 list2.set((int32_t)1);
b75a7d8f
A
445 if (list1 != list2) {
446 errln("digitlist append, operator!= or set failed ");
447 }
448 if (!(list1 == list2)) {
449 errln("digitlist append, operator== or set failed ");
450 }
451}
46f4442e 452*/
b75a7d8f
A
453
454// -------------------------------------
455
456// Test exponential pattern
457void
458NumberFormatTest::TestExponential(void)
459{
460 UErrorCode status = U_ZERO_ERROR;
461 DecimalFormatSymbols sym(Locale::getUS(), status);
729e4ab9 462 if (U_FAILURE(status)) { errcheckln(status, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status)); return; }
b75a7d8f 463 const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
2ca993e8 464 int32_t pat_length = UPRV_LENGTHOF(pat);
b75a7d8f
A
465
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.
471
472// This section may be expanded as needed.
473
474#if DBL_MAX_10_EXP > 300
475 double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
2ca993e8 476 int32_t val_length = UPRV_LENGTHOF(val);
b75a7d8f
A
477 const char* valFormat[] =
478 {
479 // 0.####E0
480 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
481 // 00.000E00
482 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
483 // ##0.######E000
484 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
485 // 0.###E0;[0.###E0]
486 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
487 };
488 double valParse[] =
489 {
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,
494 };
495#elif DBL_MAX_10_EXP > 70
496 double val[] = { 0.01234, 123456789, 1.23e70, -3.141592653e-71 };
2ca993e8 497 int32_t val_length = UPRV_LENGTHOF(val);
b75a7d8f
A
498 char* valFormat[] =
499 {
500 // 0.####E0
501 "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
502 // 00.000E00
503 "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
504 // ##0.######E000
505 "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
506 // 0.###E0;[0.###E0]
507 "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
508 };
509 double valParse[] =
510 {
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,
515 };
516#else
517 // Don't test double conversion
518 double* val = 0;
519 int32_t val_length = 0;
520 char** valFormat = 0;
521 double* valParse = 0;
522 logln("Warning: Skipping double conversion tests");
523#endif
524
525 int32_t lval[] = { 0, -1, 1, 123456789 };
2ca993e8 526 int32_t lval_length = UPRV_LENGTHOF(lval);
b75a7d8f
A
527 const char* lvalFormat[] =
528 {
529 // 0.####E0
530 "0E0", "-1E0", "1E0", "1.2346E8",
531 // 00.000E00
532 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
533 // ##0.######E000
534 "0E000", "-1E000", "1E000", "123.4568E006",
535 // 0.###E0;[0.###E0]
536 "0E0", "[1E0]", "1E0", "1.235E8"
537 };
538 int32_t lvalParse[] =
539 {
540 0, -1, 1, 123460000,
541 0, -1, 1, 123460000,
542 0, -1, 1, 123456800,
543 0, -1, 1, 123500000,
544 };
545 int32_t ival = 0, ilval = 0;
546 for (int32_t p=0; p<pat_length; ++p)
547 {
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) + "\"");
553 int32_t v;
554 for (v=0; v<val_length; ++v)
555 {
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]);
560
561 ParsePosition pos(0);
562 Formattable af;
563 fmt.parse(s, af, pos);
564 double a;
565 UBool useEpsilon = FALSE;
566 if (af.getType() == Formattable::kLong)
567 a = af.getLong();
568 else if (af.getType() == Formattable::kDouble) {
569 a = af.getDouble();
4388f060 570#if U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400
b75a7d8f
A
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.
578 useEpsilon = TRUE;
579#endif
580 }
581 else {
0f5d89e8 582 errln(UnicodeString("FAIL: Non-numeric Formattable returned: ") + pattern + " " + s);
b75a7d8f
A
583 continue;
584 }
585 if (pos.getIndex() == s.length())
586 {
587 logln((UnicodeString)" -parse-> " + a);
588 // Use epsilon comparison as necessary
589 if ((useEpsilon &&
590 (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) ||
591 (!useEpsilon && a != valParse[v+ival]))
592 {
0f5d89e8
A
593 errln((UnicodeString)"FAIL: Expected " + valParse[v+ival] + " but got " + a
594 + " on input " + s);
b75a7d8f
A
595 }
596 }
597 else {
598 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
599 errln((UnicodeString)" should be (" + s.length() + " chars) -> " + valParse[v+ival]);
600 }
601 }
602 for (v=0; v<lval_length; ++v)
603 {
604 UnicodeString s;
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);
609
610 ParsePosition pos(0);
611 Formattable af;
612 fmt.parse(s, af, pos);
374ca955
A
613 if (af.getType() == Formattable::kLong ||
614 af.getType() == Formattable::kInt64) {
615 UErrorCode status = U_ZERO_ERROR;
616 int32_t a = af.getLong(status);
b75a7d8f
A
617 if (pos.getIndex() == s.length())
618 {
619 logln((UnicodeString)" -parse-> " + a);
620 if (a != lvalParse[v+ilval])
0f5d89e8 621 errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval] + " but got " + a);
b75a7d8f
A
622 }
623 else
624 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
625 }
626 else
627 errln((UnicodeString)"FAIL: Non-long Formattable returned for " + s
628 + " Double: " + af.getDouble()
629 + ", Long: " + af.getLong());
630 }
631 ival += val_length;
632 ilval += lval_length;
633 }
634}
635
374ca955
A
636void
637NumberFormatTest::TestScientific2() {
638 // jb 2552
639 UErrorCode status = U_ZERO_ERROR;
640 DecimalFormat* fmt = (DecimalFormat*)NumberFormat::createCurrencyInstance("en_US", status);
641 if (U_SUCCESS(status)) {
642 double num = 12.34;
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");
648 }
649 delete fmt;
650}
651
729e4ab9 652void
374ca955
A
653NumberFormatTest::TestScientificGrouping() {
654 // jb 2552
655 UErrorCode status = U_ZERO_ERROR;
656 DecimalFormat fmt("##0.00E0",status);
0f5d89e8 657 if (assertSuccess("", status, true, __FILE__, __LINE__)) {
374ca955
A
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");
664 }
665}
666
46f4442e 667/*static void setFromString(DigitList& dl, const char* str) {
374ca955
A
668 char c;
669 UBool decimalSet = FALSE;
670 dl.clear();
671 while ((c = *str++)) {
672 if (c == '-') {
673 dl.fIsPositive = FALSE;
674 } else if (c == '+') {
675 dl.fIsPositive = TRUE;
676 } else if (c == '.') {
677 dl.fDecimalAt = dl.fCount;
678 decimalSet = TRUE;
679 } else {
680 dl.append(c);
681 }
682 }
683 if (!decimalSet) {
684 dl.fDecimalAt = dl.fCount;
685 }
46f4442e 686}*/
374ca955
A
687
688void
689NumberFormatTest::TestInt64() {
690 UErrorCode status = U_ZERO_ERROR;
691 DecimalFormat fmt("#.#E0",status);
2ca993e8
A
692 if (U_FAILURE(status)) {
693 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
694 return;
695 }
374ca955
A
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");
705 }
706
707 // also test digitlist
46f4442e 708/* int64_t int64max = U_INT64_MAX;
374ca955
A
709 int64_t int64min = U_INT64_MIN;
710 const char* int64maxstr = "9223372036854775807";
711 const char* int64minstr = "-9223372036854775808";
712 UnicodeString fail("fail: ");
713
714 // test max int64 value
715 DigitList dl;
716 setFromString(dl, int64maxstr);
717 {
718 if (!dl.fitsIntoInt64(FALSE)) {
719 errln(fail + int64maxstr + " didn't fit");
720 }
721 int64_t int64Value = dl.getInt64();
722 if (int64Value != int64max) {
723 errln(fail + int64maxstr);
724 }
725 dl.set(int64Value);
726 int64Value = dl.getInt64();
727 if (int64Value != int64max) {
728 errln(fail + int64maxstr);
729 }
730 }
731 // test negative of max int64 value (1 shy of min int64 value)
732 dl.fIsPositive = FALSE;
733 {
734 if (!dl.fitsIntoInt64(FALSE)) {
735 errln(fail + "-" + int64maxstr + " didn't fit");
736 }
737 int64_t int64Value = dl.getInt64();
738 if (int64Value != -int64max) {
739 errln(fail + "-" + int64maxstr);
740 }
741 dl.set(int64Value);
742 int64Value = dl.getInt64();
743 if (int64Value != -int64max) {
744 errln(fail + "-" + int64maxstr);
745 }
746 }
747 // test min int64 value
748 setFromString(dl, int64minstr);
749 {
750 if (!dl.fitsIntoInt64(FALSE)) {
751 errln(fail + "-" + int64minstr + " didn't fit");
752 }
753 int64_t int64Value = dl.getInt64();
754 if (int64Value != int64min) {
755 errln(fail + int64minstr);
756 }
757 dl.set(int64Value);
758 int64Value = dl.getInt64();
759 if (int64Value != int64min) {
760 errln(fail + int64minstr);
761 }
762 }
763 // test negative of min int 64 value (1 more than max int64 value)
764 dl.fIsPositive = TRUE; // won't fit
765 {
766 if (dl.fitsIntoInt64(FALSE)) {
767 errln(fail + "-(" + int64minstr + ") didn't fit");
768 }
46f4442e 769 }*/
374ca955
A
770}
771
b75a7d8f
A
772// -------------------------------------
773
774// Test the handling of quotes
775void
776NumberFormatTest::TestQuotes(void)
777{
778 UErrorCode status = U_ZERO_ERROR;
779 UnicodeString *pat;
780 DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), status);
729e4ab9
A
781 if (U_FAILURE(status)) {
782 errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
783 delete sym;
784 return;
785 }
b75a7d8f
A
786 pat = new UnicodeString("a'fo''o'b#");
787 DecimalFormat *fmt = new DecimalFormat(*pat, *sym, status);
729e4ab9 788 UnicodeString s;
b75a7d8f
A
789 ((NumberFormat*)fmt)->format((int32_t)123, s);
790 logln((UnicodeString)"Pattern \"" + *pat + "\"");
791 logln((UnicodeString)" Format 123 -> " + escape(s));
729e4ab9 792 if (!(s=="afo'ob123"))
b75a7d8f 793 errln((UnicodeString)"FAIL: Expected afo'ob123");
729e4ab9 794
b75a7d8f
A
795 s.truncate(0);
796 delete fmt;
797 delete pat;
798
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));
729e4ab9 804 if (!(s=="a'b123"))
b75a7d8f
A
805 errln((UnicodeString)"FAIL: Expected a'b123");
806 delete fmt;
807 delete pat;
808 delete sym;
809}
810
811/**
812 * Test the handling of the currency symbol in patterns.
813 */
814void
815NumberFormatTest::TestCurrencySign(void)
816{
817 UErrorCode status = U_ZERO_ERROR;
818 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale::getUS(), status);
819 UnicodeString pat;
820 UChar currency = 0x00A4;
729e4ab9
A
821 if (U_FAILURE(status)) {
822 errcheckln(status, "Fail to create DecimalFormatSymbols - %s", u_errorName(status));
823 delete sym;
824 return;
825 }
b75a7d8f
A
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);
831 pat.truncate(0);
832 logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
833 logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
729e4ab9 834 if (s != "$1,234.56") dataerrln((UnicodeString)"FAIL: Expected $1,234.56");
b75a7d8f
A
835 s.truncate(0);
836 ((NumberFormat*)fmt)->format(- 1234.56, s);
837 logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
729e4ab9 838 if (s != "-$1,234.56") dataerrln((UnicodeString)"FAIL: Expected -$1,234.56");
b75a7d8f
A
839 delete fmt;
840 pat.truncate(0);
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);
847 s.truncate(0);
848 ((NumberFormat*)fmt)->format(1234.56, s);
849 logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
850 logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
729e4ab9 851 if (s != "USD 1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD 1,234.56");
b75a7d8f
A
852 s.truncate(0);
853 ((NumberFormat*)fmt)->format(-1234.56, s);
854 logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
729e4ab9 855 if (s != "USD -1,234.56") dataerrln((UnicodeString)"FAIL: Expected USD -1,234.56");
b75a7d8f
A
856 delete fmt;
857 delete sym;
729e4ab9 858 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + u_errorName(status));
b75a7d8f 859}
729e4ab9 860
b75a7d8f
A
861// -------------------------------------
862
863static UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
864
865UnicodeString&
866NumberFormatTest::escape(UnicodeString& s)
867{
868 UnicodeString buf;
869 for (int32_t i=0; i<s.length(); ++i)
870 {
871 UChar c = s[(int32_t)i];
872 if (c <= (UChar)0x7F) buf += c;
873 else {
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);
879 }
880 }
881 return (s = buf);
882}
883
729e4ab9 884
b75a7d8f 885// -------------------------------------
374ca955
A
886static const char* testCases[][2]= {
887 /* locale ID */ /* expected */
3d1f044b
A
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
729e4ab9
A
897 {"en_US@currency=JPY", "\\u00A51,150"},
898 {"en_US@currency=jpy", "\\u00A51,150"},
899 {"en-US-u-cu-jpy", "\\u00A51,150"}
374ca955 900};
b75a7d8f
A
901/**
902 * Test localized currency patterns.
903 */
904void
905NumberFormatTest::TestCurrency(void)
906{
907 UErrorCode status = U_ZERO_ERROR;
908 NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
73c04bcf
A
909 if (U_FAILURE(status)) {
910 dataerrln("Error calling NumberFormat::createCurrencyInstance()");
911 return;
912 }
913
b75a7d8f
A
914 UnicodeString s; currencyFmt->format(1.50, s);
915 logln((UnicodeString)"Un pauvre ici a..........." + s);
46f4442e 916 if (!(s==CharsToUnicodeString("1,50\\u00A0$")))
0f5d89e8 917 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>$ but got " + s);
b75a7d8f
A
918 delete currencyFmt;
919 s.truncate(0);
374ca955 920 char loc[256]={0};
3d1f044b 921 int len = uloc_canonicalize("de_DE@currency=DEM", loc, 256, &status);
57a6839d 922 (void)len; // Suppress unused variable warning.
374ca955 923 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc),status);
b75a7d8f
A
924 currencyFmt->format(1.50, s);
925 logln((UnicodeString)"Un pauvre en Allemagne a.." + s);
b331163b 926 if (!(s==CharsToUnicodeString("1,50\\u00A0DM")))
0f5d89e8 927 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>DM but got " + s);
b75a7d8f
A
928 delete currencyFmt;
929 s.truncate(0);
3d1f044b 930 len = uloc_canonicalize("fr_FR@currency=FRF", loc, 256, &status);
374ca955 931 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
b75a7d8f
A
932 currencyFmt->format(1.50, s);
933 logln((UnicodeString)"Un pauvre en France a....." + s);
46f4442e
A
934 if (!(s==CharsToUnicodeString("1,50\\u00A0F")))
935 errln((UnicodeString)"FAIL: Expected 1,50<nbsp>F");
b75a7d8f
A
936 delete currencyFmt;
937 if (U_FAILURE(status))
938 errln((UnicodeString)"FAIL: Status " + (int32_t)status);
729e4ab9 939
2ca993e8 940 for(int i=0; i < UPRV_LENGTHOF(testCases); i++){
374ca955
A
941 status = U_ZERO_ERROR;
942 const char *localeID = testCases[i][0];
46f4442e 943 UnicodeString expected(testCases[i][1], -1, US_INV);
374ca955
A
944 expected = expected.unescape();
945 s.truncate(0);
946 char loc[256]={0};
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);
951 continue;
952 }
953 currencyFmt->format(1150.50, s);
954 if(s!=expected){
729e4ab9
A
955 errln(UnicodeString("FAIL: Expected: ")+expected
956 + UnicodeString(" Got: ") + s
374ca955
A
957 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
958 }
959 if (U_FAILURE(status)){
960 errln((UnicodeString)"FAIL: Status " + (int32_t)status);
961 }
962 delete currencyFmt;
963 }
b75a7d8f 964}
729e4ab9 965
b75a7d8f
A
966// -------------------------------------
967
968/**
969 * Test the Currency object handling, new as of ICU 2.2.
970 */
971void NumberFormatTest::TestCurrencyObject() {
972 UErrorCode ec = U_ZERO_ERROR;
729e4ab9 973 NumberFormat* fmt =
b75a7d8f
A
974 NumberFormat::createCurrencyInstance(Locale::getUS(), ec);
975
976 if (U_FAILURE(ec)) {
729e4ab9 977 dataerrln("FAIL: getCurrencyInstance(US) - %s", u_errorName(ec));
b75a7d8f
A
978 delete fmt;
979 return;
980 }
981
982 Locale null("", "", "");
729e4ab9 983
b75a7d8f
A
984 expectCurrency(*fmt, null, 1234.56, "$1,234.56");
985
986 expectCurrency(*fmt, Locale::getFrance(),
987 1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
988
989 expectCurrency(*fmt, Locale::getJapan(),
990 1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
991
992 expectCurrency(*fmt, Locale("fr", "CH", ""),
3d1f044b 993 1234.56, "CHF 1,234.56"); // no more 0.05 rounding here, see cldrbug 5548
b75a7d8f
A
994
995 expectCurrency(*fmt, Locale::getUS(),
996 1234.56, "$1,234.56");
997
998 delete fmt;
999 fmt = NumberFormat::createCurrencyInstance(Locale::getFrance(), ec);
1000
1001 if (U_FAILURE(ec)) {
1002 errln("FAIL: getCurrencyInstance(FRANCE)");
1003 delete fmt;
1004 return;
1005 }
729e4ab9 1006
3d1f044b 1007 expectCurrency(*fmt, null, 1234.56, CharsToUnicodeString("1\\u202F234,56 \\u20AC"));
b75a7d8f
A
1008
1009 expectCurrency(*fmt, Locale::getJapan(),
3d1f044b 1010 1234.56, CharsToUnicodeString("1\\u202F235 JPY")); // Yen
b75a7d8f
A
1011
1012 expectCurrency(*fmt, Locale("fr", "CH", ""),
3d1f044b 1013 1234.56, CharsToUnicodeString("1\\u202F234,56 CHF")); // no more 0.05 rounding here, see cldrbug 5548
b75a7d8f
A
1014
1015 expectCurrency(*fmt, Locale::getUS(),
3d1f044b 1016 1234.56, CharsToUnicodeString("1\\u202F234,56 $US"));
b75a7d8f
A
1017
1018 expectCurrency(*fmt, Locale::getFrance(),
3d1f044b 1019 1234.56, CharsToUnicodeString("1\\u202F234,56 \\u20AC")); // Euro
b75a7d8f
A
1020
1021 delete fmt;
1022}
729e4ab9 1023
b75a7d8f
A
1024// -------------------------------------
1025
1026/**
1027 * Do rudimentary testing of parsing.
1028 */
1029void
1030NumberFormatTest::TestParse(void)
1031{
1032 UErrorCode status = U_ZERO_ERROR;
1033 UnicodeString arg("0");
1034 DecimalFormat* format = new DecimalFormat("00", status);
1035 //try {
4388f060 1036 Formattable n; format->parse(arg, n, status);
b75a7d8f
A
1037 logln((UnicodeString)"parse(" + arg + ") = " + n.getLong());
1038 if (n.getType() != Formattable::kLong ||
1039 n.getLong() != 0) errln((UnicodeString)"FAIL: Expected 0");
1040 delete format;
729e4ab9 1041 if (U_FAILURE(status)) errcheckln(status, (UnicodeString)"FAIL: Status " + u_errorName(status));
b75a7d8f
A
1042 //}
1043 //catch(Exception e) {
1044 // errln((UnicodeString)"Exception caught: " + e);
1045 //}
1046}
729e4ab9 1047
b75a7d8f
A
1048// -------------------------------------
1049
46f4442e 1050static const char *lenientAffixTestCases[] = {
4388f060
A
1051 "(1)",
1052 "( 1)",
1053 "(1 )",
1054 "( 1 )"
46f4442e
A
1055};
1056
7393aa2f
A
1057static const char *lenientMinusTestCases[] = {
1058 "-5",
1059 "\\u22125",
0f5d89e8 1060 "\\u27965"
7393aa2f
A
1061};
1062
46f4442e 1063static const char *lenientCurrencyTestCases[] = {
4388f060
A
1064 "$1,000",
1065 "$ 1,000",
1066 "$1000",
1067 "$ 1000",
1068 "$1 000.00",
1069 "$ 1 000.00",
1070 "$ 1\\u00A0000.00",
1071 "1000.00"
46f4442e
A
1072};
1073
57a6839d 1074// changed from () to - per cldrbug 5674
46f4442e 1075static const char *lenientNegativeCurrencyTestCases[] = {
57a6839d
A
1076 "-$1,000",
1077 "-$ 1,000",
1078 "-$1000",
1079 "-$ 1000",
1080 "-$1 000.00",
1081 "-$ 1 000.00",
1082 "- $ 1,000.00 ",
1083 "-$ 1\\u00A0000.00",
1084 "-1000.00"
46f4442e
A
1085};
1086
1087static const char *lenientPercentTestCases[] = {
4388f060
A
1088 "25%",
1089 " 25%",
1090 " 25 %",
1091 "25 %",
729e4ab9
A
1092 "25\\u00A0%",
1093 "25"
46f4442e
A
1094};
1095
1096static const char *lenientNegativePercentTestCases[] = {
729e4ab9
A
1097 "-25%",
1098 " -25%",
1099 " - 25%",
1100 "- 25 %",
1101 " - 25 %",
1102 "-25 %",
1103 "-25\\u00A0%",
1104 "-25",
1105 "- 25"
46f4442e
A
1106};
1107
1108static const char *strictFailureTestCases[] = {
729e4ab9
A
1109 " 1000",
1110 "10,00",
1111 "1,000,.0"
46f4442e
A
1112};
1113
46f4442e
A
1114/**
1115 * Test lenient parsing.
1116 */
1117void
1118NumberFormatTest::TestLenientParse(void)
1119{
1120 UErrorCode status = U_ZERO_ERROR;
1121 DecimalFormat *format = new DecimalFormat("(#,##0)", status);
1122 Formattable n;
729e4ab9 1123
4388f060
A
1124 if (format == NULL || U_FAILURE(status)) {
1125 dataerrln("Unable to create DecimalFormat (#,##0) - %s", u_errorName(status));
1126 } else {
1127 format->setLenient(TRUE);
2ca993e8 1128 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientAffixTestCases); t += 1) {
4388f060 1129 UnicodeString testCase = ctou(lenientAffixTestCases[t]);
729e4ab9 1130
4388f060
A
1131 format->parse(testCase, n, status);
1132 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
729e4ab9 1133
4388f060
A
1134 if (U_FAILURE(status) || n.getType() != Formattable::kLong ||
1135 n.getLong() != 1) {
0f5d89e8
A
1136 dataerrln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientAffixTestCases[t]
1137 + (UnicodeString) "\"; error code = " + u_errorName(status));
4388f060
A
1138 status = U_ZERO_ERROR;
1139 }
1140 }
1141 delete format;
1142 }
729e4ab9 1143
7393aa2f
A
1144 Locale en_US("en_US");
1145 Locale sv_SE("sv_SE");
0f5d89e8 1146
4388f060 1147 NumberFormat *mFormat = NumberFormat::createInstance(sv_SE, UNUM_DECIMAL, status);
0f5d89e8 1148
4388f060
A
1149 if (mFormat == NULL || U_FAILURE(status)) {
1150 dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status));
1151 } else {
1152 mFormat->setLenient(TRUE);
2ca993e8 1153 for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) {
4388f060 1154 UnicodeString testCase = ctou(lenientMinusTestCases[t]);
0f5d89e8 1155
4388f060
A
1156 mFormat->parse(testCase, n, status);
1157 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
0f5d89e8 1158
4388f060 1159 if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
0f5d89e8
A
1160 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t]
1161 + (UnicodeString) "\"; error code = " + u_errorName(status));
4388f060
A
1162 status = U_ZERO_ERROR;
1163 }
7393aa2f 1164 }
4388f060 1165 delete mFormat;
7393aa2f 1166 }
0f5d89e8 1167
4388f060 1168 mFormat = NumberFormat::createInstance(en_US, UNUM_DECIMAL, status);
0f5d89e8 1169
4388f060
A
1170 if (mFormat == NULL || U_FAILURE(status)) {
1171 dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status));
1172 } else {
1173 mFormat->setLenient(TRUE);
2ca993e8 1174 for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) {
4388f060 1175 UnicodeString testCase = ctou(lenientMinusTestCases[t]);
0f5d89e8 1176
4388f060
A
1177 mFormat->parse(testCase, n, status);
1178 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
0f5d89e8 1179
4388f060 1180 if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
0f5d89e8
A
1181 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t]
1182 + (UnicodeString) "\"; error code = " + u_errorName(status));
4388f060
A
1183 status = U_ZERO_ERROR;
1184 }
7393aa2f 1185 }
4388f060 1186 delete mFormat;
7393aa2f 1187 }
0f5d89e8 1188
4388f060 1189 NumberFormat *cFormat = NumberFormat::createInstance(en_US, UNUM_CURRENCY, status);
729e4ab9 1190
4388f060
A
1191 if (cFormat == NULL || U_FAILURE(status)) {
1192 dataerrln("Unable to create NumberFormat (en_US, UNUM_CURRENCY) - %s", u_errorName(status));
1193 } else {
1194 cFormat->setLenient(TRUE);
2ca993e8 1195 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientCurrencyTestCases); t += 1) {
4388f060 1196 UnicodeString testCase = ctou(lenientCurrencyTestCases[t]);
729e4ab9 1197
4388f060
A
1198 cFormat->parse(testCase, n, status);
1199 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
729e4ab9 1200
4388f060
A
1201 if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1202 n.getLong() != 1000) {
0f5d89e8
A
1203 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientCurrencyTestCases[t]
1204 + (UnicodeString) "\"; error code = " + u_errorName(status));
4388f060
A
1205 status = U_ZERO_ERROR;
1206 }
46f4442e 1207 }
729e4ab9 1208
2ca993e8 1209 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientNegativeCurrencyTestCases); t += 1) {
4388f060 1210 UnicodeString testCase = ctou(lenientNegativeCurrencyTestCases[t]);
729e4ab9 1211
4388f060
A
1212 cFormat->parse(testCase, n, status);
1213 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
729e4ab9 1214
4388f060
A
1215 if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1216 n.getLong() != -1000) {
0f5d89e8
A
1217 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativeCurrencyTestCases[t]
1218 + (UnicodeString) "\"; error code = " + u_errorName(status));
4388f060
A
1219 status = U_ZERO_ERROR;
1220 }
46f4442e 1221 }
729e4ab9 1222
4388f060
A
1223 delete cFormat;
1224 }
729e4ab9 1225
7393aa2f 1226 NumberFormat *pFormat = NumberFormat::createPercentInstance(en_US, status);
729e4ab9 1227
4388f060
A
1228 if (pFormat == NULL || U_FAILURE(status)) {
1229 dataerrln("Unable to create NumberFormat::createPercentInstance (en_US) - %s", u_errorName(status));
1230 } else {
1231 pFormat->setLenient(TRUE);
2ca993e8 1232 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientPercentTestCases); t += 1) {
4388f060 1233 UnicodeString testCase = ctou(lenientPercentTestCases[t]);
729e4ab9 1234
4388f060
A
1235 pFormat->parse(testCase, n, status);
1236 logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
729e4ab9 1237
4388f060
A
1238 if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
1239 n.getDouble() != 0.25) {
0f5d89e8
A
1240 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientPercentTestCases[t]
1241 + (UnicodeString) "\"; error code = " + u_errorName(status)
1242 + "; got: " + n.getDouble(status));
4388f060
A
1243 status = U_ZERO_ERROR;
1244 }
46f4442e 1245 }
729e4ab9 1246
2ca993e8 1247 for (int32_t t = 0; t < UPRV_LENGTHOF (lenientNegativePercentTestCases); t += 1) {
4388f060 1248 UnicodeString testCase = ctou(lenientNegativePercentTestCases[t]);
729e4ab9 1249
4388f060
A
1250 pFormat->parse(testCase, n, status);
1251 logln((UnicodeString)"parse(" + testCase + ") = " + n.getDouble());
729e4ab9 1252
4388f060
A
1253 if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
1254 n.getDouble() != -0.25) {
0f5d89e8
A
1255 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativePercentTestCases[t]
1256 + (UnicodeString) "\"; error code = " + u_errorName(status)
1257 + "; got: " + n.getDouble(status));
4388f060
A
1258 status = U_ZERO_ERROR;
1259 }
46f4442e 1260 }
729e4ab9 1261
4388f060
A
1262 delete pFormat;
1263 }
729e4ab9
A
1264
1265 // Test cases that should fail with a strict parse and pass with a
1266 // lenient parse.
1267 NumberFormat *nFormat = NumberFormat::createInstance(en_US, status);
0f5d89e8 1268
4388f060
A
1269 if (nFormat == NULL || U_FAILURE(status)) {
1270 dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status));
0f5d89e8 1271 } else {
4388f060 1272 // first, make sure that they fail with a strict parse
2ca993e8 1273 for (int32_t t = 0; t < UPRV_LENGTHOF(strictFailureTestCases); t += 1) {
4388f060
A
1274 UnicodeString testCase = ctou(strictFailureTestCases[t]);
1275
1276 nFormat->parse(testCase, n, status);
1277 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1278
1279 if (! U_FAILURE(status)) {
0f5d89e8
A
1280 errln((UnicodeString)"Strict Parse succeeded for \"" + (UnicodeString) strictFailureTestCases[t]
1281 + (UnicodeString) "\"; error code = " + u_errorName(status));
4388f060
A
1282 }
1283
1284 status = U_ZERO_ERROR;
1285 }
1286
1287 // then, make sure that they pass with a lenient parse
1288 nFormat->setLenient(TRUE);
2ca993e8 1289 for (int32_t t = 0; t < UPRV_LENGTHOF(strictFailureTestCases); t += 1) {
4388f060
A
1290 UnicodeString testCase = ctou(strictFailureTestCases[t]);
1291
1292 nFormat->parse(testCase, n, status);
1293 logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
1294
1295 if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
1296 n.getLong() != 1000) {
0f5d89e8
A
1297 errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) strictFailureTestCases[t]
1298 + (UnicodeString) "\"; error code = " + u_errorName(status));
4388f060
A
1299 status = U_ZERO_ERROR;
1300 }
1301 }
1302
1303 delete nFormat;
729e4ab9 1304 }
46f4442e
A
1305}
1306
1307// -------------------------------------
1308
b75a7d8f
A
1309/**
1310 * Test proper rounding by the format method.
1311 */
1312void
1313NumberFormatTest::TestRounding487(void)
1314{
1315 UErrorCode status = U_ZERO_ERROR;
1316 NumberFormat *nf = NumberFormat::createInstance(status);
73c04bcf
A
1317 if (U_FAILURE(status)) {
1318 dataerrln("Error calling NumberFormat::createInstance()");
1319 return;
1320 }
1321
b75a7d8f
A
1322 roundingTest(*nf, 0.00159999, 4, "0.0016");
1323 roundingTest(*nf, 0.00995, 4, "0.01");
1324
1325 roundingTest(*nf, 12.3995, 3, "12.4");
1326
1327 roundingTest(*nf, 12.4999, 0, "12");
1328 roundingTest(*nf, - 19.5, 0, "-20");
1329 delete nf;
1330 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status);
1331}
1332
1333/**
1334 * Test the functioning of the secondary grouping value.
1335 */
1336void NumberFormatTest::TestSecondaryGrouping(void) {
1337 UErrorCode status = U_ZERO_ERROR;
1338 DecimalFormatSymbols US(Locale::getUS(), status);
1339 CHECK(status, "DecimalFormatSymbols ct");
1340
1341 DecimalFormat f("#,##,###", US, status);
1342 CHECK(status, "DecimalFormat ct");
1343
1344 expect2(f, (int32_t)123456789L, "12,34,56,789");
3d1f044b 1345 expectPat(f, "#,##,##0");
b75a7d8f
A
1346 f.applyPattern("#,###", status);
1347 CHECK(status, "applyPattern");
1348
1349 f.setSecondaryGroupingSize(4);
1350 expect2(f, (int32_t)123456789L, "12,3456,789");
3d1f044b 1351 expectPat(f, "#,####,##0");
b75a7d8f 1352 NumberFormat *g = NumberFormat::createInstance(Locale("hi", "IN"), status);
729e4ab9 1353 CHECK_DATA(status, "createInstance(hi_IN)");
b75a7d8f
A
1354
1355 UnicodeString out;
1356 int32_t l = (int32_t)1876543210L;
1357 g->format(l, out);
1358 delete g;
1359 // expect "1,87,65,43,210", but with Hindi digits
1360 // 01234567890123
1361 UBool ok = TRUE;
1362 if (out.length() != 14) {
1363 ok = FALSE;
1364 } else {
1365 for (int32_t i=0; i<out.length(); ++i) {
1366 UBool expectGroup = FALSE;
1367 switch (i) {
1368 case 1:
1369 case 4:
1370 case 7:
1371 case 10:
1372 expectGroup = TRUE;
1373 break;
1374 }
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) {
1379 ok = FALSE;
1380 break;
1381 }
1382 }
1383 }
1384 if (!ok) {
1385 errln((UnicodeString)"FAIL Expected " + l +
1386 " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
1387 escape(out) + "\"");
1388 } else {
1389 logln((UnicodeString)"Ok " + l +
1390 " x hi_IN -> \"" +
1391 escape(out) + "\"");
1392 }
1393}
1394
1395void 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)) {
729e4ab9 1400 errcheckln(ec, "FAIL: Constructor - %s", u_errorName(ec));
b75a7d8f
A
1401 return;
1402 }
0f5d89e8
A
1403 // From ICU 62, flexible whitespace needs lenient mode
1404 fmt.setLenient(TRUE);
b75a7d8f
A
1405 int32_t n = 1234;
1406 expect(fmt, "a b1234c ", n);
1407 expect(fmt, "a b1234c ", n);
1408}
1409
1410/**
1411 * Test currencies whose display name is a ChoiceFormat.
1412 */
1413void NumberFormatTest::TestComplexCurrency() {
729e4ab9
A
1414
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"));
1426// } else {
1427// errln("FAIL: getCurrencyInstance(kn_IN)");
1428// }
1429// delete fmt;
1430
b75a7d8f 1431}
729e4ab9 1432
b75a7d8f 1433// -------------------------------------
729e4ab9 1434
b75a7d8f
A
1435void
1436NumberFormatTest::roundingTest(NumberFormat& nf, double x, int32_t maxFractionDigits, const char* expected)
1437{
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);
1442}
1443
1444/**
1445 * Upgrade to alphaWorks
1446 */
1447void 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)");
1455 int32_t n = 1234;
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"
1459}
1460
1461/**
1462 * Upgrade to alphaWorks
1463 */
1464void NumberFormatTest::TestScientific(void) {
1465 UErrorCode status = U_ZERO_ERROR;
1466 DecimalFormatSymbols US(Locale::getUS(), status);
1467 CHECK(status, "DecimalFormatSymbols constructor");
1468
1469 // Test pattern round-trip
1470 const char* PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
1471 "0.###E0;[0.###E0]" };
2ca993e8 1472 int32_t PAT_length = UPRV_LENGTHOF(PAT);
b75a7d8f
A
1473 int32_t DIGITS[] = {
1474 // min int, max int, min frac, max frac
3d1f044b 1475 1, 1, 0, 0, // "#E0"
b75a7d8f
A
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]"
1480 };
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");
1485 UnicodeString pat2;
1486 df.toPattern(pat2);
1487 if (pat == pat2) {
1488 logln(UnicodeString("Ok Pattern rt \"") +
1489 pat + "\" -> \"" +
1490 pat2 + "\"");
1491 } else {
1492 errln(UnicodeString("FAIL Pattern rt \"") +
1493 pat + "\" -> \"" +
1494 pat2 + "\"");
1495 }
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 " +
1507 DIGITS[4*i] + "/" +
1508 DIGITS[4*i+1] + ";" +
1509 DIGITS[4*i+2] + "/" +
1510 DIGITS[4*i+3]);
1511 }
1512 }
1513
1514
1515 // Test the constructor for default locale. We have to
729e4ab9
A
1516 // manually set the default locale, as there is no
1517 // guarantee that the default locale has the same
b75a7d8f
A
1518 // scientific format.
1519 Locale def = Locale::getDefault();
1520 Locale::setDefault(Locale::getUS(), status);
1521 expect2(NumberFormat::createScientificInstance(status),
1522 12345.678901,
1523 "1.2345678901E4", status);
1524 Locale::setDefault(def, status);
1525
1526 expect2(new DecimalFormat("#E0", US, status),
1527 12345.0,
1528 "1.2345E4", status);
1529 expect(new DecimalFormat("0E0", US, status),
1530 12345.0,
1531 "1E4", status);
1532 expect2(NumberFormat::createScientificInstance(Locale::getUS(), status),
1533 12345.678901,
1534 "1.2345678901E4", status);
1535 expect(new DecimalFormat("##0.###E0", US, status),
1536 12345.0,
1537 "12.34E3", status);
1538 expect(new DecimalFormat("##0.###E0", US, status),
1539 12345.00001,
1540 "12.35E3", status);
1541 expect2(new DecimalFormat("##0.####E0", US, status),
1542 (int32_t) 12345,
1543 "12.345E3", status);
1544 expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status),
1545 12345.678901,
1546 "1,2345678901E4", status);
1547 expect(new DecimalFormat("##0.####E0", US, status),
1548 789.12345e-9,
1549 "789.12E-9", status);
1550 expect2(new DecimalFormat("##0.####E0", US, status),
1551 780.e-9,
1552 "780E-9", status);
1553 expect(new DecimalFormat(".###E0", US, status),
1554 45678.0,
1555 ".457E5", status);
1556 expect2(new DecimalFormat(".###E0", US, status),
1557 (int32_t) 0,
1558 ".0E0", status);
1559 /*
1560 expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
1561 new DecimalFormat("##E0", US),
1562 new DecimalFormat("####E0", US),
729e4ab9
A
1563 new DecimalFormat("0E0", US),
1564 new DecimalFormat("00E0", US),
1565 new DecimalFormat("000E0", US),
b75a7d8f
A
1566 },
1567 new Long(45678000),
1568 new String[] { "4.5678E7",
1569 "45.678E6",
1570 "4567.8E4",
1571 "5E7",
729e4ab9 1572 "46E6",
b75a7d8f
A
1573 "457E5",
1574 }
1575 );
1576 !
1577 ! Unroll this test into individual tests below...
1578 !
1579 */
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);
1592 /*
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",
1603 });
1604 !
1605 ! Unroll this test into individual tests below...
1606 !
1607 */
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);
1626 /*
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",
1630 });
1631 !
1632 ! Unroll this test into individual tests below...
1633 !
1634 */
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);
1639}
1640
1641/**
1642 * Upgrade to alphaWorks
1643 */
1644void NumberFormatTest::TestPad(void) {
1645 UErrorCode status = U_ZERO_ERROR;
1646 DecimalFormatSymbols US(Locale::getUS(), status);
1647 CHECK(status, "DecimalFormatSymbols constructor");
1648
1649 expect2(new DecimalFormat("*^##.##", US, status),
1650 int32_t(0), "^^^^0", status);
1651 expect2(new DecimalFormat("*^##.##", US, status),
1652 -1.3, "^-1.3", status);
374ca955 1653 expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
b75a7d8f 1654 int32_t(0), "0.0E0______ g-m/s^2", status);
374ca955 1655 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
b75a7d8f 1656 1.0/3, "333.333E-3_ g-m/s^2", status);
374ca955 1657 expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
b75a7d8f 1658 int32_t(0), "0.0______ g-m/s^2", status);
374ca955 1659 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
b75a7d8f
A
1660 1.0/3, "0.33333__ g-m/s^2", status);
1661
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);
1680
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);
1697
1698
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);
1717
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);
1734
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)"^^^");
1746 padString.remove();
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);
1753 */
1754
1755}
1756
1757/**
1758 * Upgrade to alphaWorks
1759 */
1760void NumberFormatTest::TestPatterns2(void) {
1761 UErrorCode status = U_ZERO_ERROR;
1762 DecimalFormatSymbols US(Locale::getUS(), status);
1763 CHECK(status, "DecimalFormatSymbols constructor");
1764
1765 DecimalFormat fmt("#", US, status);
1766 CHECK(status, "DecimalFormat constructor");
729e4ab9 1767
b75a7d8f
A
1768 UChar hat = 0x005E; /*^*/
1769
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*/);
1782
1783 fmt.applyPattern("AA#,##0.00ZZ", status);
1784 CHECK(status, "applyPattern");
1785 fmt.setPadCharacter(hat);
1786
1787 fmt.setFormatWidth(10);
1788
1789 fmt.setPadPosition(DecimalFormat::kPadBeforePrefix);
1790 expectPat(fmt, "*^AA#,##0.00ZZ");
1791
1792 fmt.setPadPosition(DecimalFormat::kPadBeforeSuffix);
1793 expectPat(fmt, "AA#,##0.00*^ZZ");
1794
1795 fmt.setPadPosition(DecimalFormat::kPadAfterSuffix);
1796 expectPat(fmt, "AA#,##0.00ZZ*^");
1797
1798 // 12 3456789012
1799 UnicodeString exp("AA*^#,##0.00ZZ", "");
1800 fmt.setFormatWidth(12);
1801 fmt.setPadPosition(DecimalFormat::kPadAfterPrefix);
1802 expectPat(fmt, exp);
1803
1804 fmt.setFormatWidth(13);
1805 // 12 34567890123
1806 expectPat(fmt, "AA*^##,##0.00ZZ");
1807
1808 fmt.setFormatWidth(14);
1809 // 12 345678901234
1810 expectPat(fmt, "AA*^###,##0.00ZZ");
1811
1812 fmt.setFormatWidth(15);
1813 // 12 3456789012345
1814 expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
1815
1816 fmt.setFormatWidth(16);
1817 // 12 34567890123456
3d1f044b 1818 expectPat(fmt, "AA*^#####,##0.00ZZ");
b75a7d8f
A
1819}
1820
1821void NumberFormatTest::TestSurrogateSupport(void) {
1822 UErrorCode status = U_ZERO_ERROR;
1823 DecimalFormatSymbols custom(Locale::getUS(), status);
1824 CHECK(status, "DecimalFormatSymbols constructor");
1825
1826 custom.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, "decimal");
1827 custom.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, "plus");
1828 custom.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, " minus ");
1829 custom.setSymbol(DecimalFormatSymbols::kExponentialSymbol, "exponent");
1830
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);
1837
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;
374ca955 1845 expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
b75a7d8f
A
1846 int32_t(0), "0decimal0exponent0 g-m/s^2", status);
1847 status = U_ZERO_ERROR;
374ca955 1848 expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
b75a7d8f
A
1849 1.0/3, "333decimal333exponent minus 3 g-m/s^2", status);
1850 status = U_ZERO_ERROR;
374ca955 1851 expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
b75a7d8f
A
1852 int32_t(0), "0decimal0 g-m/s^2", status);
1853 status = U_ZERO_ERROR;
374ca955 1854 expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
b75a7d8f
A
1855 1.0/3, "0decimal33333 g-m/s^2", status);
1856
1857 UnicodeString zero((UChar32)0x10000);
729e4ab9
A
1858 UnicodeString one((UChar32)0x10001);
1859 UnicodeString two((UChar32)0x10002);
1860 UnicodeString five((UChar32)0x10005);
b75a7d8f 1861 custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero);
729e4ab9
A
1862 custom.setSymbol(DecimalFormatSymbols::kOneDigitSymbol, one);
1863 custom.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol, two);
1864 custom.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol, five);
b75a7d8f
A
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);
1870
1871 custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, (UChar)0x30);
1872 custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "units of money");
1873 custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, "money separator");
46f4442e 1874 patternStr = UNICODE_STRING_SIMPLE("0.00 \\u00A4' in your bank account'");
b75a7d8f
A
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);
1880
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);
1888}
1889
1890void 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)) {
374ca955 1897 errln("FAIL: Can't create NumberFormat(%s) - %s", locs[i].getName(), u_errorName(ec));
b75a7d8f
A
1898 } else {
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();
1903 if (min != max) {
1904 UnicodeString a, b;
1905 nf->format(1.0, a);
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));
1911 }
1912
1913 // Make sure EURO currency formats have exactly 2 fraction digits
729e4ab9
A
1914 DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
1915 if (df != NULL) {
b75a7d8f
A
1916 if (u_strcmp(EUR, df->getCurrency()) == 0) {
1917 if (min != 2 || max != 2) {
1918 UnicodeString a;
1919 nf->format(1.0, a);
1920 errln((UnicodeString)"FAIL: " + locs[i].getName() +
1921 " is a EURO format but it does not have 2 fraction digits; "
1922 "x 1.0 => " +
1923 escape(a));
1924 }
1925 }
1926 }
1927 }
1928 delete nf;
1929 }
1930}
1931
1932void NumberFormatTest::TestRegCurrency(void) {
374ca955
A
1933#if !UCONFIG_NO_SERVICE
1934 UErrorCode status = U_ZERO_ERROR;
1935 UChar USD[4];
1936 ucurr_forLocale("en_US", USD, 4, &status);
1937 UChar YEN[4];
1938 ucurr_forLocale("ja_JP", YEN, 4, &status);
1939 UChar TMP[4];
3d1f044b 1940
374ca955 1941 if(U_FAILURE(status)) {
729e4ab9 1942 errcheckln(status, "Unable to get currency for locale, error %s", u_errorName(status));
374ca955
A
1943 return;
1944 }
729e4ab9 1945
374ca955 1946 UCurrRegistryKey enkey = ucurr_register(YEN, "en_US", &status);
729e4ab9 1947
374ca955
A
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");
1951 }
b75a7d8f 1952
374ca955
A
1953 int32_t fallbackLen = ucurr_forLocale("en_XX_BAR", TMP, 4, &status);
1954 if (fallbackLen) {
1955 errln("FAIL: tried to fallback en_XX_BAR");
1956 }
1957 status = U_ZERO_ERROR; // reset
729e4ab9 1958
374ca955
A
1959 if (!ucurr_unregister(enkey, &status)) {
1960 errln("FAIL: couldn't unregister enkey");
1961 }
b75a7d8f 1962
729e4ab9 1963 ucurr_forLocale("en_US", TMP, 4, &status);
374ca955
A
1964 if (u_strcmp(USD, TMP) != 0) {
1965 errln("FAIL: didn't return USD for en_US after unregister of en_US");
1966 }
1967 status = U_ZERO_ERROR; // reset
729e4ab9 1968
374ca955
A
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");
1972 }
1973 status = U_ZERO_ERROR; // reset
374ca955
A
1974#endif
1975}
b75a7d8f 1976
374ca955
A
1977void NumberFormatTest::TestCurrencyNames(void) {
1978 // Do a basic check of getName()
1979 // USD { "US$", "US Dollar" } // 04/04/1792-
1980 UErrorCode ec = U_ZERO_ERROR;
46f4442e
A
1981 static const UChar USD[] = {0x55, 0x53, 0x44, 0}; /*USD*/
1982 static const UChar USX[] = {0x55, 0x53, 0x58, 0}; /*USX*/
73c04bcf
A
1983 static const UChar CAD[] = {0x43, 0x41, 0x44, 0}; /*CAD*/
1984 static const UChar ITL[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/
374ca955
A
1985 UBool isChoiceFormat;
1986 int32_t len;
729e4ab9 1987 const UBool possibleDataError = TRUE;
374ca955
A
1988 // Warning: HARD-CODED LOCALE DATA in this test. If it fails, CHECK
1989 // THE LOCALE DATA before diving into the code.
0f5d89e8 1990 assertEquals("USD.getName(SYMBOL_NAME, en)",
46f4442e 1991 UnicodeString("$"),
374ca955
A
1992 UnicodeString(ucurr_getName(USD, "en",
1993 UCURR_SYMBOL_NAME,
729e4ab9
A
1994 &isChoiceFormat, &len, &ec)),
1995 possibleDataError);
0f5d89e8
A
1996 assertEquals("USD.getName(NARROW_SYMBOL_NAME, en)",
1997 UnicodeString("$"),
1998 UnicodeString(ucurr_getName(USD, "en",
1999 UCURR_NARROW_SYMBOL_NAME,
2000 &isChoiceFormat, &len, &ec)),
2001 possibleDataError);
2002 assertEquals("USD.getName(LONG_NAME, en)",
374ca955
A
2003 UnicodeString("US Dollar"),
2004 UnicodeString(ucurr_getName(USD, "en",
2005 UCURR_LONG_NAME,
729e4ab9
A
2006 &isChoiceFormat, &len, &ec)),
2007 possibleDataError);
0f5d89e8 2008 assertEquals("CAD.getName(SYMBOL_NAME, en)",
46f4442e
A
2009 UnicodeString("CA$"),
2010 UnicodeString(ucurr_getName(CAD, "en",
2011 UCURR_SYMBOL_NAME,
729e4ab9
A
2012 &isChoiceFormat, &len, &ec)),
2013 possibleDataError);
0f5d89e8
A
2014 assertEquals("CAD.getName(NARROW_SYMBOL_NAME, en)",
2015 UnicodeString("$"),
2016 UnicodeString(ucurr_getName(CAD, "en",
2017 UCURR_NARROW_SYMBOL_NAME,
2018 &isChoiceFormat, &len, &ec)),
2019 possibleDataError);
2020 assertEquals("CAD.getName(SYMBOL_NAME, en_CA)",
46f4442e
A
2021 UnicodeString("$"),
2022 UnicodeString(ucurr_getName(CAD, "en_CA",
2023 UCURR_SYMBOL_NAME,
729e4ab9
A
2024 &isChoiceFormat, &len, &ec)),
2025 possibleDataError);
0f5d89e8
A
2026 assertEquals("USD.getName(SYMBOL_NAME, en_CA)",
2027 UnicodeString("US$"),
2028 UnicodeString(ucurr_getName(USD, "en_CA",
2029 UCURR_SYMBOL_NAME,
2030 &isChoiceFormat, &len, &ec)),
2031 possibleDataError);
2032 assertEquals("USD.getName(NARROW_SYMBOL_NAME, en_CA)",
2033 UnicodeString("$"),
2034 UnicodeString(ucurr_getName(USD, "en_CA",
2035 UCURR_NARROW_SYMBOL_NAME,
2036 &isChoiceFormat, &len, &ec)),
2037 possibleDataError);
2ca993e8 2038 assertEquals("USD.getName(SYMBOL_NAME) in en_NZ",
46f4442e 2039 UnicodeString("US$"),
2ca993e8 2040 UnicodeString(ucurr_getName(USD, "en_NZ",
46f4442e 2041 UCURR_SYMBOL_NAME,
729e4ab9
A
2042 &isChoiceFormat, &len, &ec)),
2043 possibleDataError);
46f4442e
A
2044 assertEquals("CAD.getName(SYMBOL_NAME)",
2045 UnicodeString("CA$"),
2ca993e8 2046 UnicodeString(ucurr_getName(CAD, "en_NZ",
46f4442e 2047 UCURR_SYMBOL_NAME,
729e4ab9
A
2048 &isChoiceFormat, &len, &ec)),
2049 possibleDataError);
0f5d89e8
A
2050 assertEquals("USX.getName(SYMBOL_NAME)",
2051 UnicodeString("USX"),
2052 UnicodeString(ucurr_getName(USX, "en_US",
2053 UCURR_SYMBOL_NAME,
2054 &isChoiceFormat, &len, &ec)),
2055 possibleDataError);
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)),
2061 possibleDataError);
46f4442e
A
2062 assertEquals("USX.getName(LONG_NAME)",
2063 UnicodeString("USX"),
2064 UnicodeString(ucurr_getName(USX, "en_US",
2065 UCURR_LONG_NAME,
729e4ab9
A
2066 &isChoiceFormat, &len, &ec)),
2067 possibleDataError);
374ca955 2068 assertSuccess("ucurr_getName", ec);
729e4ab9 2069
46f4442e
A
2070 ec = U_ZERO_ERROR;
2071
73c04bcf 2072 // Test that a default or fallback warning is being returned. JB 4239.
46f4442e
A
2073 ucurr_getName(CAD, "es_ES", UCURR_LONG_NAME, &isChoiceFormat,
2074 &len, &ec);
729e4ab9
A
2075 assertTrue("ucurr_getName (es_ES fallback)",
2076 U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
46f4442e
A
2077
2078 ucurr_getName(CAD, "zh_TW", UCURR_LONG_NAME, &isChoiceFormat,
73c04bcf 2079 &len, &ec);
729e4ab9
A
2080 assertTrue("ucurr_getName (zh_TW fallback)",
2081 U_USING_FALLBACK_WARNING == ec, TRUE, possibleDataError);
46f4442e
A
2082
2083 ucurr_getName(CAD, "en_US", UCURR_LONG_NAME, &isChoiceFormat,
2084 &len, &ec);
729e4ab9
A
2085 assertTrue("ucurr_getName (en_US default)",
2086 U_USING_DEFAULT_WARNING == ec || U_USING_FALLBACK_WARNING == ec, TRUE);
2087
4388f060 2088 ucurr_getName(CAD, "ti", UCURR_LONG_NAME, &isChoiceFormat,
73c04bcf 2089 &len, &ec);
4388f060 2090 assertTrue("ucurr_getName (ti default)",
73c04bcf 2091 U_USING_DEFAULT_WARNING == ec, TRUE);
729e4ab9 2092
73c04bcf 2093 // Test that a default warning is being returned when falling back to root. JB 4536.
46f4442e 2094 ucurr_getName(ITL, "cy", UCURR_LONG_NAME, &isChoiceFormat,
73c04bcf 2095 &len, &ec);
729e4ab9 2096 assertTrue("ucurr_getName (cy default to root)",
73c04bcf 2097 U_USING_DEFAULT_WARNING == ec, TRUE);
729e4ab9 2098
374ca955 2099 // TODO add more tests later
b75a7d8f
A
2100}
2101
3d1f044b
A
2102void NumberFormatTest::Test20484_NarrowSymbolFallback(){
2103 IcuTestErrorCode status(*this, "Test20484_NarrowSymbolFallback");
2104
2105 struct TestCase {
2106 const char* locale;
2107 const char16_t* isoCode;
2108 const char16_t* expectedShort;
2109 const char16_t* expectedNarrow;
2110 UErrorCode expectedNarrowError;
2111 } cases[] = {
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
2118 };
2119 for (const auto& cas : cases) {
2120 status.setScope(cas.isoCode);
2121 UBool choiceFormatIgnored;
2122 int32_t lengthIgnored;
2123 const UChar* actualShort = ucurr_getName(
2124 cas.isoCode,
2125 cas.locale,
2126 UCURR_SYMBOL_NAME,
2127 &choiceFormatIgnored,
2128 &lengthIgnored,
2129 status);
2130 status.errIfFailureAndReset();
2131 const UChar* actualNarrow = ucurr_getName(
2132 cas.isoCode,
2133 cas.locale,
2134 UCURR_NARROW_SYMBOL_NAME,
2135 &choiceFormatIgnored,
2136 &lengthIgnored,
2137 status);
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);
2143 }
2144}
2145
73c04bcf
A
2146void NumberFormatTest::TestCurrencyUnit(void){
2147 UErrorCode ec = U_ZERO_ERROR;
0f5d89e8
A
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";
3d1f044b
A
2154 static const UChar INV[] = u"{$%";
2155 static const char INV8[] = "{$%";
2156 static const UChar ZZZ[] = u"zz";
2157 static const char ZZZ8[] = "zz";
2158
2159 UChar* EUR = (UChar*) malloc(6);
2160 EUR[0] = u'E';
2161 EUR[1] = u'U';
2162 EUR[2] = u'R';
2163 char* EUR8 = (char*) malloc(3);
2164 EUR8[0] = 'E';
2165 EUR8[1] = 'U';
2166 EUR8[2] = 'R';
2167
73c04bcf
A
2168 CurrencyUnit cu(USD, ec);
2169 assertSuccess("CurrencyUnit", ec);
2170
0f5d89e8
A
2171 assertEquals("getISOCurrency()", USD, cu.getISOCurrency());
2172 assertEquals("getSubtype()", USD8, cu.getSubtype());
73c04bcf 2173
3d1f044b
A
2174 CurrencyUnit inv(INV, ec);
2175 assertEquals("non-invariant", U_INVARIANT_CONVERSION_ERROR, ec);
2176 assertEquals("non-invariant", XXX, inv.getISOCurrency());
2177 ec = U_ZERO_ERROR;
2178
2179 CurrencyUnit zzz(ZZZ, ec);
2180 assertEquals("too short", U_ILLEGAL_ARGUMENT_ERROR, ec);
2181 assertEquals("too short", XXX, zzz.getISOCurrency());
2182 ec = U_ZERO_ERROR;
2183
2184 CurrencyUnit eur(EUR, ec);
2185 assertEquals("non-nul-terminated", u"EUR", eur.getISOCurrency());
2186 assertEquals("non-nul-terminated", "EUR", eur.getSubtype());
2187
2188 // Test StringPiece constructor
2189 CurrencyUnit cu8(USD8, ec);
2190 assertEquals("StringPiece constructor", USD, cu8.getISOCurrency());
2191
2192 CurrencyUnit inv8(INV8, ec);
2193 assertEquals("non-invariant 8", U_INVARIANT_CONVERSION_ERROR, ec);
2194 assertEquals("non-invariant 8", XXX, inv8.getISOCurrency());
2195 ec = U_ZERO_ERROR;
2196
2197 CurrencyUnit zzz8(ZZZ8, ec);
2198 assertEquals("too short 8", U_ILLEGAL_ARGUMENT_ERROR, ec);
2199 assertEquals("too short 8", XXX, zzz8.getISOCurrency());
2200 ec = U_ZERO_ERROR;
2201
2202 CurrencyUnit zzz8b({ZZZ8, 3}, ec);
2203 assertEquals("too short 8b", U_ILLEGAL_ARGUMENT_ERROR, ec);
2204 assertEquals("too short 8b", XXX, zzz8b.getISOCurrency());
2205 ec = U_ZERO_ERROR;
2206
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());
2210
73c04bcf
A
2211 CurrencyUnit cu2(cu);
2212 if (!(cu2 == cu)){
2213 errln("CurrencyUnit copy constructed object should be same");
2214 }
2215
2216 CurrencyUnit * cu3 = (CurrencyUnit *)cu.clone();
2217 if (!(*cu3 == cu)){
2218 errln("CurrencyUnit cloned object should be same");
2219 }
57a6839d
A
2220 CurrencyUnit bad(BAD, ec);
2221 assertSuccess("CurrencyUnit", ec);
2222 if (cu.getIndex() == bad.getIndex()) {
2223 errln("Indexes of different currencies should differ.");
2224 }
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.");
2229 }
2230 if (bad == bad2) {
2231 errln("Different unrecognized currencies should not be equal.");
2232 }
2233 bad = bad2;
2234 if (bad != bad2) {
2235 errln("Currency unit assignment should be the same.");
2236 }
73c04bcf 2237 delete cu3;
0f5d89e8
A
2238
2239 // Test default constructor
2240 CurrencyUnit def;
2241 assertEquals("Default currency", XXX, def.getISOCurrency());
2242 assertEquals("Default currency as subtype", XXX8, def.getSubtype());
2243
2244 // Test slicing
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());
2256
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());
3d1f044b
A
2263
2264 free(EUR);
2265 free(EUR8);
73c04bcf
A
2266}
2267
2268void 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);
2273
2274 CurrencyAmount ca2(ca);
2275 if (!(ca2 == ca)){
2276 errln("CurrencyAmount copy constructed object should be same");
2277 }
2278
2279 ca2=ca;
2280 if (!(ca2 == ca)){
2281 errln("CurrencyAmount assigned object should be same");
2282 }
729e4ab9 2283
73c04bcf
A
2284 CurrencyAmount *ca3 = (CurrencyAmount *)ca.clone();
2285 if (!(*ca3 == ca)){
2286 errln("CurrencyAmount cloned object should be same");
2287 }
2288 delete ca3;
2289}
2290
b75a7d8f
A
2291void NumberFormatTest::TestSymbolsWithBadLocale(void) {
2292 Locale locDefault;
4388f060
A
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",
2296
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
2300
2301 unsigned int i;
2ca993e8 2302 for (i = 0; i < UPRV_LENGTHOF(badLocales); i++) {
4388f060
A
2303 const char *localeName = badLocales[i];
2304 Locale locBad(localeName);
3d1f044b 2305 assertTrue(WHERE, !locBad.isBogus());
4388f060
A
2306 UErrorCode status = U_ZERO_ERROR;
2307 UnicodeString intlCurrencySymbol((UChar)0xa4);
b75a7d8f 2308
4388f060 2309 intlCurrencySymbol.append((UChar)0xa4);
0f5d89e8 2310
4388f060
A
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.");
2317 }
2318 if (strcmp(mySymbols.getLocale().getName(), locBad.getName()) != 0) {
2319 errln("DecimalFormatSymbols does not have the right locale.", locBad.getName());
2320 }
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)
2328 {
2329 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum);
2330 }
b75a7d8f 2331 }
4388f060
A
2332
2333 status = U_ZERO_ERROR;
2334 Locale::setDefault(locDefault, status);
2335 logln("Current locale is %s", Locale::getDefault().getName());
b75a7d8f 2336 }
b75a7d8f
A
2337}
2338
2339/**
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.)
2343 */
2344void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
2345 UErrorCode ec = U_ZERO_ERROR;
2346 DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2347 if (U_FAILURE(ec)) {
729e4ab9 2348 errcheckln(ec, "Fail: DecimalFormatSymbols constructor - %s", u_errorName(ec));
b75a7d8f
A
2349 delete sym;
2350 return;
2351 }
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");
2357 return;
2358 }
2359
2360 UnicodeString str;
2361 fmt.format(2350.75, str);
2362 if (str == "$ 2,350.75") {
2363 logln(str);
2364 } else {
729e4ab9 2365 dataerrln("Fail: " + str + ", expected $ 2,350.75");
b75a7d8f
A
2366 }
2367
2368 sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2369 if (U_FAILURE(ec)) {
2370 errln("Fail: DecimalFormatSymbols constructor");
2371 delete sym;
2372 return;
2373 }
2374 sym->setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
2375 fmt.adoptDecimalFormatSymbols(sym);
2376
2377 str.truncate(0);
2378 fmt.format(2350.75, str);
2379 if (str == "Q 2,350.75") {
2380 logln(str);
2381 } else {
729e4ab9 2382 dataerrln("Fail: adoptDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
b75a7d8f
A
2383 }
2384
2385 sym = new DecimalFormatSymbols(Locale::getUS(), ec);
2386 if (U_FAILURE(ec)) {
2387 errln("Fail: DecimalFormatSymbols constructor");
2388 delete sym;
2389 return;
2390 }
2391 DecimalFormat fmt2(pat, sym, ec);
2392 if (U_FAILURE(ec)) {
2393 errln("Fail: DecimalFormat constructor");
2394 return;
2395 }
729e4ab9 2396
b75a7d8f
A
2397 DecimalFormatSymbols sym2(Locale::getUS(), ec);
2398 if (U_FAILURE(ec)) {
2399 errln("Fail: DecimalFormatSymbols constructor");
2400 return;
2401 }
2402 sym2.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
2403 fmt2.setDecimalFormatSymbols(sym2);
2404
2405 str.truncate(0);
2406 fmt2.format(2350.75, str);
2407 if (str == "Q 2,350.75") {
2408 logln(str);
2409 } else {
729e4ab9 2410 dataerrln("Fail: setDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
b75a7d8f
A
2411 }
2412}
2413
374ca955
A
2414void NumberFormatTest::TestPerMill() {
2415 UErrorCode ec = U_ZERO_ERROR;
2416 UnicodeString str;
2417 DecimalFormat fmt(ctou("###.###\\u2030"), ec);
2418 if (!assertSuccess("DecimalFormat ct", ec)) return;
2419 assertEquals("0.4857 x ###.###\\u2030",
0f5d89e8 2420 ctou("485.7\\u2030"), fmt.format(0.4857, str), true);
729e4ab9 2421
374ca955 2422 DecimalFormatSymbols sym(Locale::getUS(), ec);
0f5d89e8
A
2423 if (!assertSuccess("", ec, true, __FILE__, __LINE__)) {
2424 return;
2425 }
374ca955
A
2426 sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, ctou("m"));
2427 DecimalFormat fmt2("", sym, ec);
0f5d89e8
A
2428 if (!assertSuccess("", ec, true, __FILE__, __LINE__)) {
2429 return;
2430 }
374ca955
A
2431 fmt2.applyLocalizedPattern("###.###m", ec);
2432 if (!assertSuccess("setup", ec)) return;
2433 str.truncate(0);
2434 assertEquals("0.4857 x ###.###m",
2435 "485.7m", fmt2.format(0.4857, str));
2436}
2437
2438/**
2439 * Generic test for patterns that should be legal/illegal.
2440 */
2441void NumberFormatTest::TestIllegalPatterns() {
2442 // Test cases:
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
2447 "-:000.000|###",
2448 "+:000.000'|###'",
2449 0
2450 };
2451 for (int32_t i=0; DATA[i]; ++i) {
2452 const char* pat=DATA[i];
2453 UBool valid = (*pat) == '+';
2454 pat += 2;
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));
2460 } else {
729e4ab9 2461 errcheckln(ec, "FAIL: pattern \"%s\" should have %s; got %s",
374ca955
A
2462 pat, (valid?"succeeded":"failed"),
2463 u_errorName(ec));
2464 }
2465 }
2466}
2467
2468//----------------------------------------------------------------------
2469
2470static 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>
2480 0
2481};
2482
2483/**
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
2487 * the list.
2488 */
2489static int32_t keywordIndex(const UnicodeString& tok) {
2490 for (int32_t i=0; KEYWORDS[i]!=0; ++i) {
2491 if (tok==KEYWORDS[i]) {
2492 return i;
2493 }
2494 }
2495 return -1;
2496}
2497
2498/**
2499 * Parse a CurrencyAmount using the given NumberFormat, with
2500 * the 'delim' character separating the number and the currency.
2501 */
2502static void parseCurrencyAmount(const UnicodeString& str,
2503 const NumberFormat& fmt,
2504 UChar delim,
2505 Formattable& result,
2506 UErrorCode& ec) {
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);
2511 Formattable n;
2512 fmt.parse(num, n, ec);
2513 result.adoptObject(new CurrencyAmount(n, cur.getTerminatedBuffer(), ec));
2514}
2515
2516void NumberFormatTest::TestCases() {
2517 UErrorCode ec = U_ZERO_ERROR;
2518 TextFile reader("NumberFormatTestCases.txt", "UTF8", ec);
2519 if (U_FAILURE(ec)) {
729e4ab9 2520 dataerrln("Couldn't open NumberFormatTestCases.txt");
374ca955
A
2521 return;
2522 }
2523 TokenIterator tokens(&reader);
2524
2525 Locale loc("en", "US", "");
2526 DecimalFormat *ref = 0, *fmt = 0;
2527 MeasureFormat *mfmt = 0;
2528 UnicodeString pat, tok, mloc, str, out, where, currAmt;
2529 Formattable n;
2530
2531 for (;;) {
2532 ec = U_ZERO_ERROR;
2533 if (!tokens.next(tok, ec)) {
2534 break;
2535 }
2536 where = UnicodeString("(") + tokens.getLineNumber() + ") ";
2537 int32_t cmd = keywordIndex(tok);
2538 switch (cmd) {
2539 case 0:
2540 // ref= <reference pattern>
2541 if (!tokens.next(tok, ec)) goto error;
2542 delete ref;
2543 ref = new DecimalFormat(tok,
2544 new DecimalFormatSymbols(Locale::getUS(), ec), ec);
73c04bcf
A
2545 if (U_FAILURE(ec)) {
2546 dataerrln("Error constructing DecimalFormat");
2547 goto error;
2548 }
374ca955
A
2549 break;
2550 case 1:
2551 // loc= <locale>
2552 if (!tokens.next(tok, ec)) goto error;
729e4ab9 2553 loc = Locale::createFromName(CharString().appendInvariantChars(tok, ec).data());
374ca955
A
2554 break;
2555 case 2: // f:
2556 case 3: // fp:
2557 case 4: // rt:
2558 case 5: // p:
2559 if (!tokens.next(tok, ec)) goto error;
2560 if (tok != "-") {
2561 pat = tok;
2562 delete fmt;
2563 fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc, ec), ec);
2564 if (U_FAILURE(ec)) {
2565 errln("FAIL: " + where + "Pattern \"" + pat + "\": " + u_errorName(ec));
2566 ec = U_ZERO_ERROR;
2567 if (!tokens.next(tok, ec)) goto error;
2568 if (!tokens.next(tok, ec)) goto error;
2569 if (cmd == 3) {
2570 if (!tokens.next(tok, ec)) goto error;
2571 }
2572 continue;
2573 }
2574 }
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>
2579 UnicodeString num;
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);
2591 }
2592 if (cmd != 2) { // != f:
2593 Formattable m;
2594 fmt->parse(str, m, ec);
2595 assertSuccess("parse", ec);
2596 assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
2597 n, m);
729e4ab9 2598 }
374ca955
A
2599 }
2600 // p: <pattern or '-'> <string to parse> <exp. number>
2601 else {
2602 UnicodeString expstr;
2603 if (!tokens.next(str, ec)) goto error;
2604 if (!tokens.next(expstr, ec)) goto error;
2605 Formattable exp, n;
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 + "\")",
2611 exp, n);
2612 }
2613 break;
2614 case 8: // fpc:
2615 if (!tokens.next(tok, ec)) goto error;
2616 if (tok != "-") {
2617 mloc = tok;
2618 delete mfmt;
2619 mfmt = MeasureFormat::createCurrencyFormat(
729e4ab9
A
2620 Locale::createFromName(
2621 CharString().appendInvariantChars(mloc, ec).data()), ec);
374ca955
A
2622 if (U_FAILURE(ec)) {
2623 errln("FAIL: " + where + "Loc \"" + mloc + "\": " + u_errorName(ec));
2624 ec = U_ZERO_ERROR;
2625 if (!tokens.next(tok, ec)) goto error;
2626 if (!tokens.next(tok, ec)) goto error;
2627 if (!tokens.next(tok, ec)) goto error;
2628 continue;
2629 }
b331163b
A
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;
2635 continue;
374ca955
A
2636 }
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);
2645 }
2646 if (!tokens.next(currAmt, ec)) goto error;
2647 parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
2648 if (assertSuccess("parseCurrencyAmount", ec)) {
2649 Formattable m;
729e4ab9 2650
374ca955
A
2651 mfmt->parseObject(str, m, ec);
2652 if (assertSuccess("parseCurrency", ec)) {
2653 assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",
2654 n, m);
729e4ab9
A
2655 } else {
2656 errln("FAIL: source " + str);
374ca955
A
2657 }
2658 }
2659 break;
2660 case 6:
2661 // perr: <pattern or '-'> <invalid string>
2662 errln("FAIL: Under construction");
2663 goto done;
2664 case 7: {
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 == "-") {
2673 if (err) {
2674 errln("FAIL: " + where + "Invalid command \"pat: - err\"");
2675 continue;
2676 }
2677 existingPat = TRUE;
2678 testpat = pat;
2679 }
2680 if (exppat == "-") exppat = testpat;
2681 DecimalFormat* f = 0;
2682 UErrorCode ec2 = U_ZERO_ERROR;
2683 if (existingPat) {
2684 f = fmt;
2685 } else {
2686 f = new DecimalFormat(testpat, ec2);
2687 }
2688 if (U_SUCCESS(ec2)) {
2689 if (err) {
2690 errln("FAIL: " + where + "Invalid pattern \"" + testpat +
2691 "\" was accepted");
2692 } else {
2693 UnicodeString pat2;
2694 assertEquals(where + "\"" + testpat + "\".toPattern()",
2695 exppat, f->toPattern(pat2));
2696 }
2697 } else {
2698 if (err) {
2699 logln("Ok: " + where + "Invalid pattern \"" + testpat +
2700 "\" failed: " + u_errorName(ec2));
2701 } else {
2702 errln("FAIL: " + where + "Valid pattern \"" + testpat +
2703 "\" failed: " + u_errorName(ec2));
2704 }
2705 }
2706 if (!existingPat) delete f;
2707 } break;
2708 case -1:
2709 errln("FAIL: " + where + "Unknown command \"" + tok + "\"");
2710 goto done;
2711 }
2712 }
2713 goto done;
2714
2715 error:
2716 if (U_SUCCESS(ec)) {
2717 errln("FAIL: Unexpected EOF");
2718 } else {
729e4ab9 2719 errcheckln(ec, "FAIL: " + where + "Unexpected " + u_errorName(ec));
374ca955
A
2720 }
2721
2722 done:
2723 delete mfmt;
2724 delete fmt;
2725 delete ref;
2726}
2727
2728
b75a7d8f
A
2729//----------------------------------------------------------------------
2730// Support methods
2731//----------------------------------------------------------------------
2732
2733UBool NumberFormatTest::equalValue(const Formattable& a, const Formattable& b) {
374ca955
A
2734 if (a.getType() == b.getType()) {
2735 return a == b;
2736 }
2737
b75a7d8f 2738 if (a.getType() == Formattable::kLong) {
374ca955 2739 if (b.getType() == Formattable::kInt64) {
b75a7d8f
A
2740 return a.getLong() == b.getLong();
2741 } else if (b.getType() == Formattable::kDouble) {
729e4ab9 2742 return (double) a.getLong() == b.getDouble(); // TODO check use of double instead of long
b75a7d8f
A
2743 }
2744 } else if (a.getType() == Formattable::kDouble) {
2745 if (b.getType() == Formattable::kLong) {
2746 return a.getDouble() == (double) b.getLong();
374ca955
A
2747 } else if (b.getType() == Formattable::kInt64) {
2748 return a.getDouble() == (double)b.getInt64();
2749 }
2750 } else if (a.getType() == Formattable::kInt64) {
2751 if (b.getType() == Formattable::kLong) {
2752 return a.getInt64() == (int64_t)b.getLong();
b75a7d8f 2753 } else if (b.getType() == Formattable::kDouble) {
374ca955 2754 return a.getInt64() == (int64_t)b.getDouble();
b75a7d8f
A
2755 }
2756 }
2757 return FALSE;
2758}
2759
729e4ab9
A
2760void 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);
2764}
2765
b75a7d8f
A
2766void 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);
2770}
2771
2772void NumberFormatTest::expect2(NumberFormat* fmt, const Formattable& n,
2773 const UnicodeString& exp,
2774 UErrorCode status) {
729e4ab9
A
2775 if (fmt == NULL || U_FAILURE(status)) {
2776 dataerrln("FAIL: NumberFormat constructor");
b75a7d8f
A
2777 } else {
2778 expect2(*fmt, n, exp);
2779 }
2780 delete fmt;
2781}
2782
2783void NumberFormatTest::expect(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2784 UErrorCode status = U_ZERO_ERROR;
2785 Formattable num;
2786 fmt.parse(str, num, status);
2787 if (U_FAILURE(status)) {
729e4ab9 2788 dataerrln(UnicodeString("FAIL: Parse failed for \"") + str + "\" - " + u_errorName(status));
b75a7d8f
A
2789 return;
2790 }
2791 UnicodeString pat;
2792 ((DecimalFormat*) &fmt)->toPattern(pat);
2793 if (equalValue(num, n)) {
2794 logln(UnicodeString("Ok \"") + str + "\" x " +
2795 pat + " = " +
2796 toString(num));
2797 } else {
729e4ab9 2798 dataerrln(UnicodeString("FAIL \"") + str + "\" x " +
b75a7d8f
A
2799 pat + " = " +
2800 toString(num) + ", expected " + toString(n));
2801 }
2802}
2803
729e4ab9
A
2804void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2805 UErrorCode status = U_ZERO_ERROR;
2806 Formattable num;
2807 fmt.parse(str, num, status);
2808 if (U_FAILURE(status)) {
2809 errln(UnicodeString("FAIL: Parse failed for \"") + str + "\"");
2810 return;
2811 }
2812 if (equalValue(num, n)) {
2813 logln(UnicodeString("Ok \"") + str + " = " +
2814 toString(num));
2815 } else {
2816 errln(UnicodeString("FAIL \"") + str + " = " +
2817 toString(num) + ", expected " + toString(n));
2818 }
2819}
2820
2821void NumberFormatTest::expect_rbnf(NumberFormat& fmt, const Formattable& n,
2822 const UnicodeString& exp, UBool rt) {
2823 UnicodeString saw;
2824 FieldPosition pos;
2825 UErrorCode status = U_ZERO_ERROR;
2826 fmt.format(n, saw, pos, status);
2827 CHECK(status, "NumberFormat::format");
2828 if (saw == exp) {
2829 logln(UnicodeString("Ok ") + toString(n) +
2830 " = \"" +
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):
2835 if (rt) {
2836 Formattable n2;
2837 fmt.parse(exp, n2, status);
2838 if (U_FAILURE(status)) {
2839 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\"");
2840 return;
2841 }
2842 UnicodeString saw2;
2843 fmt.format(n2, saw2, pos, status);
2844 CHECK(status, "NumberFormat::format");
2845 if (saw2 != exp) {
2846 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2847 " => \"" + saw2 + "\"");
2848 }
2849 }
2850 } else {
2851 errln(UnicodeString("FAIL ") + toString(n) +
2852 " = \"" +
2853 escape(saw) + "\", expected \"" + exp + "\"");
2854 }
2855}
2856
b75a7d8f
A
2857void NumberFormatTest::expect(NumberFormat& fmt, const Formattable& n,
2858 const UnicodeString& exp, UBool rt) {
2859 UnicodeString saw;
2860 FieldPosition pos;
2861 UErrorCode status = U_ZERO_ERROR;
2862 fmt.format(n, saw, pos, status);
2863 CHECK(status, "NumberFormat::format");
2864 UnicodeString pat;
2865 ((DecimalFormat*) &fmt)->toPattern(pat);
2866 if (saw == exp) {
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):
2873 if (rt) {
2874 Formattable n2;
2875 fmt.parse(exp, n2, status);
2876 if (U_FAILURE(status)) {
729e4ab9 2877 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\" - " + u_errorName(status));
b75a7d8f
A
2878 return;
2879 }
2880 UnicodeString saw2;
2881 fmt.format(n2, saw2, pos, status);
2882 CHECK(status, "NumberFormat::format");
2883 if (saw2 != exp) {
2884 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2885 " => \"" + saw2 + "\"");
2886 }
2887 }
2888 } else {
729e4ab9 2889 dataerrln(UnicodeString("FAIL ") + toString(n) + " x " +
b75a7d8f
A
2890 escape(pat) + " = \"" +
2891 escape(saw) + "\", expected \"" + exp + "\"");
2892 }
2893}
2894
2895void NumberFormatTest::expect(NumberFormat* fmt, const Formattable& n,
57a6839d 2896 const UnicodeString& exp, UBool rt,
b75a7d8f 2897 UErrorCode status) {
729e4ab9
A
2898 if (fmt == NULL || U_FAILURE(status)) {
2899 dataerrln("FAIL: NumberFormat constructor");
b75a7d8f 2900 } else {
57a6839d 2901 expect(*fmt, n, exp, rt);
b75a7d8f
A
2902 }
2903 delete fmt;
2904}
2905
2906void 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};
374ca955
A
2911 UChar curr[4];
2912 u_strcpy(curr, DEFAULT_CURR);
b75a7d8f 2913 if (*locale.getLanguage() != 0) {
374ca955
A
2914 ucurr_forLocale(locale.getName(), curr, 4, &ec);
2915 assertSuccess("ucurr_forLocale", ec);
2916 fmt.setCurrency(curr, ec);
2917 assertSuccess("DecimalFormat::setCurrency", ec);
73c04bcf 2918 fmt.setCurrency(curr); //Deprecated variant, for coverage only
b75a7d8f
A
2919 }
2920 UnicodeString s;
2921 fmt.format(value, s);
2922 s.findAndReplace((UChar32)0x00A0, (UChar32)0x0020);
2923
2924 // Default display of the number yields "1234.5599999999999"
2925 // instead of "1234.56". Use a formatter to fix this.
729e4ab9 2926 NumberFormat* f =
b75a7d8f
A
2927 NumberFormat::createInstance(Locale::getUS(), ec);
2928 UnicodeString v;
2929 if (U_FAILURE(ec)) {
2930 // Oops; bad formatter. Use default op+= display.
2931 v = (UnicodeString)"" + value;
2932 } else {
2933 f->setMaximumFractionDigits(4);
2934 f->setGroupingUsed(FALSE);
2935 f->format(value, v);
2936 }
2937 delete f;
2938
2939 if (s == string) {
2940 logln((UnicodeString)"Ok: " + v + " x " + curr + " => " + prettify(s));
2941 } else {
2942 errln((UnicodeString)"FAIL: " + v + " x " + curr + " => " + prettify(s) +
2943 ", expected " + prettify(string));
2944 }
2945}
2946
2947void NumberFormatTest::expectPat(DecimalFormat& fmt, const UnicodeString& exp) {
2948 UnicodeString pat;
2949 fmt.toPattern(pat);
2950 if (pat == exp) {
2951 logln(UnicodeString("Ok \"") + pat + "\"");
2952 } else {
2953 errln(UnicodeString("FAIL \"") + pat + "\", expected \"" + exp + "\"");
2954 }
2955}
2956
2957void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2958 int32_t pos) {
2959 expectPad(fmt, pat, pos, 0, (UnicodeString)"");
2960}
2961void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2962 int32_t pos, int32_t width, UChar pad) {
2963 expectPad(fmt, pat, pos, width, UnicodeString(pad));
2964}
2965void 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();
2975 } else {
2976 apos = -1;
2977 awidth = width;
2978 apadStr = pad;
2979 }
2980 if (apos == pos && awidth == width && apadStr == pad) {
374ca955
A
2981 UnicodeString infoStr;
2982 if (pos == ILLEGAL) {
2983 infoStr = UnicodeString(" width=", "") + awidth + UnicodeString(" pad=", "") + apadStr;
2984 }
2985 logln(UnicodeString("Ok \"") + pat + "\" pos=" + apos + infoStr);
b75a7d8f
A
2986 } else {
2987 errln(UnicodeString("FAIL \"") + pat + "\" pos=" + apos +
2988 " width=" + awidth + " pad=" + apadStr +
2989 ", expected " + pos + " " + width + " " + pad);
2990 }
2991}
57a6839d
A
2992
2993// This test is flaky b/c the symbols for CNY and JPY are equivalent in this locale - FIXME
2994void NumberFormatTest::TestCompatibleCurrencies() {
2995/*
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.");
3003 return;
3004 }
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");
3011
3012 LocalPointer<NumberFormat> fmtTW(
3013 NumberFormat::createCurrencyInstance(Locale::getTaiwan(), status));
3014
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");
3019
3020 LocalPointer<NumberFormat> fmtJP(
3021 NumberFormat::createCurrencyInstance(Locale::getJapan(), status));
3022
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");
0f5d89e8 3027
57a6839d
A
3028 // more..
3029*/
3030}
3031
3032void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar* currency, double amount, const char *text) {
3033 ParsePosition ppos;
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.");
3038 return;
3039 }
3040 UErrorCode status = U_ZERO_ERROR;
3041
3042 char theInfo[100];
3043 sprintf(theInfo, "For locale %s, string \"%s\", currency ",
3044 fmt.getLocale(ULOC_ACTUAL_LOCALE, status).getBaseName(),
3045 text);
3046 u_austrcpy(theInfo+uprv_strlen(theInfo), currency);
0f5d89e8 3047
57a6839d
A
3048 char theOperation[100];
3049
3050 uprv_strcpy(theOperation, theInfo);
3051 uprv_strcat(theOperation, ", check amount:");
3052 assertTrue(theOperation, amount == currencyAmount->getNumber().getDouble(status));
3053
3054 uprv_strcpy(theOperation, theInfo);
3055 uprv_strcat(theOperation, ", check currency:");
3056 assertEquals(theOperation, currency, currencyAmount->getISOCurrency());
3057}
0f5d89e8 3058
57a6839d 3059
73c04bcf
A
3060void NumberFormatTest::TestJB3832(){
3061 const char* localeID = "pt_PT@currency=PTE";
3062 Locale loc(localeID);
3063 UErrorCode status = U_ZERO_ERROR;
3d1f044b 3064 UnicodeString expected(CharsToUnicodeString("1150$50\\u00A0\\u200B")); // per cldrbug 7670
73c04bcf
A
3065 UnicodeString s;
3066 NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(loc, status);
3067 if(U_FAILURE(status)){
729e4ab9 3068 dataerrln("Could not create currency formatter for locale %s - %s", localeID, u_errorName(status));
73c04bcf
A
3069 return;
3070 }
3071 currencyFmt->format(1150.50, s);
3072 if(s!=expected){
729e4ab9
A
3073 errln(UnicodeString("FAIL: Expected: ")+expected
3074 + UnicodeString(" Got: ") + s
73c04bcf
A
3075 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
3076 }
3077 if (U_FAILURE(status)){
3078 errln("FAIL: Status %s", u_errorName(status));
3079 }
3080 delete currencyFmt;
3081}
3082
3083void NumberFormatTest::TestHost()
3084{
4388f060 3085#if U_PLATFORM_USES_ONLY_WIN32_API
73c04bcf
A
3086 Win32NumberTest::testLocales(this);
3087#endif
4388f060
A
3088 Locale loc("en_US@compat=host");
3089 for (UNumberFormatStyle k = UNUM_DECIMAL;
3090 k < UNUM_FORMAT_STYLE_COUNT; k = (UNumberFormatStyle)(k+1)) {
729e4ab9 3091 UErrorCode status = U_ZERO_ERROR;
4388f060
A
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));
3097 }
3098 continue;
3099 }
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));
729e4ab9
A
3103 return;
3104 }
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");
3110 return;
3111 }
3112 Formattable formattable;
3113 full->parse(result1, formattable, status);
3114 if (U_FAILURE(status)) {
3115 errln("FAIL: Can't parse for host");
3116 return;
3117 }
729e4ab9 3118 }
73c04bcf
A
3119}
3120
46f4442e
A
3121void NumberFormatTest::TestHostClone()
3122{
3123 /*
3124 Verify that a cloned formatter gives the same results
3125 and is useable after the original has been deleted.
3126 */
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)) {
f3c0d7a5 3133 dataerrln("FAIL: Can't create NumberFormat date instance - %s", u_errorName(status));
46f4442e
A
3134 return;
3135 }
3136 UnicodeString result1;
3137 full->format(now, result1, status);
3138 Format *fullClone = full->clone();
3139 delete full;
3140 full = NULL;
3141
3142 UnicodeString result2;
3143 fullClone->format(now, result2, status);
3144 if (U_FAILURE(status)) {
3145 errln("FAIL: format failure.");
3146 }
3147 if (result1 != result2) {
3148 errln("FAIL: Clone returned different result from non-clone.");
3149 }
3150 delete fullClone;
3151}
3152
73c04bcf
A
3153void NumberFormatTest::TestCurrencyFormat()
3154{
3155 // This test is here to increase code coverage.
3156 UErrorCode status = U_ZERO_ERROR;
3157 MeasureFormat *cloneObj;
3158 UnicodeString str;
3159 Formattable toFormat, result;
3160 static const UChar ISO_CODE[4] = {0x0047, 0x0042, 0x0050, 0};
3161
3162 Locale saveDefaultLocale = Locale::getDefault();
3163 Locale::setDefault( Locale::getUK(), status );
3164 if (U_FAILURE(status)) {
3165 errln("couldn't set default Locale!");
3166 return;
3167 }
3168
3169 MeasureFormat *measureObj = MeasureFormat::createCurrencyFormat(status);
f3c0d7a5
A
3170 if (U_FAILURE(status)){
3171 dataerrln("FAIL: MeasureFormat::createCurrencyFormat status %s", u_errorName(status));
3172 return;
3173 }
73c04bcf
A
3174 Locale::setDefault( saveDefaultLocale, status );
3175 if (U_FAILURE(status)){
f3c0d7a5 3176 dataerrln("FAIL: Locale::setDefault status %s", u_errorName(status));
73c04bcf
A
3177 return;
3178 }
3179 cloneObj = (MeasureFormat *)measureObj->clone();
3180 if (cloneObj == NULL) {
3181 errln("Clone doesn't work");
3182 return;
3183 }
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));
3189 }
3190 if (result != toFormat) {
3191 errln("measureObj does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
3192 }
3193 status = U_ZERO_ERROR;
3194 str.truncate(0);
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));
3199 }
3200 if (result != toFormat) {
3201 errln("Clone does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
3202 }
46f4442e
A
3203 if (*measureObj != *cloneObj) {
3204 errln("Cloned object is not equal to the original object");
3205 }
73c04bcf
A
3206 delete measureObj;
3207 delete cloneObj;
3208
46f4442e
A
3209 status = U_USELESS_COLLATOR_ERROR;
3210 if (MeasureFormat::createCurrencyFormat(status) != NULL) {
3211 errln("createCurrencyFormat should have returned NULL.");
3212 }
3213}
3214
3215/* Port of ICU4J rounding test. */
3216void NumberFormatTest::TestRounding() {
3217 UErrorCode status = U_ZERO_ERROR;
3218 DecimalFormat *df = (DecimalFormat*)NumberFormat::createCurrencyInstance(Locale::getEnglish(), status);
3219
3220 if (U_FAILURE(status)) {
729e4ab9 3221 dataerrln("Unable to create decimal formatter. - %s", u_errorName(status));
46f4442e
A
3222 return;
3223 }
3224
3225 int roundingIncrements[]={1, 2, 5, 20, 50, 100};
3226 int testValues[]={0, 300};
3227
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);
3237 }
3238 }
3239 }
3240 delete df;
3241}
3242
4388f060
A
3243void NumberFormatTest::TestRoundingPattern() {
3244 UErrorCode status = U_ZERO_ERROR;
3245 struct {
3246 UnicodeString pattern;
3247 double testCase;
3248 UnicodeString expected;
3249 } tests[] = {
3250 { (UnicodeString)"##0.65", 1.234, (UnicodeString)"1.30" },
3251 { (UnicodeString)"#50", 1230, (UnicodeString)"1250" }
3252 };
2ca993e8 3253 int32_t numOfTests = UPRV_LENGTHOF(tests);
4388f060
A
3254 UnicodeString result;
3255
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));
3259 return;
3260 }
3261
3262 for (int32_t i = 0; i < numOfTests; i++) {
3263 result.remove();
3264
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));
3268 }
3269
3270 df->format(tests[i].testCase, result);
3271
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);
3274 }
3275 }
3276
3277 delete df;
3278}
3279
46f4442e
A
3280void 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;
3286 if (iValue!=0) {
3287 smallIncrement*=iValue;
3288 }
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);
3293 }
3294}
3295
3296double NumberFormatTest::checkRound(DecimalFormat* df, double iValue, double lastParsed) {
3297 UErrorCode status=U_ZERO_ERROR;
3298 UnicodeString formattedDecimal;
3299 double parsed;
3300 Formattable result;
3301 df->format(iValue, formattedDecimal, status);
3302
3303 if (U_FAILURE(status)) {
3304 errln("Error formatting number.");
3305 }
3306
3307 df->parse(formattedDecimal, result, status);
3308
3309 if (U_FAILURE(status)) {
3310 errln("Error parsing number.");
3311 }
3312
3313 parsed=result.getDouble();
3314
3315 if (lastParsed>parsed) {
3316 errln("Rounding wrong direction! %d > %d", lastParsed, parsed);
3317 }
3318
3319 return lastParsed;
3320}
3321
3322void 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)");
729e4ab9 3328
46f4442e
A
3329 // test zero multiplier
3330
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");
3335 }
729e4ab9 3336
46f4442e 3337 // test negative multiplier
729e4ab9 3338
46f4442e
A
3339 df.setMultiplier(-1);
3340 if (df.getMultiplier() != -1) {
3341 errln("DecimalFormat.setMultiplier(-1) ignored its negative input");
3342 return;
3343 }
729e4ab9 3344
46f4442e
A
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);
3349
729e4ab9
A
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");
46f4442e 3359 expect(df, U_INT64_MAX-1, "-9223372036854775806");
729e4ab9 3360 expect(df, U_INT64_MAX, "-9223372036854775807");
46f4442e
A
3361
3362 df.setMultiplier(-2);
3363 expect(df, -(U_INT64_MIN/2)-1, "-9223372036854775806");
729e4ab9
A
3364 expect(df, -(U_INT64_MIN/2), "-9223372036854775808");
3365 expect(df, -(U_INT64_MIN/2)+1, "-9223372036854775810", FALSE);
46f4442e
A
3366
3367 df.setMultiplier(-7);
729e4ab9
A
3368 expect(df, -(U_INT64_MAX/7)-1, "9223372036854775814", FALSE);
3369 expect(df, -(U_INT64_MAX/7), "9223372036854775807");
46f4442e
A
3370 expect(df, -(U_INT64_MAX/7)+1, "9223372036854775800");
3371
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)));
3378
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());
3384}
3385
4388f060
A
3386typedef struct {
3387 const char * stringToParse;
3388 int parsedPos;
3389 int errorIndex;
3390 UBool lenient;
3391} TestSpaceParsingItem;
729e4ab9 3392
46f4442e
A
3393void
3394NumberFormatTest::TestSpaceParsing() {
3395 // the data are:
3396 // the string to be parsed, parsed position, parsed error index
4388f060 3397 const TestSpaceParsingItem DATA[] = {
4388f060
A
3398 {"$124", 4, -1, FALSE},
3399 {"$124 $124", 4, -1, FALSE},
3400 {"$124 ", 4, -1, FALSE},
3d1f044b
A
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},
4388f060
A
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},
3d1f044b
A
3413 {"124$", 4, -1, TRUE},
3414 {"124$", 4, -1, TRUE},
3415 {"124 $", 5, -1, TRUE},
3416 {"124 $", 5, -1, TRUE},
46f4442e 3417 };
46f4442e 3418 UErrorCode status = U_ZERO_ERROR;
729e4ab9 3419 Locale locale("en_US");
46f4442e 3420 NumberFormat* foo = NumberFormat::createCurrencyInstance(locale, status);
729e4ab9 3421
46f4442e
A
3422 if (U_FAILURE(status)) {
3423 delete foo;
3424 return;
3425 }
2ca993e8 3426 for (uint32_t i = 0; i < UPRV_LENGTHOF(DATA); ++i) {
46f4442e 3427 ParsePosition parsePosition(0);
4388f060
A
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);
46f4442e
A
3432 Formattable result;
3433 foo->parse(stringToBeParsed, result, parsePosition);
0f5d89e8 3434 logln("Parsing: " + stringToBeParsed);
46f4442e
A
3435 if (parsePosition.getIndex() != parsedPosition ||
3436 parsePosition.getErrorIndex() != errorIndex) {
4388f060 3437 errln("FAILED parse " + stringToBeParsed + "; lenient: " + DATA[i].lenient + "; wrong position, expected: (" + parsedPosition + ", " + errorIndex + "); got (" + parsePosition.getIndex() + ", " + parsePosition.getErrorIndex() + ")");
46f4442e
A
3438 }
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());
3443 }
3444 }
3445 delete foo;
73c04bcf 3446}
b75a7d8f 3447
729e4ab9
A
3448/**
3449 * Test using various numbering systems and numbering system keyword.
3450 */
4388f060
A
3451typedef struct {
3452 const char *localeName;
3453 double value;
3454 UBool isRBNF;
3455 const char *expectedResult;
3456} TestNumberingSystemItem;
3457
729e4ab9 3458void NumberFormatTest::TestNumberingSystems() {
729e4ab9 3459
4388f060
A
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" },
57a6839d 3464 { "ar_EG", 1234.567, FALSE, "\\u0661\\u066C\\u0662\\u0663\\u0664\\u066b\\u0665\\u0666\\u0667" },
4388f060
A
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" },
51004dcb 3473 { "zh_TW@numbers=finance", 1234.567, TRUE, "\\u58F9\\u4EDF\\u8CB3\\u4F70\\u53C3\\u62FE\\u8086\\u9EDE\\u4F0D\\u9678\\u67D2" },
4388f060
A
3474 { NULL, 0, FALSE, NULL }
3475 };
729e4ab9 3476
4388f060 3477 UErrorCode ec;
729e4ab9 3478
4388f060
A
3479 const TestNumberingSystemItem *item;
3480 for (item = DATA; item->localeName != NULL; item++) {
3481 ec = U_ZERO_ERROR;
3482 Locale loc = Locale::createFromName(item->localeName);
729e4ab9 3483
57a6839d 3484 NumberFormat *origFmt = NumberFormat::createInstance(loc,ec);
4388f060
A
3485 if (U_FAILURE(ec)) {
3486 dataerrln("FAIL: getInstance(%s) - %s", item->localeName, u_errorName(ec));
3487 continue;
3488 }
57a6839d
A
3489 // Clone to test ticket #10682
3490 NumberFormat *fmt = (NumberFormat *) origFmt->clone();
3491 delete origFmt;
3492
0f5d89e8 3493
4388f060
A
3494 if (item->isRBNF) {
3495 expect3(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
3496 } else {
3497 expect2(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
3498 }
3499 delete fmt;
729e4ab9
A
3500 }
3501
4388f060 3502
729e4ab9 3503 // Test bogus keyword value
4388f060
A
3504 ec = U_ZERO_ERROR;
3505 Locale loc4 = Locale::createFromName("en_US@numbers=foobar");
729e4ab9
A
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");
4388f060 3509 delete fmt4;
729e4ab9
A
3510 }
3511
3512 ec = U_ZERO_ERROR;
3513 NumberingSystem *ns = NumberingSystem::createInstance(ec);
3514 if (U_FAILURE(ec)) {
3515 dataerrln("FAIL: NumberingSystem::createInstance(ec); - %s", u_errorName(ec));
3516 }
3517
3518 if ( ns != NULL ) {
3519 ns->getDynamicClassID();
3520 ns->getStaticClassID();
3521 } else {
3522 errln("FAIL: getInstance() returned NULL.");
3523 }
3524
3525 NumberingSystem *ns1 = new NumberingSystem(*ns);
3526 if (ns1 == NULL) {
3527 errln("FAIL: NumberSystem copy constructor returned NULL.");
3528 }
3529
3530 delete ns1;
3531 delete ns;
4388f060 3532
729e4ab9
A
3533}
3534
3535
3536void
3537NumberFormatTest::TestMultiCurrencySign() {
3538 const char* DATA[][6] = {
3539 // the fields in the following test are:
3540 // locale,
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".
3546 // for US locale
3d1f044b
A
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"},
729e4ab9 3550 // for CHINA locale
3d1f044b
A
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"}
729e4ab9
A
3554 };
3555
3556 const UChar doubleCurrencySign[] = {0xA4, 0xA4, 0};
3557 UnicodeString doubleCurrencyStr(doubleCurrencySign);
3558 const UChar tripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
3559 UnicodeString tripleCurrencyStr(tripleCurrencySign);
3560
2ca993e8 3561 for (uint32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
729e4ab9
A
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)) {
3568 delete sym;
3569 continue;
3570 }
3571 for (int j=1; j<=3; ++j) {
3572 // j represents the number of currency sign in the pattern.
3573 if (j == 2) {
3574 pat = pat.findAndReplace(ctou("\\u00A4"), doubleCurrencyStr);
3575 } else if (j == 3) {
3576 pat = pat.findAndReplace(ctou("\\u00A4\\u00A4"), tripleCurrencyStr);
3577 }
3578
3579 DecimalFormat* fmt = new DecimalFormat(pat, new DecimalFormatSymbols(*sym), status);
3580 if (U_FAILURE(status)) {
3581 errln("FAILED init DecimalFormat ");
3582 delete fmt;
3583 continue;
3584 }
3585 UnicodeString s;
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);
3598 }
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);
3618 }
3619 }
3620 delete fmt;
3621 }
3622 delete sym;
3623 }
3624}
3625
3626
3627void
3628NumberFormatTest::TestCurrencyFormatForMixParsing() {
3629 UErrorCode status = U_ZERO_ERROR;
3630 MeasureFormat* curFmt = MeasureFormat::createCurrencyFormat(Locale("en_US"), status);
3631 if (U_FAILURE(status)) {
3632 delete curFmt;
3633 return;
3634 }
3635 const char* formats[] = {
3636 "$1,234.56", // string to be parsed
3637 "USD1,234.56",
3638 "US dollars1,234.56",
0f5d89e8 3639 // "1,234.56 US dollars" // Fails in 62 because currency format is not compatible with pattern.
729e4ab9
A
3640 };
3641 const CurrencyAmount* curramt = NULL;
2ca993e8 3642 for (uint32_t i = 0; i < UPRV_LENGTHOF(formats); ++i) {
729e4ab9
A
3643 UnicodeString stringToBeParsed = ctou(formats[i]);
3644 logln(UnicodeString("stringToBeParsed: ") + stringToBeParsed);
3645 Formattable result;
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)
3654 ) {
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());
3658 }
3659 if (curramt->getISOCurrency() != ISO_CURRENCY_USD) {
3660 errln((UnicodeString)"wong currency, expect: USD" + ", got: " + curramt->getISOCurrency());
3661 }
3662 }
3663 }
3664 delete curFmt;
3665}
3666
3667
0f5d89e8
A
3668/** Starting in ICU 62, strict mode is actually strict with currency formats. */
3669void 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",
3676 u"\u00A4#,##0.00",
3677 df->toPattern(pattern));
3678 // Should round-trip on the correct currency format:
3d1f044b 3679 expect2(*df, 1.23, u"\u00A41.23");
0f5d89e8
A
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);
3688 {
3689 Formattable result;
3690 ErrorCode failStatus;
3691 df->parse(u"1.23\u20AC", result, failStatus);
3692 assertEquals("Should fail to parse", U_INVALID_FORMAT_ERROR, failStatus);
3693 }
3694 {
3695 ParsePosition ppos;
3696 df->parseCurrency(u"1.23\u20AC", ppos);
3697 assertEquals("Should fail to parse currency", 0, ppos.getIndex());
3698 }
3699}
3700
3701
729e4ab9
A
3702void
3703NumberFormatTest::TestDecimalFormatCurrencyParse() {
3704 // Locale.US
3705 UErrorCode status = U_ZERO_ERROR;
3706 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale("en_US"), status);
3707 if (U_FAILURE(status)) {
3708 delete sym;
3709 return;
3710 }
3711 UnicodeString pat;
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)) {
3717 delete fmt;
3718 errln("failed to new DecimalFormat in TestDecimalFormatCurrencyParse");
3719 return;
3720 }
3721 const char* DATA[][2] = {
3722 // the data are:
3723 // string to be parsed, the parsed result (number)
3724 {"$1.00", "1"},
3725 {"USD1.00", "1"},
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"},
3730 };
0f5d89e8
A
3731 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3732 fmt->setLenient(TRUE);
2ca993e8 3733 for (uint32_t i = 0; i < UPRV_LENGTHOF(DATA); ++i) {
729e4ab9
A
3734 UnicodeString stringToBeParsed = ctou(DATA[i][0]);
3735 double parsedResult = atof(DATA[i][1]);
3736 UErrorCode status = U_ZERO_ERROR;
3737 Formattable result;
3738 fmt->parse(stringToBeParsed, result, status);
0f5d89e8 3739 logln((UnicodeString)"Input: " + stringToBeParsed + "; output: " + result.getDouble(status));
729e4ab9
A
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);
3746 }
3747 }
3748 delete fmt;
3749}
3750
3751
3752void
3753NumberFormatTest::TestCurrencyIsoPluralFormat() {
4388f060 3754 static const char* DATA[][6] = {
729e4ab9
A
3755 // the data are:
3756 // locale,
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,
3762
3d1f044b
A
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"},
57a6839d
A
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"},
729e4ab9
A
3773 // test locale without currency information
3774 {"root", "-1.23", "USD", "-US$\\u00A01.23", "-USD\\u00A01.23", "-1.23 USD"},
3775 // test choice format
2ca993e8 3776 {"es_AR", "1", "INR", "INR\\u00A01,00", "INR\\u00A01,00", "1,00 rupia india"},
4388f060
A
3777 };
3778 static const UNumberFormatStyle currencyStyles[] = {
3779 UNUM_CURRENCY,
3780 UNUM_CURRENCY_ISO,
3781 UNUM_CURRENCY_PLURAL
729e4ab9
A
3782 };
3783
b331163b 3784 for (int32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
0f5d89e8
A
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);
b331163b 3790 for (int32_t kIndex = 0; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) {
4388f060 3791 UNumberFormatStyle k = currencyStyles[kIndex];
0f5d89e8 3792 logln(UnicodeString(u"UNumberFormatStyle: ") + k);
729e4ab9
A
3793 UErrorCode status = U_ZERO_ERROR;
3794 NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
3795 if (U_FAILURE(status)) {
3796 delete numFmt;
3797 dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
3798 continue;
3799 }
3800 UChar currencyCode[4];
3801 u_charsToUChars(currencyISOCode, currencyCode, 4);
3802 numFmt->setCurrency(currencyCode, status);
3803 if (U_FAILURE(status)) {
3804 delete numFmt;
3805 errln((UnicodeString)"can not set currency:" + currencyISOCode);
3806 continue;
3807 }
3808
3809 UnicodeString strBuf;
3810 numFmt->format(numberToBeFormat, strBuf);
4388f060 3811 int resultDataIndex = 3 + kIndex;
729e4ab9
A
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);
3817 }
3818 // test parsing, and test parsing for all currency formats.
0f5d89e8
A
3819 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3820 numFmt->setLenient(TRUE);
729e4ab9
A
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());
3841 } else {
3842 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual: " +parseResult.getLong());
3843 }
3844 }
3845 }
3846 delete numFmt;
3847 }
3848 }
3849}
3850
3851void
3852NumberFormatTest::TestCurrencyParsing() {
4388f060 3853 static const char* DATA[][6] = {
729e4ab9
A
3854 // the data are:
3855 // locale,
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,
0f5d89e8 3861 {"en_US", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00 US dollars"},
57a6839d 3862 {"pa_IN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\u0a2f\\u0a42.\\u0a10\\u0a38. \\u0a21\\u0a3e\\u0a32\\u0a30"},
2ca993e8 3863 {"es_AR", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 d\\u00f3lar estadounidense"},
4388f060 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"},
0f5d89e8 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"},
f3c0d7a5 3866 {"he_IL", "1", "USD", "\\u200f1.00\\u00a0$", "\\u200f1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"},
0f5d89e8
A
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"},
3d1f044b
A
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"},
0f5d89e8
A
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"}
729e4ab9 3880 };
4388f060
A
3881 static const UNumberFormatStyle currencyStyles[] = {
3882 UNUM_CURRENCY,
3883 UNUM_CURRENCY_ISO,
3884 UNUM_CURRENCY_PLURAL
3885 };
57a6839d
A
3886 static const char* currencyStyleNames[] = {
3887 "UNUM_CURRENCY",
3888 "UNUM_CURRENCY_ISO",
3889 "UNUM_CURRENCY_PLURAL"
3890 };
729e4ab9
A
3891
3892#ifdef NUMFMTST_CACHE_DEBUG
3893int deadloop = 0;
3894for (;;) {
3895 printf("loop: %d\n", deadloop++);
3896#endif
2ca993e8 3897 for (uint32_t i=0; i< UPRV_LENGTHOF(DATA); ++i) { /* i = test case # - should be i=0*/
b331163b 3898 for (int32_t kIndex = 2; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) {
57a6839d 3899 UNumberFormatStyle k = currencyStyles[kIndex]; /* k = style */
729e4ab9
A
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);
57a6839d 3906 logln("#%d NumberFormat(%s, %s) Currency=%s\n",
0f5d89e8 3907 i, localeString, currencyStyleNames[kIndex],
57a6839d
A
3908 currencyISOCode);
3909
729e4ab9
A
3910 if (U_FAILURE(status)) {
3911 delete numFmt;
3912 dataerrln((UnicodeString)"can not create instance, locale:" + localeString + ", style: " + k + " - " + u_errorName(status));
3913 continue;
3914 }
729e4ab9 3915 UChar currencyCode[4];
4388f060 3916 u_charsToUChars(currencyISOCode, currencyCode, 4);
729e4ab9
A
3917 numFmt->setCurrency(currencyCode, status);
3918 if (U_FAILURE(status)) {
3919 delete numFmt;
3920 errln((UnicodeString)"can not set currency:" + currencyISOCode);
3921 continue;
3922 }
3923
729e4ab9
A
3924 UnicodeString strBuf;
3925 numFmt->format(numberToBeFormat, strBuf);
4388f060 3926 int resultDataIndex = 3 + kIndex;
729e4ab9
A
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);
3932 }
729e4ab9 3933 // test parsing, and test parsing for all currency formats.
0f5d89e8
A
3934 // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
3935 numFmt->setLenient(TRUE);
729e4ab9
A
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;
57a6839d 3946 logln("parse(%s)", DATA[i][j]);
729e4ab9
A
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)) {
57a6839d
A
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+"]");
729e4ab9 3955 if (parseResult.getType() == Formattable::kDouble) {
57a6839d 3956 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (double): " +parseResult.getDouble());
729e4ab9 3957 } else {
57a6839d 3958 errln((UnicodeString)"expected: " + numberToBeFormat + "; actual (long): " +parseResult.getLong());
729e4ab9 3959 }
57a6839d 3960 errln((UnicodeString)" round-trip would be: " + strBuf);
729e4ab9
A
3961 }
3962 }
3963 delete numFmt;
3964 }
3965 }
3966#ifdef NUMFMTST_CACHE_DEBUG
3967}
3968#endif
3969}
3970
3971
3972void
3973NumberFormatTest::TestParseCurrencyInUCurr() {
3974 const char* DATA[] = {
3975 "1.00 US DOLLAR", // case in-sensitive
3976 "$1.00",
3977 "USD1.00",
3d1f044b 3978 "usd1.00", // case in-sensitive: #13696
729e4ab9
A
3979 "US dollar1.00",
3980 "US dollars1.00",
3981 "$1.00",
51004dcb 3982 "A$1.00",
729e4ab9
A
3983 "ADP1.00",
3984 "ADP1.00",
3985 "AED1.00",
3986 "AED1.00",
3987 "AFA1.00",
3988 "AFA1.00",
3989 "AFN1.00",
3990 "ALL1.00",
3991 "AMD1.00",
3992 "ANG1.00",
3993 "AOA1.00",
3994 "AOK1.00",
3995 "AOK1.00",
3996 "AON1.00",
3997 "AON1.00",
3998 "AOR1.00",
3999 "AOR1.00",
4388f060 4000 "ARS1.00",
729e4ab9
A
4001 "ARA1.00",
4002 "ARA1.00",
4003 "ARP1.00",
4004 "ARP1.00",
4005 "ARS1.00",
4006 "ATS1.00",
4007 "ATS1.00",
4008 "AUD1.00",
4009 "AWG1.00",
4010 "AZM1.00",
4011 "AZM1.00",
4012 "AZN1.00",
57a6839d
A
4013 "Afghan Afghani (1927\\u20132002)1.00",
4014 "Afghan afghani (1927\\u20132002)1.00",
729e4ab9 4015 "Afghan Afghani1.00",
729e4ab9 4016 "Afghan Afghanis1.00",
729e4ab9
A
4017 "Albanian Lek1.00",
4018 "Albanian lek1.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",
57a6839d
A
4026 "Angolan Kwanza (1977\\u20131991)1.00",
4027 "Angolan Readjusted Kwanza (1995\\u20131999)1.00",
729e4ab9 4028 "Angolan Kwanza1.00",
57a6839d
A
4029 "Angolan New Kwanza (1990\\u20132000)1.00",
4030 "Angolan kwanza (1977\\u20131991)1.00",
4031 "Angolan readjusted kwanza (1995\\u20131999)1.00",
729e4ab9 4032 "Angolan kwanza1.00",
57a6839d
A
4033 "Angolan kwanzas (1977\\u20131991)1.00",
4034 "Angolan readjusted kwanzas (1995\\u20131999)1.00",
729e4ab9 4035 "Angolan kwanzas1.00",
57a6839d
A
4036 "Angolan new kwanza (1990\\u20132000)1.00",
4037 "Angolan new kwanzas (1990\\u20132000)1.00",
729e4ab9 4038 "Argentine Austral1.00",
57a6839d 4039 "Argentine Peso (1983\\u20131985)1.00",
729e4ab9
A
4040 "Argentine Peso1.00",
4041 "Argentine austral1.00",
4042 "Argentine australs1.00",
57a6839d 4043 "Argentine peso (1983\\u20131985)1.00",
729e4ab9 4044 "Argentine peso1.00",
57a6839d 4045 "Argentine pesos (1983\\u20131985)1.00",
729e4ab9
A
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",
57a6839d 4058 "Azerbaijani Manat (1993\\u20132006)1.00",
729e4ab9 4059 "Azerbaijani Manat1.00",
57a6839d 4060 "Azerbaijani manat (1993\\u20132006)1.00",
729e4ab9 4061 "Azerbaijani manat1.00",
57a6839d 4062 "Azerbaijani manats (1993\\u20132006)1.00",
729e4ab9 4063 "Azerbaijani manats1.00",
729e4ab9
A
4064 "BAD1.00",
4065 "BAD1.00",
4066 "BAM1.00",
4067 "BBD1.00",
729e4ab9
A
4068 "BDT1.00",
4069 "BEC1.00",
4070 "BEC1.00",
4071 "BEF1.00",
4072 "BEL1.00",
4073 "BEL1.00",
729e4ab9
A
4074 "BGL1.00",
4075 "BGN1.00",
4076 "BGN1.00",
4077 "BHD1.00",
4078 "BIF1.00",
4079 "BMD1.00",
4080 "BND1.00",
4081 "BOB1.00",
4082 "BOP1.00",
4083 "BOP1.00",
4084 "BOV1.00",
4085 "BOV1.00",
4086 "BRB1.00",
4087 "BRB1.00",
4088 "BRC1.00",
4089 "BRC1.00",
4090 "BRE1.00",
4091 "BRE1.00",
4092 "BRL1.00",
4093 "BRN1.00",
4094 "BRN1.00",
4095 "BRR1.00",
4096 "BRR1.00",
4097 "BSD1.00",
4098 "BSD1.00",
4099 "BTN1.00",
4100 "BUK1.00",
4101 "BUK1.00",
4102 "BWP1.00",
4103 "BYB1.00",
4104 "BYB1.00",
4105 "BYR1.00",
729e4ab9
A
4106 "BZD1.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",
f3c0d7a5 4119 "Belarusian Ruble (1994\\u20131999)1.00",
729e4ab9 4120 "Belarusian Ruble1.00",
f3c0d7a5
A
4121 "Belarusian ruble (1994\\u20131999)1.00",
4122 "Belarusian rubles (1994\\u20131999)1.00",
729e4ab9
A
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",
57a6839d 4153 "Bosnia-Herzegovina Dinar (1992\\u20131994)1.00",
729e4ab9
A
4154 "Bosnia-Herzegovina convertible mark1.00",
4155 "Bosnia-Herzegovina convertible marks1.00",
57a6839d
A
4156 "Bosnia-Herzegovina dinar (1992\\u20131994)1.00",
4157 "Bosnia-Herzegovina dinars (1992\\u20131994)1.00",
729e4ab9
A
4158 "Botswanan Pula1.00",
4159 "Botswanan pula1.00",
4160 "Botswanan pulas1.00",
57a6839d
A
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",
729e4ab9 4166 "Brazilian Real1.00",
57a6839d
A
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",
729e4ab9
A
4177 "Brazilian real1.00",
4178 "Brazilian reals1.00",
b331163b
A
4179 "British Pound1.00",
4180 "British pound1.00",
4181 "British pounds1.00",
729e4ab9
A
4182 "Brunei Dollar1.00",
4183 "Brunei dollar1.00",
4184 "Brunei dollars1.00",
729e4ab9
A
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",
4191 "Burmese Kyat1.00",
4192 "Burmese kyat1.00",
4193 "Burmese kyats1.00",
4194 "Burundian Franc1.00",
4195 "Burundian franc1.00",
4196 "Burundian francs1.00",
729e4ab9
A
4197 "CA$1.00",
4198 "CAD1.00",
4199 "CDF1.00",
4200 "CDF1.00",
b331163b
A
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",
729e4ab9
A
4207 "CFP Franc1.00",
4208 "CFP franc1.00",
4209 "CFP francs1.00",
4210 "CFPF1.00",
4211 "CHE1.00",
4212 "CHE1.00",
4213 "CHF1.00",
4214 "CHW1.00",
4215 "CHW1.00",
729e4ab9
A
4216 "CLF1.00",
4217 "CLF1.00",
4218 "CLP1.00",
4219 "CNY1.00",
729e4ab9
A
4220 "COP1.00",
4221 "COU1.00",
4222 "COU1.00",
4223 "CRC1.00",
4224 "CSD1.00",
4225 "CSD1.00",
4226 "CSK1.00",
4227 "CSK1.00",
4228 "CUP1.00",
4229 "CUP1.00",
4230 "CVE1.00",
4231 "CYP1.00",
4232 "CZK1.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",
4245 "Chilean Peso1.00",
4246 "Chilean Unit of Account (UF)1.00",
4247 "Chilean peso1.00",
4248 "Chilean pesos1.00",
4249 "Chilean unit of account (UF)1.00",
4250 "Chilean units of account (UF)1.00",
4251 "Chinese Yuan1.00",
4252 "Chinese yuan1.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",
4271 "Cuban Peso1.00",
4272 "Cuban peso1.00",
4273 "Cuban pesos1.00",
4274 "Cypriot Pound1.00",
4275 "Cypriot pound1.00",
4276 "Cypriot pounds1.00",
f3c0d7a5
A
4277 "Czech Koruna1.00",
4278 "Czech koruna1.00",
4279 "Czech korunas1.00",
729e4ab9
A
4280 "Czechoslovak Hard Koruna1.00",
4281 "Czechoslovak hard koruna1.00",
4282 "Czechoslovak hard korunas1.00",
729e4ab9
A
4283 "DDM1.00",
4284 "DDM1.00",
4285 "DEM1.00",
4286 "DEM1.00",
4287 "DJF1.00",
4288 "DKK1.00",
4289 "DOP1.00",
4290 "DZD1.00",
4291 "Danish Krone1.00",
4292 "Danish krone1.00",
4293 "Danish kroner1.00",
729e4ab9
A
4294 "German Mark1.00",
4295 "German mark1.00",
4296 "German marks1.00",
4297 "Djiboutian Franc1.00",
4298 "Djiboutian franc1.00",
4299 "Djiboutian francs1.00",
729e4ab9
A
4300 "Dominican Peso1.00",
4301 "Dominican peso1.00",
4302 "Dominican pesos1.00",
4303 "EC$1.00",
4304 "ECS1.00",
4305 "ECS1.00",
4306 "ECV1.00",
4307 "ECV1.00",
4308 "EEK1.00",
4309 "EEK1.00",
4310 "EGP1.00",
4311 "EGP1.00",
4312 "ERN1.00",
4313 "ERN1.00",
4314 "ESA1.00",
4315 "ESA1.00",
4316 "ESB1.00",
4317 "ESB1.00",
4318 "ESP1.00",
4319 "ETB1.00",
4320 "EUR1.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",
729e4ab9
A
4344 "Estonian Kroon1.00",
4345 "Estonian kroon1.00",
4346 "Estonian kroons1.00",
4347 "Ethiopian Birr1.00",
4348 "Ethiopian birr1.00",
4349 "Ethiopian birrs1.00",
4350 "Euro1.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",
729e4ab9
A
4366 "FIM1.00",
4367 "FIM1.00",
4368 "FJD1.00",
4369 "FKP1.00",
4370 "FKP1.00",
4371 "FRF1.00",
4372 "FRF1.00",
4373 "Falkland Islands Pound1.00",
4374 "Falkland Islands pound1.00",
4375 "Falkland Islands pounds1.00",
729e4ab9
A
4376 "Fijian Dollar1.00",
4377 "Fijian dollar1.00",
4378 "Fijian dollars1.00",
4379 "Finnish Markka1.00",
4380 "Finnish markka1.00",
4381 "Finnish markkas1.00",
4382 "CHF1.00",
4383 "French Franc1.00",
4384 "French Gold Franc1.00",
4385 "French UIC-Franc1.00",
4386 "French UIC-franc1.00",
4387 "French UIC-francs1.00",
4388 "French franc1.00",
4389 "French francs1.00",
4390 "French gold franc1.00",
4391 "French gold francs1.00",
729e4ab9
A
4392 "GBP1.00",
4393 "GEK1.00",
4394 "GEK1.00",
4395 "GEL1.00",
729e4ab9
A
4396 "GHC1.00",
4397 "GHC1.00",
4398 "GHS1.00",
4399 "GIP1.00",
4400 "GIP1.00",
4401 "GMD1.00",
4402 "GMD1.00",
4403 "GNF1.00",
4404 "GNS1.00",
4405 "GNS1.00",
4406 "GQE1.00",
4407 "GQE1.00",
4408 "GRD1.00",
4409 "GRD1.00",
4410 "GTQ1.00",
4411 "GWE1.00",
4412 "GWE1.00",
4413 "GWP1.00",
4414 "GWP1.00",
4415 "GYD1.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",
57a6839d 4425 "Ghanaian Cedi (1979\\u20132007)1.00",
729e4ab9 4426 "Ghanaian Cedi1.00",
57a6839d 4427 "Ghanaian cedi (1979\\u20132007)1.00",
729e4ab9 4428 "Ghanaian cedi1.00",
57a6839d 4429 "Ghanaian cedis (1979\\u20132007)1.00",
729e4ab9
A
4430 "Ghanaian cedis1.00",
4431 "Gibraltar Pound1.00",
4432 "Gibraltar pound1.00",
4433 "Gibraltar pounds1.00",
4434 "Gold1.00",
4435 "Gold1.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",
4443 "Guinean Syli1.00",
4444 "Guinean franc1.00",
4445 "Guinean francs1.00",
4446 "Guinean syli1.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",
4454 "HK$1.00",
4455 "HKD1.00",
4456 "HNL1.00",
4457 "HRD1.00",
4458 "HRD1.00",
4459 "HRK1.00",
4460 "HRK1.00",
4461 "HTG1.00",
4462 "HTG1.00",
4463 "HUF1.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",
4476 "IDR1.00",
4477 "IEP1.00",
4478 "ILP1.00",
4479 "ILP1.00",
4480 "ILS1.00",
4481 "INR1.00",
4482 "IQD1.00",
4483 "IRR1.00",
729e4ab9
A
4484 "ISK1.00",
4485 "ISK1.00",
4486 "ITL1.00",
4487 "Icelandic Kr\\u00f3na1.00",
4488 "Icelandic kr\\u00f3na1.00",
4489 "Icelandic kr\\u00f3nur1.00",
4490 "Indian Rupee1.00",
4491 "Indian rupee1.00",
4492 "Indian rupees1.00",
4493 "Indonesian Rupiah1.00",
4494 "Indonesian rupiah1.00",
4495 "Indonesian rupiahs1.00",
4496 "Iranian Rial1.00",
4497 "Iranian rial1.00",
4498 "Iranian rials1.00",
4499 "Iraqi Dinar1.00",
4500 "Iraqi dinar1.00",
4501 "Iraqi dinars1.00",
4502 "Irish Pound1.00",
4503 "Irish pound1.00",
4504 "Irish pounds1.00",
4505 "Israeli Pound1.00",
f3c0d7a5 4506 "Israeli new shekel1.00",
729e4ab9
A
4507 "Israeli pound1.00",
4508 "Israeli pounds1.00",
4509 "Italian Lira1.00",
4510 "Italian lira1.00",
4511 "Italian liras1.00",
729e4ab9
A
4512 "JMD1.00",
4513 "JOD1.00",
4514 "JPY1.00",
4515 "Jamaican Dollar1.00",
4516 "Jamaican dollar1.00",
4517 "Jamaican dollars1.00",
4518 "Japanese Yen1.00",
4519 "Japanese yen1.00",
4520 "Jordanian Dinar1.00",
4521 "Jordanian dinar1.00",
4522 "Jordanian dinars1.00",
729e4ab9
A
4523 "KES1.00",
4524 "KGS1.00",
4525 "KHR1.00",
4526 "KMF1.00",
4527 "KPW1.00",
4528 "KPW1.00",
4529 "KRW1.00",
4530 "KWD1.00",
4531 "KYD1.00",
4532 "KYD1.00",
4533 "KZT1.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",
729e4ab9
A
4546 "HNL1.00",
4547 "LAK1.00",
4548 "LAK1.00",
4549 "LBP1.00",
729e4ab9 4550 "LKR1.00",
729e4ab9
A
4551 "LRD1.00",
4552 "LRD1.00",
4553 "LSL1.00",
4554 "LTL1.00",
4555 "LTL1.00",
4556 "LTT1.00",
4557 "LTT1.00",
4558 "LUC1.00",
4559 "LUC1.00",
4560 "LUF1.00",
4561 "LUF1.00",
4562 "LUL1.00",
4563 "LUL1.00",
4564 "LVL1.00",
4565 "LVL1.00",
4566 "LVR1.00",
4567 "LVR1.00",
4568 "LYD1.00",
4569 "Laotian Kip1.00",
4570 "Laotian kip1.00",
4571 "Laotian kips1.00",
4572 "Latvian Lats1.00",
4573 "Latvian Ruble1.00",
4574 "Latvian lats1.00",
4575 "Latvian lati1.00",
4576 "Latvian ruble1.00",
4577 "Latvian rubles1.00",
4578 "Lebanese Pound1.00",
4579 "Lebanese pound1.00",
4580 "Lebanese pounds1.00",
4581 "Lesotho Loti1.00",
4582 "Lesotho loti1.00",
4583 "Lesotho lotis1.00",
4584 "Liberian Dollar1.00",
4585 "Liberian dollar1.00",
4586 "Liberian dollars1.00",
4587 "Libyan Dinar1.00",
4588 "Libyan dinar1.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",
729e4ab9
A
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",
4605 "MAD1.00",
4606 "MAD1.00",
4607 "MAF1.00",
4608 "MAF1.00",
4609 "MDL1.00",
4610 "MDL1.00",
4611 "MX$1.00",
4612 "MGA1.00",
4613 "MGA1.00",
4614 "MGF1.00",
4615 "MGF1.00",
4616 "MKD1.00",
4617 "MLF1.00",
4618 "MLF1.00",
4619 "MMK1.00",
4620 "MMK1.00",
4621 "MNT1.00",
4622 "MOP1.00",
4623 "MOP1.00",
4624 "MRO1.00",
4625 "MTL1.00",
4626 "MTP1.00",
4627 "MTP1.00",
729e4ab9
A
4628 "MUR1.00",
4629 "MUR1.00",
4630 "MVR1.00",
4631 "MVR1.00",
4632 "MWK1.00",
4633 "MXN1.00",
4634 "MXP1.00",
4635 "MXP1.00",
4636 "MXV1.00",
4637 "MXV1.00",
4638 "MYR1.00",
4639 "MZE1.00",
4640 "MZE1.00",
4641 "MZM1.00",
4642 "MZN1.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",
4664 "Malian Franc1.00",
4665 "Malian franc1.00",
4666 "Malian francs1.00",
4667 "Maltese Lira1.00",
4668 "Maltese Pound1.00",
4669 "Maltese lira1.00",
4670 "Maltese lira1.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",
4679 "Mexican Peso1.00",
57a6839d 4680 "Mexican Silver Peso (1861\\u20131992)1.00",
729e4ab9
A
4681 "Mexican Investment Unit1.00",
4682 "Mexican peso1.00",
4683 "Mexican pesos1.00",
57a6839d
A
4684 "Mexican silver peso (1861\\u20131992)1.00",
4685 "Mexican silver pesos (1861\\u20131992)1.00",
729e4ab9
A
4686 "Mexican investment unit1.00",
4687 "Mexican investment units1.00",
4688 "Moldovan Leu1.00",
4689 "Moldovan leu1.00",
4690 "Moldovan lei1.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",
57a6839d
A
4706 "Myanmar Kyat1.00",
4707 "Myanmar kyat1.00",
4708 "Myanmar kyats1.00",
729e4ab9 4709 "NAD1.00",
729e4ab9
A
4710 "NGN1.00",
4711 "NIC1.00",
4712 "NIO1.00",
4713 "NIO1.00",
729e4ab9
A
4714 "NLG1.00",
4715 "NLG1.00",
4716 "NOK1.00",
4717 "NPR1.00",
4718 "NT$1.00",
4719 "NZ$1.00",
4720 "NZD1.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",
f3c0d7a5
A
4733 "Israeli New Shekel1.00",
4734 "Israeli New Shekels1.00",
729e4ab9
A
4735 "New Zealand Dollar1.00",
4736 "New Zealand dollar1.00",
4737 "New Zealand dollars1.00",
4738 "Nicaraguan C\\u00f3rdoba1.00",
57a6839d 4739 "Nicaraguan C\\u00f3rdoba (1988\\u20131991)1.00",
729e4ab9
A
4740 "Nicaraguan c\\u00f3rdoba1.00",
4741 "Nicaraguan c\\u00f3rdobas1.00",
57a6839d
A
4742 "Nicaraguan c\\u00f3rdoba (1988\\u20131991)1.00",
4743 "Nicaraguan c\\u00f3rdobas (1988\\u20131991)1.00",
729e4ab9
A
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",
729e4ab9 4753 "OMR1.00",
57a6839d
A
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",
729e4ab9
A
4771 "Omani Rial1.00",
4772 "Omani rial1.00",
4773 "Omani rials1.00",
4774 "PAB1.00",
4775 "PAB1.00",
4776 "PEI1.00",
4777 "PEI1.00",
4778 "PEN1.00",
4779 "PEN1.00",
4780 "PES1.00",
4781 "PES1.00",
4782 "PGK1.00",
4783 "PGK1.00",
4784 "PHP1.00",
4785 "PKR1.00",
4786 "PLN1.00",
4787 "PLZ1.00",
4788 "PLZ1.00",
4789 "PTE1.00",
4790 "PTE1.00",
4791 "PYG1.00",
4792 "Pakistani Rupee1.00",
4793 "Pakistani rupee1.00",
4794 "Pakistani rupees1.00",
4795 "Palladium1.00",
4796 "Palladium1.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",
f3c0d7a5 4807 "Peruvian Sol1.00",
57a6839d 4808 "Peruvian Sol (1863\\u20131965)1.00",
729e4ab9
A
4809 "Peruvian inti1.00",
4810 "Peruvian intis1.00",
f3c0d7a5
A
4811 "Peruvian sol1.00",
4812 "Peruvian soles1.00",
57a6839d
A
4813 "Peruvian sol (1863\\u20131965)1.00",
4814 "Peruvian soles (1863\\u20131965)1.00",
0f5d89e8
A
4815 "Philippine Piso1.00",
4816 "Philippine piso1.00",
4817 "Philippine pisos1.00",
729e4ab9
A
4818 "Platinum1.00",
4819 "Platinum1.00",
57a6839d 4820 "Polish Zloty (1950\\u20131995)1.00",
729e4ab9
A
4821 "Polish Zloty1.00",
4822 "Polish zlotys1.00",
4823 "Polish zloty (PLZ)1.00",
4824 "Polish zloty1.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",
729e4ab9
A
4832 "GTQ1.00",
4833 "QAR1.00",
729e4ab9
A
4834 "Qatari Rial1.00",
4835 "Qatari rial1.00",
4836 "Qatari rials1.00",
729e4ab9
A
4837 "RHD1.00",
4838 "RHD1.00",
4839 "RINET Funds1.00",
4840 "RINET Funds1.00",
729e4ab9
A
4841 "CN\\u00a51.00",
4842 "ROL1.00",
4843 "ROL1.00",
4844 "RON1.00",
4845 "RON1.00",
4846 "RSD1.00",
4847 "RSD1.00",
4848 "RUB1.00",
729e4ab9
A
4849 "RUR1.00",
4850 "RUR1.00",
4851 "RWF1.00",
4852 "RWF1.00",
4853 "Rhodesian Dollar1.00",
4854 "Rhodesian dollar1.00",
4855 "Rhodesian dollars1.00",
4856 "Romanian Leu1.00",
4857 "Romanian lei1.00",
4858 "Romanian leu1.00",
57a6839d 4859 "Russian Ruble (1991\\u20131998)1.00",
729e4ab9 4860 "Russian Ruble1.00",
57a6839d 4861 "Russian ruble (1991\\u20131998)1.00",
729e4ab9 4862 "Russian ruble1.00",
57a6839d 4863 "Russian rubles (1991\\u20131998)1.00",
729e4ab9
A
4864 "Russian rubles1.00",
4865 "Rwandan Franc1.00",
4866 "Rwandan franc1.00",
4867 "Rwandan francs1.00",
729e4ab9
A
4868 "SAR1.00",
4869 "SBD1.00",
4870 "SCR1.00",
4871 "SDD1.00",
4872 "SDD1.00",
4873 "SDG1.00",
4874 "SDG1.00",
4875 "SDP1.00",
4876 "SDP1.00",
4877 "SEK1.00",
4878 "SGD1.00",
4879 "SHP1.00",
4880 "SHP1.00",
729e4ab9
A
4881 "SIT1.00",
4882 "SIT1.00",
4883 "SKK1.00",
729e4ab9
A
4884 "SLL1.00",
4885 "SLL1.00",
4886 "SOS1.00",
4887 "SRD1.00",
4888 "SRD1.00",
4889 "SRG1.00",
729e4ab9
A
4890 "STD1.00",
4891 "SUR1.00",
4892 "SUR1.00",
4893 "SVC1.00",
4894 "SVC1.00",
4895 "SYP1.00",
4896 "SZL1.00",
b331163b
A
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",
729e4ab9
A
4903 "Saudi Riyal1.00",
4904 "Saudi riyal1.00",
4905 "Saudi riyals1.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",
729e4ab9
A
4912 "Sierra Leonean Leone1.00",
4913 "Sierra Leonean leone1.00",
4914 "Sierra Leonean leones1.00",
4915 "Silver1.00",
4916 "Silver1.00",
4917 "Singapore Dollar1.00",
4918 "Singapore dollar1.00",
4919 "Singapore dollars1.00",
729e4ab9
A
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",
4972 "Swiss Franc1.00",
4973 "Swiss franc1.00",
4974 "Swiss francs1.00",
4975 "Syrian Pound1.00",
4976 "Syrian pound1.00",
4977 "Syrian pounds1.00",
729e4ab9
A
4978 "THB1.00",
4979 "TJR1.00",
4980 "TJR1.00",
4981 "TJS1.00",
4982 "TJS1.00",
729e4ab9
A
4983 "TMM1.00",
4984 "TMM1.00",
4985 "TND1.00",
4986 "TND1.00",
4987 "TOP1.00",
4988 "TPE1.00",
4989 "TPE1.00",
4990 "TRL1.00",
4991 "TRY1.00",
4992 "TRY1.00",
729e4ab9
A
4993 "TTD1.00",
4994 "TWD1.00",
4995 "TZS1.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",
5010 "Thai Baht1.00",
5011 "Thai baht1.00",
5012 "Thai baht1.00",
5013 "Timorese Escudo1.00",
5014 "Timorese escudo1.00",
5015 "Timorese escudos1.00",
729e4ab9
A
5016 "Tongan Pa\\u02bbanga1.00",
5017 "Tongan pa\\u02bbanga1.00",
5018 "Tongan pa\\u02bbanga1.00",
b331163b
A
5019 "Trinidad & Tobago Dollar1.00",
5020 "Trinidad & Tobago dollar1.00",
5021 "Trinidad & Tobago dollars1.00",
729e4ab9
A
5022 "Tunisian Dinar1.00",
5023 "Tunisian dinar1.00",
5024 "Tunisian dinars1.00",
5025 "Turkish Lira1.00",
5026 "Turkish Lira1.00",
5027 "Turkish lira1.00",
5028 "Turkmenistani Manat1.00",
5029 "Turkmenistani manat1.00",
5030 "Turkmenistani manat1.00",
729e4ab9
A
5031 "UAE dirham1.00",
5032 "UAE dirhams1.00",
5033 "UAH1.00",
5034 "UAK1.00",
5035 "UAK1.00",
5036 "UGS1.00",
5037 "UGS1.00",
5038 "UGX1.00",
729e4ab9
A
5039 "US Dollar (Next day)1.00",
5040 "US Dollar (Same day)1.00",
5041 "US Dollar1.00",
5042 "US dollar (next day)1.00",
5043 "US dollar (same day)1.00",
5044 "US dollar1.00",
5045 "US dollars (next day)1.00",
5046 "US dollars (same day)1.00",
5047 "US dollars1.00",
5048 "USD1.00",
5049 "USN1.00",
5050 "USN1.00",
5051 "USS1.00",
5052 "USS1.00",
5053 "UYI1.00",
5054 "UYI1.00",
5055 "UYP1.00",
5056 "UYP1.00",
5057 "UYU1.00",
5058 "UZS1.00",
5059 "UZS1.00",
57a6839d 5060 "Ugandan Shilling (1966\\u20131987)1.00",
729e4ab9 5061 "Ugandan Shilling1.00",
57a6839d 5062 "Ugandan shilling (1966\\u20131987)1.00",
729e4ab9 5063 "Ugandan shilling1.00",
57a6839d 5064 "Ugandan shillings (1966\\u20131987)1.00",
729e4ab9
A
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",
57a6839d 5075 "Uruguayan Peso (1975\\u20131993)1.00",
729e4ab9
A
5076 "Uruguayan Peso1.00",
5077 "Uruguayan Peso (Indexed Units)1.00",
57a6839d 5078 "Uruguayan peso (1975\\u20131993)1.00",
729e4ab9
A
5079 "Uruguayan peso (indexed units)1.00",
5080 "Uruguayan peso1.00",
57a6839d 5081 "Uruguayan pesos (1975\\u20131993)1.00",
729e4ab9
A
5082 "Uruguayan pesos (indexed units)1.00",
5083 "Uruguayan pesos1.00",
b331163b
A
5084 "Uzbekistani Som1.00",
5085 "Uzbekistani som1.00",
5086 "Uzbekistani som1.00",
729e4ab9
A
5087 "VEB1.00",
5088 "VEF1.00",
5089 "VND1.00",
729e4ab9
A
5090 "VUV1.00",
5091 "Vanuatu Vatu1.00",
5092 "Vanuatu vatu1.00",
5093 "Vanuatu vatus1.00",
5094 "Venezuelan Bol\\u00edvar1.00",
57a6839d 5095 "Venezuelan Bol\\u00edvar (1871\\u20132008)1.00",
729e4ab9
A
5096 "Venezuelan bol\\u00edvar1.00",
5097 "Venezuelan bol\\u00edvars1.00",
57a6839d
A
5098 "Venezuelan bol\\u00edvar (1871\\u20132008)1.00",
5099 "Venezuelan bol\\u00edvars (1871\\u20132008)1.00",
729e4ab9
A
5100 "Vietnamese Dong1.00",
5101 "Vietnamese dong1.00",
5102 "Vietnamese dong1.00",
5103 "WIR Euro1.00",
5104 "WIR Franc1.00",
5105 "WIR euro1.00",
5106 "WIR euros1.00",
5107 "WIR franc1.00",
5108 "WIR francs1.00",
5109 "WST1.00",
5110 "WST1.00",
5111 "Samoan Tala1.00",
5112 "Samoan tala1.00",
5113 "Samoan tala1.00",
5114 "XAF1.00",
5115 "XAF1.00",
5116 "XAG1.00",
5117 "XAG1.00",
5118 "XAU1.00",
5119 "XAU1.00",
5120 "XBA1.00",
5121 "XBA1.00",
5122 "XBB1.00",
5123 "XBB1.00",
5124 "XBC1.00",
5125 "XBC1.00",
5126 "XBD1.00",
5127 "XBD1.00",
5128 "XCD1.00",
5129 "XDR1.00",
5130 "XDR1.00",
5131 "XEU1.00",
5132 "XEU1.00",
5133 "XFO1.00",
5134 "XFO1.00",
5135 "XFU1.00",
5136 "XFU1.00",
5137 "XOF1.00",
5138 "XOF1.00",
5139 "XPD1.00",
5140 "XPD1.00",
5141 "XPF1.00",
5142 "XPT1.00",
5143 "XPT1.00",
5144 "XRE1.00",
5145 "XRE1.00",
5146 "XTS1.00",
5147 "XTS1.00",
5148 "XXX1.00",
5149 "XXX1.00",
5150 "YDD1.00",
5151 "YDD1.00",
5152 "YER1.00",
5153 "YUD1.00",
5154 "YUD1.00",
5155 "YUM1.00",
5156 "YUM1.00",
5157 "YUN1.00",
5158 "YUN1.00",
5159 "Yemeni Dinar1.00",
5160 "Yemeni Rial1.00",
5161 "Yemeni dinar1.00",
5162 "Yemeni dinars1.00",
5163 "Yemeni rial1.00",
5164 "Yemeni rials1.00",
57a6839d
A
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",
729e4ab9
A
5174 "ZAL1.00",
5175 "ZAL1.00",
5176 "ZAR1.00",
5177 "ZMK1.00",
5178 "ZMK1.00",
5179 "ZRN1.00",
5180 "ZRN1.00",
5181 "ZRZ1.00",
5182 "ZRZ1.00",
5183 "ZWD1.00",
57a6839d
A
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",
729e4ab9
A
5190 "Zambian Kwacha1.00",
5191 "Zambian kwacha1.00",
5192 "Zambian kwachas1.00",
57a6839d
A
5193 "Zimbabwean Dollar (1980\\u20132008)1.00",
5194 "Zimbabwean dollar (1980\\u20132008)1.00",
5195 "Zimbabwean dollars (1980\\u20132008)1.00",
729e4ab9
A
5196 "euro1.00",
5197 "euros1.00",
57a6839d 5198 "Turkish lira (1922\\u20132005)1.00",
729e4ab9
A
5199 "special drawing rights1.00",
5200 "Colombian real value unit1.00",
5201 "Colombian real value units1.00",
4388f060 5202 "unknown currency1.00",
729e4ab9 5203 "\\u00a31.00",
729e4ab9 5204 "\\u00a51.00",
729e4ab9 5205 "\\u20ab1.00",
729e4ab9
A
5206 "\\u20aa1.00",
5207 "\\u20ac1.00",
5208 "\\u20b91.00",
729e4ab9
A
5209 //
5210 // Following has extra text, should be parsed correctly too
5211 "$1.00 random",
5212 "USD1.00 random",
5213 "1.00 US dollar random",
5214 "1.00 US dollars random",
5215 "1.00 Afghan Afghani random",
5216 "1.00 Afghan Afghani random",
57a6839d 5217 "1.00 Afghan Afghanis (1927\\u20131992) random",
729e4ab9
A
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",
57a6839d
A
5228 "1.00 Angolan Kwanza (1977\\u20131990) random",
5229 "1.00 Angolan Readjusted Kwanza (1995\\u20131999) random",
729e4ab9 5230 "1.00 Angolan Kwanza random",
57a6839d
A
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",
729e4ab9 5234 "1.00 Angolan kwanza random",
57a6839d
A
5235 "1.00 Angolan kwanzas (1977\\u20131991) random",
5236 "1.00 Angolan readjusted kwanzas (1995\\u20131999) random",
729e4ab9 5237 "1.00 Angolan kwanzas random",
57a6839d
A
5238 "1.00 Angolan new kwanza (1990\\u20132000) random",
5239 "1.00 Angolan new kwanzas (1990\\u20132000) random",
729e4ab9 5240 "1.00 Argentine Austral random",
57a6839d 5241 "1.00 Argentine Peso (1983\\u20131985) random",
729e4ab9
A
5242 "1.00 Argentine Peso random",
5243 "1.00 Argentine austral random",
5244 "1.00 Argentine australs random",
57a6839d 5245 "1.00 Argentine peso (1983\\u20131985) random",
729e4ab9 5246 "1.00 Argentine peso random",
57a6839d 5247 "1.00 Argentine pesos (1983\\u20131985) random",
729e4ab9
A
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",
57a6839d 5260 "1.00 Azerbaijani Manat (1993\\u20132006) random",
729e4ab9 5261 "1.00 Azerbaijani Manat random",
57a6839d 5262 "1.00 Azerbaijani manat (1993\\u20132006) random",
729e4ab9 5263 "1.00 Azerbaijani manat random",
57a6839d 5264 "1.00 Azerbaijani manats (1993\\u20132006) random",
729e4ab9
A
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",
f3c0d7a5 5278 "1.00 Belarusian Ruble (1994\\u20131999) random",
729e4ab9 5279 "1.00 Belarusian Ruble random",
f3c0d7a5
A
5280 "1.00 Belarusian ruble (1994\\u20131999) random",
5281 "1.00 Belarusian rubles (1994\\u20131999) random",
729e4ab9
A
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",
57a6839d 5312 "1.00 Bosnia-Herzegovina Dinar (1992\\u20131994) random",
729e4ab9
A
5313 "1.00 Bosnia-Herzegovina convertible mark random",
5314 "1.00 Bosnia-Herzegovina convertible marks random",
57a6839d
A
5315 "1.00 Bosnia-Herzegovina dinar (1992\\u20131994) random",
5316 "1.00 Bosnia-Herzegovina dinars (1992\\u20131994) random",
729e4ab9
A
5317 "1.00 Botswanan Pula random",
5318 "1.00 Botswanan pula random",
5319 "1.00 Botswanan pulas random",
57a6839d
A
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",
729e4ab9 5325 "1.00 Brazilian Real random",
57a6839d
A
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",
729e4ab9
A
5336 "1.00 Brazilian real random",
5337 "1.00 Brazilian reals random",
b331163b
A
5338 "1.00 British Pound random",
5339 "1.00 British pound random",
5340 "1.00 British pounds random",
729e4ab9
A
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",
f3c0d7a5
A
5400 "1.00 Czech Koruna random",
5401 "1.00 Czech koruna random",
5402 "1.00 Czech korunas random",
729e4ab9
A
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",
57a6839d 5489 "1.00 Ghanaian Cedi (1979\\u20132007) random",
729e4ab9 5490 "1.00 Ghanaian Cedi random",
57a6839d 5491 "1.00 Ghanaian cedi (1979\\u20132007) random",
729e4ab9 5492 "1.00 Ghanaian cedi random",
57a6839d 5493 "1.00 Ghanaian cedis (1979\\u20132007) random",
729e4ab9
A
5494 "1.00 Ghanaian cedis random",
5495 "1.00 Gibraltar Pound random",
5496 "1.00 Gibraltar pound random",
5497 "1.00 Gibraltar pounds random",
5498 "1.00 Gold random",
5499 "1.00 Gold 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",
f3c0d7a5 5549 "1.00 Israeli new shekel random",
729e4ab9
A
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",
57a6839d 5648 "1.00 Mexican Silver Peso (1861\\u20131992) random",
729e4ab9
A
5649 "1.00 Mexican Investment Unit random",
5650 "1.00 Mexican peso random",
5651 "1.00 Mexican pesos random",
57a6839d
A
5652 "1.00 Mexican silver peso (1861\\u20131992) random",
5653 "1.00 Mexican silver pesos (1861\\u20131992) random",
729e4ab9
A
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",
57a6839d
A
5674 "1.00 Myanmar Kyat random",
5675 "1.00 Myanmar kyat random",
5676 "1.00 Myanmar kyats random",
729e4ab9
A
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",
f3c0d7a5
A
5689 "1.00 Israeli New Shekel random",
5690 "1.00 Israeli new shekels random",
729e4ab9
A
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",
57a6839d 5695 "1.00 Nicaraguan C\\u00f3rdoba (1988\\u20131991) random",
729e4ab9
A
5696 "1.00 Nicaraguan c\\u00f3rdoba random",
5697 "1.00 Nicaraguan c\\u00f3rdoba random",
57a6839d
A
5698 "1.00 Nicaraguan c\\u00f3rdoba (1988\\u20131991) random",
5699 "1.00 Nicaraguan c\\u00f3rdobas (1988\\u20131991) random",
729e4ab9
A
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",
57a6839d
A
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",
729e4ab9
A
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",
f3c0d7a5 5744 "1.00 Peruvian Sol random",
57a6839d 5745 "1.00 Peruvian Sol (1863\\u20131965) random",
729e4ab9
A
5746 "1.00 Peruvian inti random",
5747 "1.00 Peruvian intis random",
f3c0d7a5
A
5748 "1.00 Peruvian sol random",
5749 "1.00 Peruvian soles random",
57a6839d
A
5750 "1.00 Peruvian sol (1863\\u20131965) random",
5751 "1.00 Peruvian soles (1863\\u20131965) random",
0f5d89e8
A
5752 "1.00 Philippine Piso random",
5753 "1.00 Philippine piso random",
5754 "1.00 Philippine pisos random",
729e4ab9
A
5755 "1.00 Platinum random",
5756 "1.00 Platinum random",
57a6839d 5757 "1.00 Polish Zloty (1950\\u20131995) random",
729e4ab9
A
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",
57a6839d 5780 "1.00 Russian Ruble (1991\\u20131998) random",
729e4ab9 5781 "1.00 Russian Ruble random",
57a6839d 5782 "1.00 Russian ruble (1991\\u20131998) random",
729e4ab9 5783 "1.00 Russian ruble random",
57a6839d 5784 "1.00 Russian rubles (1991\\u20131998) random",
729e4ab9
A
5785 "1.00 Russian rubles random",
5786 "1.00 Rwandan Franc random",
5787 "1.00 Rwandan franc random",
5788 "1.00 Rwandan francs random",
b331163b
A
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",
729e4ab9
A
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",
b331163b
A
5888 "1.00 Trinidad & Tobago Dollar random",
5889 "1.00 Trinidad & Tobago dollar random",
5890 "1.00 Trinidad & Tobago dollars random",
729e4ab9
A
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",
57a6839d 5909 "1.00 Ugandan Shilling (1966\\u20131987) random",
729e4ab9 5910 "1.00 Ugandan Shilling random",
57a6839d 5911 "1.00 Ugandan shilling (1966\\u20131987) random",
729e4ab9 5912 "1.00 Ugandan shilling random",
57a6839d 5913 "1.00 Ugandan shillings (1966\\u20131987) random",
729e4ab9
A
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",
57a6839d 5924 "1.00 Uruguayan Peso (1975\\u20131993) random",
729e4ab9
A
5925 "1.00 Uruguayan Peso random",
5926 "1.00 Uruguayan Peso (Indexed Units) random",
57a6839d 5927 "1.00 Uruguayan peso (1975\\u20131993) random",
729e4ab9
A
5928 "1.00 Uruguayan peso (indexed units) random",
5929 "1.00 Uruguayan peso random",
57a6839d 5930 "1.00 Uruguayan pesos (1975\\u20131993) random",
729e4ab9 5931 "1.00 Uruguayan pesos (indexed units) random",
b331163b
A
5932 "1.00 Uzbekistani Som random",
5933 "1.00 Uzbekistani som random",
5934 "1.00 Uzbekistani som random",
729e4ab9
A
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",
57a6839d 5939 "1.00 Venezuelan Bol\\u00edvar (1871\\u20132008) random",
729e4ab9
A
5940 "1.00 Venezuelan bol\\u00edvar random",
5941 "1.00 Venezuelan bol\\u00edvars random",
57a6839d
A
5942 "1.00 Venezuelan bol\\u00edvar (1871\\u20132008) random",
5943 "1.00 Venezuelan bol\\u00edvars (1871\\u20132008) random",
729e4ab9
A
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",
57a6839d
A
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",
729e4ab9
A
5977 "1.00 Zambian Kwacha random",
5978 "1.00 Zambian kwacha random",
5979 "1.00 Zambian kwachas random",
57a6839d
A
5980 "1.00 Zimbabwean Dollar (1980\\u20132008) random",
5981 "1.00 Zimbabwean dollar (1980\\u20132008) random",
5982 "1.00 Zimbabwean dollars (1980\\u20132008) random",
729e4ab9
A
5983 "1.00 euro random",
5984 "1.00 euros random",
57a6839d 5985 "1.00 Turkish lira (1922\\u20132005) random",
729e4ab9
A
5986 "1.00 special drawing rights random",
5987 "1.00 Colombian real value unit random",
5988 "1.00 Colombian real value units random",
4388f060 5989 "1.00 unknown currency random",
729e4ab9
A
5990 };
5991
5992 const char* WRONG_DATA[] = {
5993 // Following are missing one last char in the currency name
729e4ab9
A
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",
6013 "1.00 US dolla",
6014 "1.00",
6015 "A1.00",
6016 "AD1.00",
6017 "AE1.00",
6018 "AF1.00",
6019 "AL1.00",
6020 "AM1.00",
6021 "AN1.00",
6022 "AO1.00",
6023 "AR1.00",
6024 "AT1.00",
6025 "AU1.00",
6026 "AW1.00",
6027 "AZ1.00",
6028 "Afghan Afghan1.00",
57a6839d 6029 "Afghan Afghani (1927\\u201320021.00",
729e4ab9
A
6030 "Afl1.00",
6031 "Albanian Le1.00",
6032 "Algerian Dina1.00",
6033 "Andorran Peset1.00",
6034 "Angolan Kwanz1.00",
57a6839d
A
6035 "Angolan Kwanza (1977\\u201319901.00",
6036 "Angolan Readjusted Kwanza (1995\\u201319991.00",
6037 "Angolan New Kwanza (1990\\u201320001.00",
729e4ab9
A
6038 "Argentine Austra1.00",
6039 "Argentine Pes1.00",
57a6839d 6040 "Argentine Peso (1983\\u201319851.00",
729e4ab9
A
6041 "Armenian Dra1.00",
6042 "Aruban Flori1.00",
6043 "Australian Dolla1.00",
6044 "Austrian Schillin1.00",
6045 "Azerbaijani Mana1.00",
57a6839d 6046 "Azerbaijani Manat (1993\\u201320061.00",
729e4ab9
A
6047 "B1.00",
6048 "BA1.00",
6049 "BB1.00",
6050 "BE1.00",
6051 "BG1.00",
6052 "BH1.00",
6053 "BI1.00",
6054 "BM1.00",
6055 "BN1.00",
6056 "BO1.00",
6057 "BR1.00",
6058 "BS1.00",
6059 "BT1.00",
6060 "BU1.00",
6061 "BW1.00",
6062 "BY1.00",
6063 "BZ1.00",
6064 "Bahamian Dolla1.00",
6065 "Bahraini Dina1.00",
6066 "Bangladeshi Tak1.00",
6067 "Barbadian Dolla1.00",
6068 "Bds1.00",
f3c0d7a5 6069 "Belarusian Ruble (1994\\u201319991.00",
729e4ab9
A
6070 "Belarusian Rubl1.00",
6071 "Belgian Fran1.00",
6072 "Belgian Franc (convertible1.00",
6073 "Belgian Franc (financial1.00",
6074 "Belize Dolla1.00",
6075 "Bermudan Dolla1.00",
6076 "Bhutanese Ngultru1.00",
6077 "Bolivian Mvdo1.00",
6078 "Bolivian Pes1.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",
57a6839d
A
6086 "Brazilian Cruzeiro (1990\\u201319931.00",
6087 "Brazilian New Cruzeiro (1967\\u201319861.00",
729e4ab9
A
6088 "Brazilian Rea1.00",
6089 "British Pound Sterlin1.00",
6090 "Brunei Dolla1.00",
6091 "Bulgarian Hard Le1.00",
6092 "Bulgarian Le1.00",
6093 "Burmese Kya1.00",
6094 "Burundian Fran1.00",
6095 "C1.00",
6096 "CA1.00",
6097 "CD1.00",
729e4ab9
A
6098 "CFP Fran1.00",
6099 "CFP1.00",
6100 "CH1.00",
6101 "CL1.00",
6102 "CN1.00",
6103 "CO1.00",
6104 "CS1.00",
6105 "CU1.00",
6106 "CV1.00",
6107 "CY1.00",
6108 "CZ1.00",
6109 "Cambodian Rie1.00",
6110 "Canadian Dolla1.00",
6111 "Cape Verdean Escud1.00",
6112 "Cayman Islands Dolla1.00",
6113 "Chilean Pes1.00",
6114 "Chilean Unit of Accoun1.00",
6115 "Chinese Yua1.00",
6116 "Colombian Pes1.00",
6117 "Comoro Fran1.00",
6118 "Congolese Fran1.00",
6119 "Costa Rican Col\\u00f31.00",
6120 "Croatian Dina1.00",
6121 "Croatian Kun1.00",
6122 "Cuban Pes1.00",
6123 "Cypriot Poun1.00",
6124 "Czech Republic Korun1.00",
6125 "Czechoslovak Hard Korun1.00",
6126 "D1.00",
6127 "DD1.00",
6128 "DE1.00",
6129 "DJ1.00",
6130 "DK1.00",
6131 "DO1.00",
6132 "DZ1.00",
6133 "Danish Kron1.00",
6134 "German Mar1.00",
6135 "Djiboutian Fran1.00",
6136 "Dk1.00",
6137 "Dominican Pes1.00",
6138 "EC1.00",
6139 "EE1.00",
6140 "EG1.00",
6141 "EQ1.00",
6142 "ER1.00",
6143 "ES1.00",
6144 "ET1.00",
6145 "EU1.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",
6151 "Ekwel1.00",
6152 "Salvadoran Col\\u00f31.00",
6153 "Equatorial Guinean Ekwel1.00",
6154 "Eritrean Nakf1.00",
6155 "Es1.00",
6156 "Estonian Kroo1.00",
6157 "Ethiopian Bir1.00",
6158 "Eur1.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",
6164 "F1.00",
6165 "FB1.00",
6166 "FI1.00",
6167 "FJ1.00",
6168 "FK1.00",
6169 "FR1.00",
6170 "Falkland Islands Poun1.00",
6171 "Fd1.00",
6172 "Fijian Dolla1.00",
6173 "Finnish Markk1.00",
6174 "Fr1.00",
6175 "French Fran1.00",
6176 "French Gold Fran1.00",
6177 "French UIC-Fran1.00",
6178 "G1.00",
6179 "GB1.00",
6180 "GE1.00",
6181 "GH1.00",
6182 "GI1.00",
6183 "GM1.00",
6184 "GN1.00",
6185 "GQ1.00",
6186 "GR1.00",
6187 "GT1.00",
6188 "GW1.00",
6189 "GY1.00",
6190 "Gambian Dalas1.00",
6191 "Georgian Kupon Lari1.00",
6192 "Georgian Lar1.00",
6193 "Ghanaian Ced1.00",
57a6839d 6194 "Ghanaian Cedi (1979\\u201320071.00",
729e4ab9
A
6195 "Gibraltar Poun1.00",
6196 "Gol1.00",
6197 "Greek Drachm1.00",
6198 "Guatemalan Quetza1.00",
6199 "Guinean Fran1.00",
6200 "Guinean Syl1.00",
6201 "Guinea-Bissau Pes1.00",
6202 "Guyanaese Dolla1.00",
6203 "HK1.00",
6204 "HN1.00",
6205 "HR1.00",
6206 "HT1.00",
6207 "HU1.00",
6208 "Haitian Gourd1.00",
6209 "Honduran Lempir1.00",
6210 "Hong Kong Dolla1.00",
6211 "Hungarian Forin1.00",
6212 "I1.00",
6213 "IE1.00",
6214 "IL1.00",
6215 "IN1.00",
6216 "IQ1.00",
6217 "IR1.00",
6218 "IS1.00",
6219 "IT1.00",
6220 "Icelandic Kron1.00",
6221 "Indian Rupe1.00",
6222 "Indonesian Rupia1.00",
6223 "Iranian Ria1.00",
6224 "Iraqi Dina1.00",
6225 "Irish Poun1.00",
6226 "Israeli Poun1.00",
6227 "Italian Lir1.00",
6228 "J1.00",
6229 "JM1.00",
6230 "JO1.00",
6231 "JP1.00",
6232 "Jamaican Dolla1.00",
6233 "Japanese Ye1.00",
6234 "Jordanian Dina1.00",
6235 "K S1.00",
6236 "K1.00",
6237 "KE1.00",
6238 "KG1.00",
6239 "KH1.00",
6240 "KP1.00",
6241 "KR1.00",
6242 "KW1.00",
6243 "KY1.00",
6244 "KZ1.00",
6245 "Kazakhstani Teng1.00",
6246 "Kenyan Shillin1.00",
6247 "Kuwaiti Dina1.00",
6248 "Kyrgystani So1.00",
6249 "LA1.00",
6250 "LB1.00",
6251 "LK1.00",
6252 "LR1.00",
6253 "LT1.00",
6254 "LU1.00",
6255 "LV1.00",
6256 "LY1.00",
6257 "Laotian Ki1.00",
6258 "Latvian Lat1.00",
6259 "Latvian Rubl1.00",
6260 "Lebanese Poun1.00",
6261 "Lesotho Lot1.00",
6262 "Liberian Dolla1.00",
6263 "Libyan Dina1.00",
6264 "Lithuanian Lit1.00",
6265 "Lithuanian Talona1.00",
6266 "Luxembourgian Convertible Fran1.00",
6267 "Luxembourg Financial Fran1.00",
6268 "Luxembourgian Fran1.00",
6269 "MA1.00",
6270 "MD1.00",
6271 "MDe1.00",
6272 "MEX1.00",
6273 "MG1.00",
6274 "ML1.00",
6275 "MM1.00",
6276 "MN1.00",
6277 "MO1.00",
6278 "MR1.00",
6279 "MT1.00",
6280 "MU1.00",
6281 "MV1.00",
6282 "MW1.00",
6283 "MX1.00",
6284 "MY1.00",
6285 "MZ1.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",
6293 "Malian Fran1.00",
6294 "Malot1.00",
6295 "Maltese Lir1.00",
6296 "Maltese Poun1.00",
6297 "Mauritanian Ouguiy1.00",
6298 "Mauritian Rupe1.00",
6299 "Mexican Pes1.00",
57a6839d 6300 "Mexican Silver Peso (1861\\u201319921.00",
729e4ab9
A
6301 "Mexican Investment Uni1.00",
6302 "Moldovan Le1.00",
6303 "Mongolian Tugri1.00",
6304 "Moroccan Dirha1.00",
6305 "Moroccan Fran1.00",
6306 "Mozambican Escud1.00",
6307 "Mozambican Metica1.00",
57a6839d 6308 "Myanmar Kya1.00",
729e4ab9
A
6309 "N1.00",
6310 "NA1.00",
6311 "NAf1.00",
6312 "NG1.00",
6313 "NI1.00",
6314 "NK1.00",
6315 "NL1.00",
6316 "NO1.00",
6317 "NP1.00",
6318 "NT1.00",
6319 "Namibian Dolla1.00",
6320 "Nepalese Rupe1.00",
6321 "Netherlands Antillean Guilde1.00",
6322 "Dutch Guilde1.00",
6323 "Israeli New Sheqe1.00",
6324 "New Zealand Dolla1.00",
57a6839d 6325 "Nicaraguan C\\u00f3rdoba (1988\\u201319911.00",
729e4ab9
A
6326 "Nicaraguan C\\u00f3rdob1.00",
6327 "Nigerian Nair1.00",
6328 "North Korean Wo1.00",
6329 "Norwegian Kron1.00",
6330 "Nr1.00",
6331 "OM1.00",
6332 "Old Mozambican Metica1.00",
57a6839d
A
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",
729e4ab9
A
6338 "Omani Ria1.00",
6339 "PA1.00",
6340 "PE1.00",
6341 "PG1.00",
6342 "PH1.00",
6343 "PK1.00",
6344 "PL1.00",
6345 "PT1.00",
6346 "PY1.00",
6347 "Pakistani Rupe1.00",
6348 "Palladiu1.00",
6349 "Panamanian Balbo1.00",
6350 "Papua New Guinean Kin1.00",
6351 "Paraguayan Guaran1.00",
6352 "Peruvian Int1.00",
57a6839d 6353 "Peruvian Sol (1863\\u201319651.00",
729e4ab9
A
6354 "Peruvian Sol Nuev1.00",
6355 "Philippine Pes1.00",
6356 "Platinu1.00",
6357 "Polish Zlot1.00",
57a6839d 6358 "Polish Zloty (1950\\u201319951.00",
729e4ab9
A
6359 "Portuguese Escud1.00",
6360 "Portuguese Guinea Escud1.00",
6361 "Pr1.00",
6362 "QA1.00",
6363 "Qatari Ria1.00",
6364 "RD1.00",
6365 "RH1.00",
6366 "RINET Fund1.00",
6367 "RS1.00",
6368 "RU1.00",
6369 "RW1.00",
6370 "Rb1.00",
6371 "Rhodesian Dolla1.00",
6372 "Romanian Le1.00",
6373 "Russian Rubl1.00",
57a6839d 6374 "Russian Ruble (1991\\u201319981.00",
729e4ab9
A
6375 "Rwandan Fran1.00",
6376 "S1.00",
6377 "SA1.00",
6378 "SB1.00",
6379 "SC1.00",
6380 "SD1.00",
6381 "SE1.00",
6382 "SG1.00",
6383 "SH1.00",
6384 "SI1.00",
6385 "SK1.00",
6386 "SL R1.00",
6387 "SL1.00",
6388 "SO1.00",
6389 "ST1.00",
6390 "SU1.00",
6391 "SV1.00",
6392 "SY1.00",
6393 "SZ1.00",
b331163b
A
6394 "St. Helena Poun1.00",
6395 "S\\u00e3o Tom\\u00e9 & Pr\\u00edncipe Dobr1.00",
729e4ab9
A
6396 "Saudi Riya1.00",
6397 "Serbian Dina1.00",
6398 "Seychellois Rupe1.00",
6399 "Sh1.00",
6400 "Sierra Leonean Leon1.00",
6401 "Silve1.00",
6402 "Singapore Dolla1.00",
6403 "Slovak Korun1.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",
6410 "Soviet Roubl1.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",
6420 "Swedish Kron1.00",
6421 "Swiss Fran1.00",
6422 "Syrian Poun1.00",
6423 "T S1.00",
6424 "TH1.00",
6425 "TJ1.00",
6426 "TM1.00",
6427 "TN1.00",
6428 "TO1.00",
6429 "TP1.00",
6430 "TR1.00",
6431 "TT1.00",
6432 "TW1.00",
6433 "TZ1.00",
6434 "New Taiwan Dolla1.00",
6435 "Tajikistani Rubl1.00",
6436 "Tajikistani Somon1.00",
6437 "Tanzanian Shillin1.00",
6438 "Testing Currency Cod1.00",
6439 "Thai Bah1.00",
6440 "Timorese Escud1.00",
6441 "Tongan Pa\\u20bbang1.00",
b331163b 6442 "Trinidad & Tobago Dolla1.00",
729e4ab9
A
6443 "Tunisian Dina1.00",
6444 "Turkish Lir1.00",
6445 "Turkmenistani Mana1.00",
6446 "U S1.00",
6447 "U1.00",
6448 "UA1.00",
6449 "UG1.00",
6450 "US Dolla1.00",
6451 "US Dollar (Next day1.00",
6452 "US Dollar (Same day1.00",
6453 "US1.00",
6454 "UY1.00",
6455 "UZ1.00",
6456 "Ugandan Shillin1.00",
57a6839d 6457 "Ugandan Shilling (1966\\u201319871.00",
729e4ab9
A
6458 "Ukrainian Hryvni1.00",
6459 "Ukrainian Karbovanet1.00",
6460 "Colombian Real Value Uni1.00",
6461 "United Arab Emirates Dirha1.00",
6462 "Unknown Currenc1.00",
6463 "Ur1.00",
57a6839d 6464 "Uruguay Peso (1975\\u201319931.00",
729e4ab9
A
6465 "Uruguay Peso Uruguay1.00",
6466 "Uruguay Peso (Indexed Units1.00",
b331163b 6467 "Uzbekistani So1.00",
729e4ab9
A
6468 "V1.00",
6469 "VE1.00",
6470 "VN1.00",
6471 "VU1.00",
6472 "Vanuatu Vat1.00",
6473 "Venezuelan Bol\\u00edva1.00",
6474 "Venezuelan Bol\\u00edvar Fuert1.00",
6475 "Vietnamese Don1.00",
b331163b
A
6476 "West African CFA Fran1.00",
6477 "Central African CFA Fran1.00",
729e4ab9
A
6478 "WIR Eur1.00",
6479 "WIR Fran1.00",
6480 "WS1.00",
6481 "Samoa Tal1.00",
6482 "XA1.00",
6483 "XB1.00",
6484 "XC1.00",
6485 "XD1.00",
6486 "XE1.00",
6487 "XF1.00",
6488 "XO1.00",
6489 "XP1.00",
6490 "XR1.00",
6491 "XT1.00",
6492 "XX1.00",
6493 "YD1.00",
6494 "YE1.00",
6495 "YU1.00",
6496 "Yemeni Dina1.00",
6497 "Yemeni Ria1.00",
6498 "Yugoslavian Convertible Dina1.00",
57a6839d 6499 "Yugoslavian Hard Dinar (1966\\u201319901.00",
729e4ab9
A
6500 "Yugoslavian New Dina1.00",
6501 "Z1.00",
6502 "ZA1.00",
6503 "ZM1.00",
6504 "ZR1.00",
6505 "ZW1.00",
57a6839d 6506 "Zairean New Zaire (1993\\u201319981.00",
729e4ab9
A
6507 "Zairean Zair1.00",
6508 "Zambian Kwach1.00",
57a6839d 6509 "Zimbabwean Dollar (1980\\u201320081.00",
729e4ab9
A
6510 "dra1.00",
6511 "lar1.00",
6512 "le1.00",
6513 "man1.00",
6514 "so1.00",
6515 };
6516
6517 Locale locale("en_US");
2ca993e8 6518 for (uint32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
0f5d89e8
A
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__)) {
6523 return;
6524 }
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);
6533 }
6534 } else {
6535 errln("Failed to parse as currency: " + formatted);
6536 }
729e4ab9
A
6537 }
6538
2ca993e8 6539 for (uint32_t i=0; i<UPRV_LENGTHOF(WRONG_DATA); ++i) {
729e4ab9
A
6540 UnicodeString formatted = ctou(WRONG_DATA[i]);
6541 UErrorCode status = U_ZERO_ERROR;
4388f060 6542 NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
729e4ab9 6543 if (numFmt != NULL && U_SUCCESS(status)) {
4388f060
A
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);
729e4ab9
A
6549 }
6550 } else {
6551 dataerrln("Unable to create NumberFormat. - %s", u_errorName(status));
6552 delete numFmt;
6553 break;
6554 }
6555 delete numFmt;
6556 }
6557}
6558
6559const char* attrString(int32_t);
6560
6561// UnicodeString s;
6562// std::string ss;
6563// std::cout << s.toUTF8String(ss)
6564void NumberFormatTest::expectPositions(FieldPositionIterator& iter, int32_t *values, int32_t tupleCount,
6565 const UnicodeString& str) {
6566 UBool found[10];
6567 FieldPosition fp;
6568
6569 if (tupleCount > 10) {
6570 assertTrue("internal error, tupleCount too large", FALSE);
6571 } else {
6572 for (int i = 0; i < tupleCount; ++i) {
6573 found[i] = FALSE;
6574 }
6575 }
6576
6577 logln(str);
6578 while (iter.next(fp)) {
6579 UBool ok = FALSE;
6580 int32_t id = fp.getField();
6581 int32_t start = fp.getBeginIndex();
6582 int32_t limit = fp.getEndIndex();
6583
6584 // is there a logln using printf?
6585 char buf[128];
6586 sprintf(buf, "%24s %3d %3d %3d", attrString(id), id, start, limit);
6587 logln(buf);
6588
6589 for (int i = 0; i < tupleCount; ++i) {
6590 if (found[i]) {
6591 continue;
6592 }
6593 if (values[i*3] == id &&
6594 values[i*3+1] == start &&
6595 values[i*3+2] == limit) {
6596 found[i] = ok = TRUE;
6597 break;
6598 }
6599 }
6600
6601 assertTrue((UnicodeString)"found [" + id + "," + start + "," + limit + "]", ok);
6602 }
6603
6604 // check that all were found
6605 UBool ok = TRUE;
6606 for (int i = 0; i < tupleCount; ++i) {
6607 if (!found[i]) {
6608 ok = FALSE;
6609 assertTrue((UnicodeString) "missing [" + values[i*3] + "," + values[i*3+1] + "," + values[i*3+2] + "]", found[i]);
6610 }
6611 }
6612 assertTrue("no expected values were missing", ok);
6613}
6614
6615void NumberFormatTest::expectPosition(FieldPosition& pos, int32_t id, int32_t start, int32_t limit,
6616 const UnicodeString& str) {
6617 logln(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());
6621}
6622
6623void NumberFormatTest::TestFieldPositionIterator() {
6624 // bug 7372
6625 UErrorCode status = U_ZERO_ERROR;
6626 FieldPositionIterator iter1;
6627 FieldPositionIterator iter2;
6628 FieldPosition pos;
6629
6630 DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(status);
6631 if (failure(status, "NumberFormat::createInstance", TRUE)) return;
6632
6633 double num = 1234.56;
6634 UnicodeString str1;
6635 UnicodeString str2;
6636
6637 assertTrue((UnicodeString)"self==", iter1 == iter1);
6638 assertTrue((UnicodeString)"iter1==iter2", iter1 == iter2);
6639
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);
6644 iter1.next(pos);
6645 assertTrue((UnicodeString)"iter1 != iter2 (2)", iter1 != iter2);
6646 iter2.next(pos);
6647 assertTrue((UnicodeString)"iter1 == iter2 (3)", iter1 == iter2);
6648
6649 // should format ok with no iterator
6650 str2.remove();
6651 decFmt->format(num, str2, NULL, status);
6652 assertEquals("null fpiter", str1, str2);
6653
6654 delete decFmt;
6655}
6656
6657void NumberFormatTest::TestFormatAttributes() {
6658 Locale locale("en_US");
6659 UErrorCode status = U_ZERO_ERROR;
4388f060 6660 DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
729e4ab9
A
6661 if (failure(status, "NumberFormat::createInstance", TRUE)) return;
6662 double val = 12345.67;
0f5d89e8 6663
729e4ab9
A
6664 {
6665 int32_t expected[] = {
4388f060
A
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,
729e4ab9 6671 };
2ca993e8 6672 int32_t tupleCount = UPRV_LENGTHOF(expected)/3;
729e4ab9
A
6673
6674 FieldPositionIterator posIter;
6675 UnicodeString result;
6676 decFmt->format(val, result, &posIter, status);
6677 expectPositions(posIter, expected, tupleCount, result);
6678 }
6679 {
4388f060 6680 FieldPosition fp(UNUM_INTEGER_FIELD);
729e4ab9
A
6681 UnicodeString result;
6682 decFmt->format(val, result, fp);
4388f060 6683 expectPosition(fp, UNUM_INTEGER_FIELD, 1, 7, result);
729e4ab9
A
6684 }
6685 {
4388f060 6686 FieldPosition fp(UNUM_FRACTION_FIELD);
729e4ab9
A
6687 UnicodeString result;
6688 decFmt->format(val, result, fp);
4388f060 6689 expectPosition(fp, UNUM_FRACTION_FIELD, 8, 10, result);
729e4ab9
A
6690 }
6691 delete decFmt;
6692
4388f060 6693 decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_SCIENTIFIC, status);
729e4ab9
A
6694 val = -0.0000123;
6695 {
6696 int32_t expected[] = {
4388f060
A
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
729e4ab9 6704 };
2ca993e8 6705 int32_t tupleCount = UPRV_LENGTHOF(expected)/3;
729e4ab9
A
6706
6707 FieldPositionIterator posIter;
6708 UnicodeString result;
6709 decFmt->format(val, result, &posIter, status);
6710 expectPositions(posIter, expected, tupleCount, result);
6711 }
6712 {
4388f060 6713 FieldPosition fp(UNUM_INTEGER_FIELD);
729e4ab9
A
6714 UnicodeString result;
6715 decFmt->format(val, result, fp);
4388f060 6716 expectPosition(fp, UNUM_INTEGER_FIELD, 1, 2, result);
729e4ab9
A
6717 }
6718 {
4388f060 6719 FieldPosition fp(UNUM_FRACTION_FIELD);
729e4ab9
A
6720 UnicodeString result;
6721 decFmt->format(val, result, fp);
4388f060 6722 expectPosition(fp, UNUM_FRACTION_FIELD, 3, 5, result);
729e4ab9
A
6723 }
6724 delete decFmt;
6725
6726 fflush(stderr);
6727}
6728
6729const char* attrString(int32_t attrId) {
6730 switch (attrId) {
4388f060
A
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";
729e4ab9
A
6742 default: return "";
6743 }
6744}
6745
6746//
6747// Test formatting & parsing of big decimals.
0f5d89e8 6748// API test, not a comprehensive test.
729e4ab9
A
6749// See DecimalFormatTest/DataDrivenTests
6750//
0f5d89e8
A
6751#define ASSERT_SUCCESS(status) { \
6752 assertSuccess(UnicodeString("file ") + __FILE__ + ", line " + __LINE__, (status)); \
6753}
6754#define ASSERT_EQUALS(expected, actual) { \
6755 assertEquals(UnicodeString("file ") + __FILE__ + ", line " + __LINE__, (expected), (actual)); \
729e4ab9
A
6756}
6757
6758void NumberFormatTest::TestDecimal() {
6759 {
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);
0f5d89e8 6765 ASSERT_EQUALS("1.2345678999987654321E+667", s.data());
729e4ab9
A
6766 //printf("%s\n", s.data());
6767 }
6768
6769 {
6770 UErrorCode status = U_ZERO_ERROR;
6771 Formattable f1("this is not a number", status);
6772 ASSERT_EQUALS(U_DECIMAL_NUMBER_SYNTAX_ERROR, status);
6773 }
6774
6775 {
6776 UErrorCode status = U_ZERO_ERROR;
6777 Formattable f;
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);
0f5d89e8 6784 ASSERT_EQUALS("123.45", f.getDecimalNumber(status).data());
729e4ab9
A
6785 ASSERT_SUCCESS(status);
6786
6787 f.setDecimalNumber("4.5678E7", status);
6788 int32_t n;
6789 n = f.getLong();
6790 ASSERT_EQUALS(45678000, n);
6791
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);
0f5d89e8 6799 ASSERT_EQUALS("-123", f.getDecimalNumber(status).data());
729e4ab9
A
6800 ASSERT_SUCCESS(status);
6801
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);
0f5d89e8 6809 ASSERT_EQUALS("1234567890123", f.getDecimalNumber(status).data());
729e4ab9
A
6810 ASSERT_SUCCESS(status);
6811 }
6812
6813 {
6814 UErrorCode status = U_ZERO_ERROR;
4388f060 6815 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
729e4ab9
A
6816 if (U_FAILURE(status) || fmtr == NULL) {
6817 dataerrln("Unable to create NumberFormat");
6818 } else {
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);
6825 delete fmtr;
6826 }
6827 }
6828
6829 {
6830 // Check formatting a DigitList. DigitList is internal, but this is
6831 // a critical interface that must work.
6832 UErrorCode status = U_ZERO_ERROR;
4388f060 6833 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
729e4ab9
A
6834 if (U_FAILURE(status) || fmtr == NULL) {
6835 dataerrln("Unable to create NumberFormat");
6836 } else {
6837 UnicodeString formattedResult;
3d1f044b 6838 DecimalQuantity dl;
729e4ab9 6839 StringPiece num("123.4566666666666666666666666666666666621E+40");
3d1f044b 6840 dl.setToDecNumber(num, status);
729e4ab9
A
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);
6845
6846 status = U_ZERO_ERROR;
6847 num.set("666.666");
3d1f044b 6848 dl.setToDecNumber(num, status);
729e4ab9
A
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());
6857 delete fmtr;
6858 }
6859 }
6860
6861 {
6862 // Check a parse with a formatter with a multiplier.
6863 UErrorCode status = U_ZERO_ERROR;
4388f060 6864 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_PERCENT, status);
729e4ab9
A
6865 if (U_FAILURE(status) || fmtr == NULL) {
6866 dataerrln("Unable to create NumberFormat");
6867 } else {
6868 UnicodeString input = "1.84%";
6869 Formattable result;
6870 fmtr->parse(input, result, status);
6871 ASSERT_SUCCESS(status);
0f5d89e8 6872 ASSERT_EQUALS("0.0184", result.getDecimalNumber(status).data());
729e4ab9
A
6873 //std::cout << result.getDecimalNumber(status).data();
6874 delete fmtr;
6875 }
6876 }
0f5d89e8 6877
51004dcb
A
6878#if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC)
6879 /*
6880 * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod().
6881 * See #9463
6882 */
729e4ab9
A
6883 {
6884 // Check that a parse returns a decimal number with full accuracy
6885 UErrorCode status = U_ZERO_ERROR;
4388f060 6886 NumberFormat *fmtr = NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, status);
729e4ab9
A
6887 if (U_FAILURE(status) || fmtr == NULL) {
6888 dataerrln("Unable to create NumberFormat");
6889 } else {
6890 UnicodeString input = "1.002200044400088880000070000";
6891 Formattable result;
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();
6897 delete fmtr;
6898 }
6899 }
51004dcb 6900#endif
729e4ab9
A
6901
6902}
6903
6904void NumberFormatTest::TestCurrencyFractionDigits() {
6905 UErrorCode status = U_ZERO_ERROR;
6906 UnicodeString text1, text2;
6907 double value = 99.12345;
6908
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");
6913 } else {
6914 fmt->format(value, text1);
6915
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);
6920
6921 if (text1 != text2) {
6922 errln((UnicodeString)"NumberFormat::format() should return the same result - text1="
6923 + text1 + " text2=" + text2);
6924 }
729e4ab9 6925 }
0f5d89e8 6926 delete fmt;
729e4ab9
A
6927}
6928
0f5d89e8
A
6929void NumberFormatTest::TestExponentParse() {
6930
6931 UErrorCode status = U_ZERO_ERROR;
6932 Formattable result;
6933 ParsePosition parsePos(0);
6934
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)");
6940 return;
6941 }
6942
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*)");
6948 }
6949
6950 // parse the text
6951 fmt.parse("5.06e-27", result, parsePos);
6952 if(result.getType() != Formattable::kDouble &&
6953 result.getDouble() != 5.06E-27 &&
6954 parsePos.getIndex() != 8
6955 )
6956 {
6957 errln("ERROR: parse failed - expected 5.06E-27, 8 - returned %d, %i",
6958 result.getDouble(), parsePos.getIndex());
6959 }
6960}
729e4ab9 6961
4388f060
A
6962void NumberFormatTest::TestExplicitParents() {
6963
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 */
3d1f044b
A
6968 {"es_CO", "1250,75" },
6969 {"es_ES", "1250,75" },
6970 {"es_GQ", "1250,75" },
1a147d09 6971 {"es_MX", "1,250.75" },
3d1f044b
A
6972 {"es_US", "1250.75" },
6973 {"es_VE", "1250,75" },
4388f060
A
6974 };
6975
6976 UnicodeString s;
6977
2ca993e8 6978 for(int i=0; i < UPRV_LENGTHOF(parentLocaleTests); i++){
4388f060
A
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();
6983 char loc[256]={0};
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));
6988 continue;
6989 }
6990 s.remove();
6991 fmt->format(1250.75, s);
6992 if(s!=expected){
6993 errln(UnicodeString("FAIL: Expected: ")+expected
6994 + UnicodeString(" Got: ") + s
6995 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
6996 }
6997 if (U_FAILURE(status)){
6998 errln((UnicodeString)"FAIL: Status " + (int32_t)status);
6999 }
7000 delete fmt;
7001 }
7002
7003}
7004
7005/**
7006 * Test available numbering systems API.
7007 */
7008void NumberFormatTest::TestAvailableNumberingSystems() {
3d1f044b 7009 IcuTestErrorCode status(*this, "TestAvailableNumberingSystems");
4388f060
A
7010 StringEnumeration *availableNumberingSystems = NumberingSystem::getAvailableNames(status);
7011 CHECK_DATA(status, "NumberingSystem::getAvailableNames()")
7012
7013 int32_t nsCount = availableNumberingSystems->count(status);
2ca993e8
A
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);
4388f060
A
7016 }
7017
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. */
7022
7023 int32_t len;
3d1f044b 7024 const char* prevName = nullptr;
4388f060
A
7025 for ( int32_t i = 0 ; i < nsCount ; i++ ) {
7026 const char *nsname = availableNumberingSystems->next(&len,status);
7027 NumberingSystem* ns = NumberingSystem::createInstanceByName(nsname,status);
2ca993e8 7028 logln("OK for ns = %s",nsname);
4388f060
A
7029 if ( uprv_strcmp(nsname,ns->getName()) ) {
7030 errln("FAIL: Numbering system name didn't match for name = %s\n",nsname);
7031 }
3d1f044b
A
7032 if (prevName != nullptr) {
7033 int comp = uprv_strcmp(prevName, nsname);
7034 assertTrue(
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
7038 comp <= 0);
7039 }
7040 prevName = nsname;
4388f060
A
7041
7042 delete ns;
7043 }
7044
3d1f044b
A
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());
7048
4388f060
A
7049 delete availableNumberingSystems;
7050}
7051
7052void
7053NumberFormatTest::Test9087(void)
7054{
7055 U_STRING_DECL(pattern,"#",1);
7056 U_STRING_INIT(pattern,"#",1);
0f5d89e8 7057
4388f060
A
7058 U_STRING_DECL(infstr,"INF",3);
7059 U_STRING_INIT(infstr,"INF",3);
7060
7061 U_STRING_DECL(nanstr,"NAN",3);
7062 U_STRING_INIT(nanstr,"NAN",3);
0f5d89e8 7063
4388f060
A
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));
7069 return;
7070 }
7071
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");
7076 }
7077
7078 double inf = uprv_getInfinity();
7079
7080 unum_setAttribute(fmt,UNUM_ROUNDING_MODE,UNUM_ROUND_HALFEVEN);
7081 unum_setDoubleAttribute(fmt,UNUM_ROUNDING_INCREMENT,0);
7082
7083 UFieldPosition position = { 0, 0, 0};
7084 unum_formatDouble(fmt,inf,outputbuf,50,&position,&status);
0f5d89e8 7085
4388f060
A
7086 if ( u_strcmp(infstr, outputbuf)) {
7087 errln((UnicodeString)"FAIL: unexpected result for infinity - expected " + infstr + " got " + outputbuf);
7088 }
7089
7090 unum_close(fmt);
7091}
51004dcb 7092
51004dcb 7093void NumberFormatTest::TestFormatFastpaths() {
51004dcb
A
7094 // get some additional case
7095 {
7096 UErrorCode status=U_ZERO_ERROR;
0f5d89e8 7097 DecimalFormat df(UnicodeString(u"0000"),status);
2ca993e8
A
7098 if (U_FAILURE(status)) {
7099 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
51004dcb 7100 } else {
2ca993e8
A
7101 int64_t long_number = 1;
7102 UnicodeString expect = "0001";
7103 UnicodeString result;
7104 FieldPosition pos;
7105 df.format(long_number, result, pos);
7106 if(U_FAILURE(status)||expect!=result) {
0f5d89e8
A
7107 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s",
7108 __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
7109 } else {
2ca993e8
A
7110 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),""));
7111 }
51004dcb
A
7112 }
7113 }
7114 {
7115 UErrorCode status=U_ZERO_ERROR;
0f5d89e8 7116 DecimalFormat df(UnicodeString(u"0000000000000000000"),status);
2ca993e8
A
7117 if (U_FAILURE(status)) {
7118 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
51004dcb 7119 } else {
2ca993e8
A
7120 int64_t long_number = U_INT64_MIN; // -9223372036854775808L;
7121 // uint8_t bits[8];
7122 // memcpy(bits,&long_number,8);
7123 // for(int i=0;i<8;i++) {
7124 // logln("bits: %02X", (unsigned int)bits[i]);
7125 // }
7126 UnicodeString expect = "-9223372036854775808";
7127 UnicodeString result;
7128 FieldPosition pos;
7129 df.format(long_number, result, pos);
7130 if(U_FAILURE(status)||expect!=result) {
0f5d89e8
A
7131 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on -9223372036854775808",
7132 __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
2ca993e8
A
7133 } else {
7134 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
7135 }
51004dcb
A
7136 }
7137 }
7138 {
7139 UErrorCode status=U_ZERO_ERROR;
0f5d89e8 7140 DecimalFormat df(UnicodeString(u"0000000000000000000"),status);
2ca993e8
A
7141 if (U_FAILURE(status)) {
7142 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
51004dcb 7143 } else {
2ca993e8
A
7144 int64_t long_number = U_INT64_MAX; // -9223372036854775808L;
7145 // uint8_t bits[8];
7146 // memcpy(bits,&long_number,8);
7147 // for(int i=0;i<8;i++) {
7148 // logln("bits: %02X", (unsigned int)bits[i]);
7149 // }
7150 UnicodeString expect = "9223372036854775807";
7151 UnicodeString result;
7152 FieldPosition pos;
7153 df.format(long_number, result, pos);
7154 if(U_FAILURE(status)||expect!=result) {
0f5d89e8
A
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));
2ca993e8
A
7157 } else {
7158 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
7159 }
51004dcb
A
7160 }
7161 }
7162 {
7163 UErrorCode status=U_ZERO_ERROR;
7164 DecimalFormat df(UnicodeString("0000000000000000000",""),status);
2ca993e8
A
7165 if (U_FAILURE(status)) {
7166 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
51004dcb 7167 } else {
2ca993e8
A
7168 int64_t long_number = 0;
7169 // uint8_t bits[8];
7170 // memcpy(bits,&long_number,8);
7171 // for(int i=0;i<8;i++) {
7172 // logln("bits: %02X", (unsigned int)bits[i]);
7173 // }
7174 UnicodeString expect = "0000000000000000000";
7175 UnicodeString result;
7176 FieldPosition pos;
7177 df.format(long_number, result, pos);
7178 if(U_FAILURE(status)||expect!=result) {
0f5d89e8
A
7179 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on 0",
7180 __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
2ca993e8
A
7181 } else {
7182 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
7183 }
51004dcb
A
7184 }
7185 }
7186 {
7187 UErrorCode status=U_ZERO_ERROR;
7188 DecimalFormat df(UnicodeString("0000000000000000000",""),status);
2ca993e8
A
7189 if (U_FAILURE(status)) {
7190 dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
51004dcb 7191 } else {
2ca993e8
A
7192 int64_t long_number = U_INT64_MIN + 1;
7193 UnicodeString expect = "-9223372036854775807";
7194 UnicodeString result;
7195 FieldPosition pos;
7196 df.format(long_number, result, pos);
7197 if(U_FAILURE(status)||expect!=result) {
0f5d89e8
A
7198 dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on -9223372036854775807",
7199 __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
2ca993e8
A
7200 } else {
7201 logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
7202 }
51004dcb
A
7203 }
7204 }
7205}
7206
7207
3d1f044b
A
7208void 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);
51004dcb 7215 } else {
0f5d89e8
A
7216 logln("sizeof(Formattable)=%d, 112=%d\n",
7217 sizeof(Formattable), 112);
51004dcb
A
7218 }
7219}
7220
57a6839d
A
7221UBool NumberFormatTest::testFormattableAsUFormattable(const char *file, int line, Formattable &f) {
7222 UnicodeString fileLine = UnicodeString(file)+UnicodeString(":")+line+UnicodeString(": ");
7223
7224 UFormattable *u = f.toUFormattable();
7225 logln();
7226 if (u == NULL) {
7227 errln("%s:%d: Error: f.toUFormattable() retuned NULL.");
7228 return FALSE;
7229 }
7230 logln("%s:%d: comparing Formattable with UFormattable", file, line);
7231 logln(fileLine + toString(f));
7232
7233 UErrorCode status = U_ZERO_ERROR;
7234 UErrorCode valueStatus = U_ZERO_ERROR;
7235 UFormattableType expectUType = UFMT_COUNT; // invalid
7236
7237 UBool triedExact = FALSE; // did we attempt an exact comparison?
7238 UBool exactMatch = FALSE; // was the exact comparison true?
7239
7240 switch( f.getType() ) {
7241 case Formattable::kDate:
7242 expectUType = UFMT_DATE;
7243 exactMatch = (f.getDate()==ufmt_getDate(u, &valueStatus));
7244 triedExact = TRUE;
7245 break;
7246 case Formattable::kDouble:
7247 expectUType = UFMT_DOUBLE;
7248 exactMatch = (f.getDouble()==ufmt_getDouble(u, &valueStatus));
7249 triedExact = TRUE;
7250 break;
7251 case Formattable::kLong:
7252 expectUType = UFMT_LONG;
7253 exactMatch = (f.getLong()==ufmt_getLong(u, &valueStatus));
7254 triedExact = TRUE;
7255 break;
7256 case Formattable::kString:
7257 expectUType = UFMT_STRING;
7258 {
7259 UnicodeString str;
7260 f.getString(str);
7261 int32_t len;
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);
7267 }
7268 triedExact = TRUE;
7269 }
7270 break;
7271 case Formattable::kArray:
7272 expectUType = UFMT_ARRAY;
7273 triedExact = TRUE;
7274 {
7275 int32_t count = ufmt_getArrayLength(u, &valueStatus);
7276 int32_t count2;
7277 const Formattable *array2 = f.getArray(count2);
7278 exactMatch = assertEquals(fileLine + " array count", count, count2);
7279
7280 if(exactMatch) {
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]));
7286 exactMatch = FALSE;
7287 } else {
7288 if(!testFormattableAsUFormattable("(sub item)",i,*Formattable::fromUFormattable(uu))) {
7289 exactMatch = FALSE;
7290 }
7291 }
7292 }
7293 }
7294 }
7295 break;
7296 case Formattable::kInt64:
7297 expectUType = UFMT_INT64;
7298 exactMatch = (f.getInt64()==ufmt_getInt64(u, &valueStatus));
7299 triedExact = TRUE;
7300 break;
7301 case Formattable::kObject:
7302 expectUType = UFMT_OBJECT;
7303 exactMatch = (f.getObject()==ufmt_getObject(u, &valueStatus));
7304 triedExact = TRUE;
7305 break;
7306 }
7307 UFormattableType uType = ufmt_getType(u, &status);
7308
7309 if(U_FAILURE(status)) {
7310 errln("%s:%d: Error calling ufmt_getType - %s", file, line, u_errorName(status));
7311 return FALSE;
7312 }
7313
7314 if(uType != expectUType) {
7315 errln("%s:%d: got type (%d) expected (%d) from ufmt_getType", file, line, (int) uType, (int) expectUType);
7316 }
7317
7318 if(triedExact) {
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);
7323 } else {
7324 logln("%s:%d: exact match OK", file, line);
7325 }
7326 } else {
7327 logln("%s:%d: note, did not attempt exact match for this formattable type", file, line);
7328 }
7329
7330 if( assertEquals(fileLine + " isNumeric()", f.isNumeric(), ufmt_isNumeric(u))
7331 && f.isNumeric()) {
7332 UErrorCode convStatus = U_ZERO_ERROR;
7333
7334 if(uType != UFMT_INT64) { // may fail to compare
7335 assertTrue(fileLine + " as doubles ==", f.getDouble(convStatus)==ufmt_getDouble(u, &convStatus));
7336 }
7337
7338 if( assertSuccess(fileLine + " (numeric conversion status)", convStatus) ) {
7339 StringPiece fDecNum = f.getDecimalNumber(convStatus);
7340#if 1
7341 int32_t len;
7342 const char *decNumChars = ufmt_getDecNumChars(u, &len, &convStatus);
7343#else
7344 // copy version
7345 char decNumChars[200];
7346 int32_t len = ufmt_getDecNumChars(u, decNumChars, 200, &convStatus);
7347#endif
7348
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());
7353 }
7354
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);
7359
0f5d89e8 7360 if( (l==r)
57a6839d 7361 && ( uType != UFMT_INT64 ) // int64 better not overflow
0f5d89e8 7362 && (U_INVALID_FORMAT_ERROR==int64ConversionU)
57a6839d
A
7363 && (U_INVALID_FORMAT_ERROR==int64ConversionF) ) {
7364 logln("%s:%d: OK: 64 bit overflow", file, line);
7365 } else {
7366 assertEquals(fileLine + " as int64 ==", l, r);
7367 assertSuccess(fileLine + " Formattable.getnt64()", int64ConversionF);
7368 assertSuccess(fileLine + " ufmt_getInt64()", int64ConversionU);
7369 }
7370 }
7371 }
7372 return exactMatch || !triedExact;
7373}
7374
7375void NumberFormatTest::TestUFormattable(void) {
7376 {
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()",
7383 (defaultFormattable
7384 == *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
7385 assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
7386 (defaultFormattable
7387 == *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
7388 assertTrue((UnicodeString)"comparing Formattable() round tripped through UFormattable",
7389 (defaultFormattable
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);
7398 }
7399 // test some random Formattables
7400 {
7401 Formattable f(ucal_getNow(), Formattable::kIsDate);
7402 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7403 }
7404 {
7405 Formattable f((double)1.61803398874989484820); // golden ratio
7406 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7407 }
7408 {
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);
7411 }
7412 {
7413 Formattable f((int32_t)4); // random number, source: http://www.xkcd.com/221/
7414 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7415 }
7416 {
7417 Formattable f("Hello world."); // should be invariant?
7418 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7419 }
7420 {
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);
7425 }
7426 {
7427 UErrorCode status2 = U_ZERO_ERROR;
7428 UObject *obj = new Locale();
7429 Formattable f(obj);
7430 assertSuccess("Constructing a Formattable from a default constructed Locale()", status2);
7431 testFormattableAsUFormattable(__FILE__, __LINE__, f);
7432 }
7433 {
7434 const Formattable array[] = {
7435 Formattable(ucal_getNow(), Formattable::kIsDate),
7436 Formattable((int32_t)4),
7437 Formattable((double)1.234),
7438 };
7439
7440 Formattable fa(array, 3);
7441 testFormattableAsUFormattable(__FILE__, __LINE__, fa);
7442 }
7443}
7444
7445void NumberFormatTest::TestSignificantDigits(void) {
7446 double input[] = {
7447 0, 0,
7448 0.1, -0.1,
7449 123, -123,
7450 12345, -12345,
7451 123.45, -123.45,
7452 123.44501, -123.44501,
7453 0.001234, -0.001234,
7454 0.00000000123, -0.00000000123,
7455 0.0000000000000000000123, -0.0000000000000000000123,
7456 1.2, -1.2,
7457 0.0000000012344501, -0.0000000012344501,
7458 123445.01, -123445.01,
7459 12344501000000000000000000000000000.0, -12344501000000000000000000000000000.0,
7460 };
7461 const char* expected[] = {
7462 "0.00", "0.00",
7463 "0.100", "-0.100",
7464 "123", "-123",
7465 "12345", "-12345",
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",
7471 "1.20", "-1.20",
7472 "0.0000000012345", "-0.0000000012345",
7473 "123450", "-123450",
7474 "12345000000000000000000000000000000", "-12345000000000000000000000000000000",
7475 };
7476
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")
7482
7483 numberFormat->setSignificantDigitsUsed(TRUE);
7484 numberFormat->setMinimumSignificantDigits(3);
7485 numberFormat->setMaximumSignificantDigits(5);
7486 numberFormat->setGroupingUsed(false);
0f5d89e8 7487
57a6839d
A
7488 UnicodeString result;
7489 UnicodeString expectedResult;
2ca993e8 7490 for (unsigned int i = 0; i < UPRV_LENGTHOF(input); ++i) {
57a6839d
A
7491 numberFormat->format(input[i], result);
7492 UnicodeString expectedResult(expected[i]);
7493 if (result != expectedResult) {
7494 errln((UnicodeString)"Expected: '" + expectedResult + "' got '" + result);
7495 }
7496 result.remove();
7497 }
3d1f044b
A
7498
7499 // Test for ICU-20063
7500 {
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");
7526 }
57a6839d
A
7527}
7528
7529void 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")
7535
7536 numberFormat->setSignificantDigitsUsed(TRUE);
7537 numberFormat->setMaximumSignificantDigits(3);
0f5d89e8 7538
57a6839d
A
7539 UnicodeString result;
7540 numberFormat->format(0.0, result);
7541 if (result != "0") {
7542 errln((UnicodeString)"Expected: 0, got " + result);
7543 }
7544}
7545
7546void 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));
7553 return;
7554 }
0f5d89e8 7555
57a6839d
A
7556 if (numberFormat->areSignificantDigitsUsed() == TRUE) {
7557 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__);
7558 }
7559 numberFormat->setSignificantDigitsUsed(TRUE);
7560 if (numberFormat->areSignificantDigitsUsed() == FALSE) {
7561 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
7562 }
7563
7564 numberFormat->setSignificantDigitsUsed(FALSE);
7565 if (numberFormat->areSignificantDigitsUsed() == TRUE) {
7566 errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__);
7567 }
7568
7569 numberFormat->setMinimumSignificantDigits(3);
7570 if (numberFormat->areSignificantDigitsUsed() == FALSE) {
7571 errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
7572 }
7573
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__);
7578 }
0f5d89e8 7579
57a6839d
A
7580}
7581
7582void 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);
7587 Formattable af;
7588 ParsePosition ppos;
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.");
7594 }
7595 delete test;
7596}
7597
7598void 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);
7603 Formattable af;
7604 ParsePosition ppos;
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."));
7610 }
7611 delete test;
7612}
7613
7614void NumberFormatTest::TestCustomCurrencySignAndSeparator() {
7615 UErrorCode status = U_ZERO_ERROR;
7616 DecimalFormatSymbols custom(Locale::getUS(), status);
7617 CHECK(status, "DecimalFormatSymbols constructor");
7618
7619 custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "*");
7620 custom.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, "^");
7621 custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, ":");
7622
7623 UnicodeString pat(" #,##0.00");
7624 pat.insert(0, (UChar)0x00A4);
7625
7626 DecimalFormat fmt(pat, custom, status);
7627 CHECK(status, "DecimalFormat constructor");
7628
7629 UnicodeString numstr("* 1^234:56");
7630 expect2(fmt, (Formattable)((double)1234.56), numstr);
7631}
7632
7633typedef struct {
7634 const char * locale;
7635 UBool lenient;
7636 UnicodeString numString;
7637 double value;
7638} SignsAndMarksItem;
7639
7640
7641void 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 },
7652
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 },
7661
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 },
0f5d89e8 7670
57a6839d
A
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 },
7679
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 },
7688
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 },
7697
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 },
7706
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 },
7718 // terminator
7719 { NULL, 0, UnicodeString(""), 0 },
7720 };
7721
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);
7728 Formattable fmtobj;
7729 ParsePosition ppos;
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);
7735 }
7736 } else {
7737 errln((UnicodeString)"FAIL: locale " + itemPtr->locale + ", lenient " + itemPtr->lenient + ", parse of \"" + itemPtr->numString + "\" gives position " + ppos.getIndex());
7738 }
7739 } else {
7740 dataerrln("FAIL: NumberFormat::createInstance for locale % gives error %s", itemPtr->locale, u_errorName(status));
7741 }
7742 delete numfmt;
7743 }
7744}
7745
7746typedef struct {
7747 DecimalFormat::ERoundingMode mode;
7748 double value;
7749 UnicodeString expected;
7750} Test10419Data;
7751
7752
7753// Tests that rounding works right when fractional digits is set to 0.
7754void 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"},
7763 };
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));
7768 return;
7769 }
2ca993e8 7770 for (int32_t i = 0; i < UPRV_LENGTHOF(items); ++i) {
57a6839d
A
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);
7776 }
7777 }
7778}
7779
7780void NumberFormatTest::Test10468ApplyPattern() {
7781 // Padding char of fmt is now 'a'
7782 UErrorCode status = U_ZERO_ERROR;
7783 DecimalFormat fmt("'I''ll'*a###.##", status);
7784
7785 if (U_FAILURE(status)) {
7786 errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status));
7787 return;
7788 }
7789
0f5d89e8 7790 assertEquals("Padding character should be 'a'.", u"a", fmt.getPadCharacterString());
57a6839d
A
7791
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);
7795
0f5d89e8
A
7796 // Oops this still prints 'a' even though we changed the pattern.
7797 assertEquals("applyPattern did not clear padding character.", u" ", fmt.getPadCharacterString());
57a6839d
A
7798}
7799
7800void 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));
7805 return;
7806 }
0f5d89e8 7807
57a6839d
A
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[] = {
7817 "Round Ceiling",
7818 "Round Down",
7819 "Round Floor",
7820 "Round half down",
7821 "Round half even",
7822 "Round half up",
7823 "Round up"};
0f5d89e8 7824
57a6839d
A
7825 {
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"};
7836 verifyRounding(
7837 format,
7838 values,
7839 expected,
7840 roundingModes,
7841 descriptions,
2ca993e8
A
7842 UPRV_LENGTHOF(values),
7843 UPRV_LENGTHOF(roundingModes));
57a6839d
A
7844 }
7845 {
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"};
7856 verifyRounding(
7857 format,
7858 values,
7859 expected,
7860 roundingModes,
7861 descriptions,
2ca993e8
A
7862 UPRV_LENGTHOF(values),
7863 UPRV_LENGTHOF(roundingModes));
57a6839d
A
7864 }
7865/* Commented out for now until we decide how rounding to zero should work, +0 vs. -0
7866 {
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"};
7877 verifyRounding(
7878 format,
7879 values,
7880 expected,
7881 roundingModes,
7882 descriptions,
2ca993e8
A
7883 UPRV_LENGTHOF(values),
7884 UPRV_LENGTHOF(roundingModes));
57a6839d
A
7885 }
7886*/
7887 {
7888
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"};
7899 verifyRounding(
7900 format,
7901 values,
7902 expected,
7903 roundingModes,
7904 descriptions,
2ca993e8
A
7905 UPRV_LENGTHOF(values),
7906 UPRV_LENGTHOF(roundingModes));
57a6839d
A
7907 }
7908 {
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"};
7919 verifyRounding(
7920 format,
7921 values,
7922 expected,
7923 roundingModes,
7924 descriptions,
2ca993e8
A
7925 UPRV_LENGTHOF(values),
7926 UPRV_LENGTHOF(roundingModes));
57a6839d
A
7927 }
7928 {
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"};
7939 verifyRounding(
7940 format,
7941 values,
7942 expected,
7943 roundingModes,
7944 descriptions,
2ca993e8
A
7945 UPRV_LENGTHOF(values),
7946 UPRV_LENGTHOF(roundingModes));
57a6839d
A
7947 }
7948 {
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"};
7959 verifyRounding(
7960 format,
7961 values,
7962 expected,
7963 roundingModes,
7964 descriptions,
2ca993e8
A
7965 UPRV_LENGTHOF(values),
7966 UPRV_LENGTHOF(roundingModes));
57a6839d
A
7967 }
7968}
7969
7970void NumberFormatTest::TestZeroScientific10547() {
7971 UErrorCode status = U_ZERO_ERROR;
7972 DecimalFormat fmt("0.00E0", status);
0f5d89e8 7973 if (!assertSuccess("Format creation", status)) {
57a6839d
A
7974 return;
7975 }
7976 UnicodeString out;
7977 fmt.format(-0.0, out);
0f5d89e8 7978 assertEquals("format", "-0.00E0", out, true);
57a6839d
A
7979}
7980
7981void NumberFormatTest::verifyRounding(
7982 DecimalFormat& format,
7983 const double *values,
7984 const char * const *expected,
7985 const DecimalFormat::ERoundingMode *roundingModes,
7986 const char * const *descriptions,
7987 int32_t valueSize,
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) {
0f5d89e8
A
7997 dataerrln("For %s value %f, expected '%s', got '%s'",
7998 descriptions[i], values[j], CStr(currentExpected)(), CStr(actual)());
57a6839d
A
7999 }
8000 }
8001 }
8002}
8003
8004void NumberFormatTest::TestAccountingCurrency() {
8005 UErrorCode status = U_ZERO_ERROR;
8006 UNumberFormatStyle style = UNUM_CURRENCY_ACCOUNTING;
8007
8008 expect(NumberFormat::createInstance("en_US", style, status),
f3c0d7a5 8009 (Formattable)(double)1234.5, "$1,234.50", TRUE, status);
57a6839d 8010 expect(NumberFormat::createInstance("en_US", style, status),
f3c0d7a5 8011 (Formattable)(double)-1234.5, "($1,234.50)", TRUE, status);
57a6839d 8012 expect(NumberFormat::createInstance("en_US", style, status),
f3c0d7a5 8013 (Formattable)(double)0, "$0.00", TRUE, status);
57a6839d 8014 expect(NumberFormat::createInstance("en_US", style, status),
f3c0d7a5 8015 (Formattable)(double)-0.2, "($0.20)", TRUE, status);
57a6839d
A
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),
f3c0d7a5 8021 (Formattable)(double)-23456.7, UnicodeString("-23.456,70\\u00A0\\u20AC").unescape(), TRUE, status);
57a6839d
A
8022}
8023
8024// for #5186
8025void NumberFormatTest::TestEquality() {
8026 UErrorCode status = U_ZERO_ERROR;
0f5d89e8 8027 DecimalFormatSymbols symbols(Locale("root"), status);
57a6839d
A
8028 if (U_FAILURE(status)) {
8029 dataerrln("Fail: can't create DecimalFormatSymbols for root");
8030 return;
8031 }
8032 UnicodeString pattern("#,##0.###");
0f5d89e8 8033 DecimalFormat fmtBase(pattern, symbols, status);
57a6839d
A
8034 if (U_FAILURE(status)) {
8035 dataerrln("Fail: can't create DecimalFormat using root symbols");
8036 return;
8037 }
8038
0f5d89e8
A
8039 DecimalFormat* fmtClone = (DecimalFormat*)fmtBase.clone();
8040 fmtClone->setFormatWidth(fmtBase.getFormatWidth() + 32);
8041 if (*fmtClone == fmtBase) {
57a6839d
A
8042 errln("Error: DecimalFormat == does not distinguish objects that differ only in FormatWidth");
8043 }
8044 delete fmtClone;
57a6839d
A
8045}
8046
b331163b
A
8047void NumberFormatTest::TestCurrencyUsage() {
8048 double agent = 123.567;
8049
8050 UErrorCode status;
8051 DecimalFormat *fmt;
8052
8053 // compare the Currency and Currency Cash Digits
8054 // Note that as of CLDR 26:
c5116b9f
A
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)
2ca993e8 8058 // * CAD rounds to .05 in cash mode only
b331163b 8059 // 1st time for getter/setter, 2nd time for factory method
3d1f044b 8060 Locale enUS_ISK("en_US@currency=ISK");
b331163b
A
8061
8062 for(int i=0; i<2; i++){
8063 status = U_ZERO_ERROR;
8064 if(i == 0){
3d1f044b
A
8065 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_ISK, UNUM_CURRENCY, status);
8066 if (assertSuccess("en_US@currency=ISK/CURRENCY", status, TRUE) == FALSE) {
b331163b
A
8067 continue;
8068 }
8069
8070 UnicodeString original;
8071 fmt->format(agent,original);
3d1f044b 8072 assertEquals("Test Currency Usage 1", u"ISK\u00A0124", original);
b331163b
A
8073
8074 // test the getter here
8075 UCurrencyUsage curUsage = fmt->getCurrencyUsage();
f3c0d7a5 8076 assertEquals("Test usage getter - standard", (int32_t)curUsage, (int32_t)UCURR_USAGE_STANDARD);
b331163b
A
8077
8078 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status);
8079 }else{
3d1f044b
A
8080 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_ISK, UNUM_CASH_CURRENCY, status);
8081 if (assertSuccess("en_US@currency=ISK/CASH", status, TRUE) == FALSE) {
b331163b
A
8082 continue;
8083 }
8084 }
8085
8086 // must be usage = cash
8087 UCurrencyUsage curUsage = fmt->getCurrencyUsage();
f3c0d7a5 8088 assertEquals("Test usage getter - cash", (int32_t)curUsage, (int32_t)UCURR_USAGE_CASH);
b331163b
A
8089
8090 UnicodeString cash_currency;
8091 fmt->format(agent,cash_currency);
3d1f044b 8092 assertEquals("Test Currency Usage 2", u"ISK\u00A0124", cash_currency);
b331163b
A
8093 delete fmt;
8094 }
8095
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;
8101 if(i == 0){
8102 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CURRENCY, status);
8103 if (assertSuccess("en_US@currency=CAD/CURRENCY", status, TRUE) == FALSE) {
8104 continue;
8105 }
8106
8107 UnicodeString original_rounding;
8108 fmt->format(agent, original_rounding);
0f5d89e8 8109 assertEquals("Test Currency Usage 3", u"CA$123.57", original_rounding);
b331163b
A
8110 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status);
8111 }else{
0f5d89e8 8112 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status);
b331163b
A
8113 if (assertSuccess("en_US@currency=CAD/CASH", status, TRUE) == FALSE) {
8114 continue;
8115 }
8116 }
8117
8118 UnicodeString cash_rounding_currency;
8119 fmt->format(agent, cash_rounding_currency);
0f5d89e8 8120 assertEquals("Test Currency Usage 4", u"CA$123.55", cash_rounding_currency);
b331163b
A
8121 delete fmt;
8122 }
8123
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;
8129 if(i == 0){
8130 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CURRENCY, status);
8131 if (assertSuccess("en_US@currency=CAD/CURRENCY", status, TRUE) == FALSE) {
8132 continue;
8133 }
8134 fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status);
8135 }else{
8136 fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status);
8137 if (assertSuccess("en_US@currency=CAD/CASH", status, TRUE) == FALSE) {
8138 continue;
8139 }
8140 }
8141
8142 UnicodeString cur_original;
2ca993e8 8143 fmt->setCurrencyUsage(UCURR_USAGE_STANDARD, &status);
b331163b 8144 fmt->format(agent, cur_original);
0f5d89e8 8145 assertEquals("Test Currency Usage 5", u"CA$123.57", cur_original);
b331163b
A
8146
8147 fmt->setCurrency(CUR_PKR, status);
8148 assertSuccess("Set currency to PKR", status);
8149
8150 UnicodeString PKR_changed;
8151 fmt->format(agent, PKR_changed);
c5116b9f 8152 assertEquals("Test Currency Usage 6", u"PKR\u00A0124", PKR_changed);
b331163b
A
8153 delete fmt;
8154 }
8155}
8156
8157
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.
8162//
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.
8167
8168void NumberFormatTest::TestDoubleLimit11439() {
8169 char buf[50];
8170 for (int64_t num = MAX_INT64_IN_DOUBLE-10; num<=MAX_INT64_IN_DOUBLE; num++) {
8171 sprintf(buf, "%lld", (long long)num);
8172 double fNum = 0.0;
8173 sscanf(buf, "%lf", &fNum);
0f5d89e8 8174 int64_t rtNum = static_cast<int64_t>(fNum);
b331163b
A
8175 if (num != rtNum) {
8176 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__, __LINE__, (long long)num, (long long)rtNum);
8177 return;
8178 }
8179 }
8180 for (int64_t num = -MAX_INT64_IN_DOUBLE+10; num>=-MAX_INT64_IN_DOUBLE; num--) {
8181 sprintf(buf, "%lld", (long long)num);
8182 double fNum = 0.0;
8183 sscanf(buf, "%lf", &fNum);
0f5d89e8 8184 int64_t rtNum = static_cast<int64_t>(fNum);
b331163b
A
8185 if (num != rtNum) {
8186 errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__, __LINE__, (long long)num, (long long)rtNum);
8187 return;
8188 }
8189 }
8190}
8191
2ca993e8
A
8192void 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));
8200 return;
8201 }
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));
8207
8208 // Test equality with affixes. set affix methods can't capture special
8209 // characters which is why equality should fail.
8210 {
8211 DecimalFormat fmtCopy(fmt);
8212 assertTrue("", fmt == fmtCopy);
8213 UnicodeString someAffix;
8214 fmtCopy.setPositivePrefix(fmtCopy.getPositivePrefix(someAffix));
8215 assertTrue("", fmt != fmtCopy);
8216 }
8217 {
8218 DecimalFormat fmtCopy(fmt);
8219 assertTrue("", fmt == fmtCopy);
8220 UnicodeString someAffix;
8221 fmtCopy.setPositiveSuffix(fmtCopy.getPositiveSuffix(someAffix));
8222 assertTrue("", fmt != fmtCopy);
8223 }
8224 {
8225 DecimalFormat fmtCopy(fmt);
8226 assertTrue("", fmt == fmtCopy);
8227 UnicodeString someAffix;
8228 fmtCopy.setNegativePrefix(fmtCopy.getNegativePrefix(someAffix));
8229 assertTrue("", fmt != fmtCopy);
8230 }
8231 {
8232 DecimalFormat fmtCopy(fmt);
8233 assertTrue("", fmt == fmtCopy);
8234 UnicodeString someAffix;
8235 fmtCopy.setNegativeSuffix(fmtCopy.getNegativeSuffix(someAffix));
8236 assertTrue("", fmt != fmtCopy);
8237 }
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));
8248}
8249
8250void NumberFormatTest::TestToPatternScientific11648() {
8251 UErrorCode status = U_ZERO_ERROR;
8252 Locale en("en");
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));
8257 return;
8258 }
8259 fmt.setScientificNotation(TRUE);
8260 UnicodeString pattern;
8261 assertEquals("", "0.00E0", fmt.toPattern(pattern));
8262 DecimalFormat fmt2(pattern, sym, status);
8263 assertSuccess("", status);
8264}
8265
8266void NumberFormatTest::TestBenchmark() {
8267/*
8268 UErrorCode status = U_ZERO_ERROR;
8269 Locale en("en");
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);
f3c0d7a5 8274 FieldPosition fpos(FieldPosition::DONT_CARE);
2ca993e8
A
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);
8283 }
8284 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8285 assertSuccess("", status);
8286
8287 UErrorCode status = U_ZERO_ERROR;
8288 MessageFormat fmt("{0, plural, one {I have # friend.} other {I have # friends.}}", status);
f3c0d7a5 8289 FieldPosition fpos(FieldPosition::DONT_CARE);
2ca993e8
A
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);
8298 }
8299 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8300 assertSuccess("", status);
8301
8302 UErrorCode status = U_ZERO_ERROR;
8303 Locale en("en");
8304 Measure measureC(23, MeasureUnit::createCelsius(status), status);
8305 MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status);
f3c0d7a5 8306 FieldPosition fpos(FieldPosition::DONT_CARE);
2ca993e8
A
8307 clock_t start = clock();
8308 for (int32_t i = 0; i < 1000000; ++i) {
8309 UnicodeString appendTo;
8310 fmt.formatMeasures(
8311 &measureC, 1, appendTo, fpos, status);
8312 }
8313 errln("Took %f", (double) (clock() - start) / CLOCKS_PER_SEC);
8314 assertSuccess("", status);
8315*/
8316}
8317
8318void 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));
8323 return;
8324 }
8325 UChar JPY[] = {0x4A, 0x50, 0x59, 0x0};
8326 fmt->setCurrency(JPY, status);
8327 if (!assertSuccess("", status)) {
8328 return;
8329 }
8330 assertEquals("", 0, fmt->getMaximumFractionDigits());
8331}
8332
8333
8334void 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));
8340 return;
8341 }
8342 UnicodeString formattedNum;
8343 fmt->format(11234.567, formattedNum, NULL, status);
8344 assertEquals("", "11,234.57 US dollars", formattedNum);
8345 delete fmt;
8346}
8347
8348void 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));
8355 return;
8356 }
8357 UnicodeString result;
8358 assertEquals(
8359 "ctor favors precision of currency",
8360 "$5.00",
f3c0d7a5 8361 fmt.format((double)5, result));
2ca993e8
A
8362 result.remove();
8363 fmt.applyPattern(pattern.unescape(), status);
8364 assertEquals(
8365 "applyPattern favors precision of pattern",
8366 "$5",
f3c0d7a5 8367 fmt.format((double)5, result));
2ca993e8
A
8368}
8369
8370void NumberFormatTest::Test11868() {
8371 double posAmt = 34.567;
8372 double negAmt = -9876.543;
8373
8374 Locale selectedLocale("en_US");
8375 UErrorCode status = U_ZERO_ERROR;
8376
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)) {
8383 return;
8384 }
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());
8389
8390 // Test field position iterator
8391 {
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},
8397 {0, -1, 0}};
8398 UnicodeString result;
8399 FieldPositionIterator iter;
8400 fmt->format(posAmt, result, &iter, status);
8401 assertEquals("", "34.57 US dollars", result);
8402 verifyFieldPositionIterator(attributes, iter);
8403 }
8404
8405 result.remove();
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());
8410
8411 // Test field position iterator
8412 {
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},
8420 {0, -1, 0}};
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);
8426 }
8427}
8428
8429void NumberFormatTest::Test10727_RoundingZero() {
0f5d89e8
A
8430 IcuTestErrorCode status(*this, "Test10727_RoundingZero");
8431 DecimalQuantity dq;
8432 dq.setToDouble(-0.0);
8433 assertTrue("", dq.isNegative());
8434 dq.roundToMagnitude(0, UNUM_ROUND_HALFEVEN, status);
8435 assertTrue("", dq.isNegative());
8436}
8437
8438void 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());
3d1f044b
A
8446 if (ppos.getErrorIndex() != -1) {
8447 return;
8448 }
0f5d89e8
A
8449 assertEquals("Should parse to 1500 USD", 1500LL, result->getNumber().getInt64(status));
8450 assertEquals("Should parse to 1500 USD", u"USD", result->getISOCurrency());
8451}
8452
8453void 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);
8469}
8470
8471void 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);
8476 // Parse Test
8477 expect(*df, u"1.2", 1.2);
2ca993e8
A
8478}
8479
8480void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
8481 {
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)) {
8487 return;
8488 }
8489 DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias();
8490 dfmt->setCurrency(USD);
8491 UnicodeString result;
0f5d89e8 8492
2ca993e8
A
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));
8496
8497 UnicodeString appendTo;
8498 assertEquals("", "$3.78", dfmt->format(3.78, appendTo, status));
8499 assertSuccess("", status);
8500 }
8501 {
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)) {
8507 return;
8508 }
8509 DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias();
8510 UnicodeString result;
3d1f044b 8511 assertEquals("", u" (unknown currency)", dfmt->getPositiveSuffix(result));
2ca993e8
A
8512 dfmt->setCurrency(USD);
8513
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");
8521 appendTo.remove();
8522 assertEquals("", "3.78booya", dfmt->format(3.78, appendTo, status));
8523 assertEquals("", "booya", dfmt->getPositiveSuffix(result));
8524 }
8525}
8526
8527void NumberFormatTest::Test11475_signRecognition() {
8528 UErrorCode status = U_ZERO_ERROR;
8529 DecimalFormatSymbols sym("en", status);
8530 UnicodeString result;
8531 {
8532 DecimalFormat fmt("+0.00", sym, status);
8533 if (!assertSuccess("", status)) {
8534 return;
8535 }
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},
8541 {0, -1, 0}};
8542 UnicodeString result;
8543 FieldPositionIterator iter;
8544 fmt.format(2.3, result, &iter, status);
8545 assertEquals("", "+2.30", result);
8546 verifyFieldPositionIterator(attributes, iter);
8547 }
8548 {
8549 DecimalFormat fmt("++0.00+;-(#)--", sym, status);
8550 if (!assertSuccess("", status)) {
8551 return;
8552 }
8553 {
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},
8560 {0, -1, 0}};
8561 UnicodeString result;
8562 FieldPositionIterator iter;
8563 fmt.format(2.3, result, &iter, status);
8564 assertEquals("", "++2.30+", result);
8565 verifyFieldPositionIterator(attributes, iter);
8566 }
8567 {
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},
8574 {0, -1, 0}};
8575 UnicodeString result;
8576 FieldPositionIterator iter;
8577 fmt.format(-2.3, result, &iter, status);
8578 assertEquals("", "-(2.30)--", result);
8579 verifyFieldPositionIterator(attributes, iter);
8580 }
8581 }
8582}
8583
8584void NumberFormatTest::Test11640_getAffixes() {
8585 UErrorCode status = U_ZERO_ERROR;
8586 DecimalFormatSymbols symbols("en_US", status);
8587 if (!assertSuccess("", status)) {
8588 return;
8589 }
8590 UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00 %\\u00a4\\u00a4");
8591 pattern = pattern.unescape();
8592 DecimalFormat fmt(pattern, symbols, status);
8593 if (!assertSuccess("", status)) {
8594 return;
8595 }
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));
8601}
8602
8603void 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)) {
8609 return;
8610 }
8611 static UChar USD[] = {0x55, 0x53, 0x44, 0x0};
8612 fmt.setCurrency(USD);
8613 UnicodeString appendTo;
0f5d89e8 8614
2ca993e8
A
8615 assertEquals("", "US dollars 12.34", fmt.format(12.34, appendTo));
8616
8617 UnicodeString topattern;
8618 fmt.toPattern(topattern);
8619 DecimalFormat fmt2(topattern, status);
8620 if (!assertSuccess("", status)) {
8621 return;
8622 }
8623 fmt2.setCurrency(USD);
0f5d89e8 8624
2ca993e8
A
8625 appendTo.remove();
8626 assertEquals("", "US dollars 12.34", fmt2.format(12.34, appendTo));
8627}
8628
0f5d89e8
A
8629void 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;
8636
8637 CharString localeId("en@numbers=", status);
8638 for (int i = 0; i < ULOC_KEYWORDS_CAPACITY + extraLength; i++) {
8639 localeId.append('x', status);
8640 }
8641 assertSuccess("Constructing locale string", status);
8642 Locale locale(localeId.data());
8643
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);
8647 }
8648}
8649
8650void 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__);
8656 return;
8657 }
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);
8663
8664 Formattable result;
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);
8668
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);
8677
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);
8682}
8683
2ca993e8
A
8684
8685void NumberFormatTest::verifyFieldPositionIterator(
8686 NumberFormatTest_Attributes *expected, FieldPositionIterator &iter) {
8687 int32_t idx = 0;
8688 FieldPosition fp;
8689 while (iter.next(fp)) {
8690 if (expected[idx].spos == -1) {
8691 errln("Iterator should have ended. got %d", fp.getField());
8692 return;
8693 }
8694 assertEquals("id", expected[idx].id, fp.getField());
8695 assertEquals("start", expected[idx].spos, fp.getBeginIndex());
8696 assertEquals("end", expected[idx].epos, fp.getEndIndex());
8697 ++idx;
8698 }
8699 if (expected[idx].spos != -1) {
8700 errln("Premature end of iterator. expected %d", expected[idx].id);
8701 }
8702}
8703
0f5d89e8
A
8704void NumberFormatTest::Test11735_ExceptionIssue() {
8705 IcuTestErrorCode status(*this, "Test11735_ExceptionIssue");
2ca993e8
A
8706 Locale enLocale("en");
8707 DecimalFormatSymbols symbols(enLocale, status);
0f5d89e8
A
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());
8714 }
8715}
8716
8717void NumberFormatTest::Test11035_FormatCurrencyAmount() {
8718 UErrorCode status = U_ZERO_ERROR;
8719 double amount = 12345.67;
8720 const char16_t* expected = u"12,345$67 ​";
8721
8722 // Test two ways to set a currency via API
2ca993e8 8723
0f5d89e8
A
8724 Locale loc1 = Locale("pt_PT");
8725 LocalPointer<NumberFormat> fmt1(NumberFormat::createCurrencyInstance("loc1", status),
8726 status);
2ca993e8 8727 if (U_FAILURE(status)) {
0f5d89e8
A
8728 dataerrln("%s %d NumberFormat instance fmt1 is null", __FILE__, __LINE__);
8729 return;
8730 }
8731 fmt1->setCurrency(u"PTE", status);
8732 assertSuccess("Setting currency on fmt1", status);
8733 UnicodeString actualSetCurrency;
8734 fmt1->format(amount, actualSetCurrency);
8735
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);
8741
8742 // TODO: The following test will fail until DecimalFormat wraps NumberFormatter.
8743 if (!logKnownIssue("13574")) {
8744 assertEquals("Custom Currency Pattern, Set Currency", expected, actualSetCurrency);
2ca993e8 8745 }
0f5d89e8 8746}
2ca993e8 8747
0f5d89e8
A
8748void NumberFormatTest::Test11318_DoubleConversion() {
8749 IcuTestErrorCode status(*this, "Test11318_DoubleConversion");
8750 LocalPointer<NumberFormat> nf(NumberFormat::createInstance("en", status), status);
2ca993e8 8751 if (U_FAILURE(status)) {
0f5d89e8
A
8752 dataerrln("%s %d Error in NumberFormat instance creation", __FILE__, __LINE__);
8753 return;
8754 }
8755 nf->setMaximumFractionDigits(40);
8756 nf->setMaximumIntegerDigits(40);
3d1f044b
A
8757
8758 // Apple addition for <rdar://problem/39240173>
0f5d89e8
A
8759 DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf.getAlias());
8760 if (df != NULL) {
8761 UErrorCode status = U_ZERO_ERROR;
3d1f044b 8762 df->setAttribute(UNUM_FORMAT_WITH_FULL_PRECISION, TRUE, status);
2ca993e8 8763 }
3d1f044b 8764
0f5d89e8
A
8765 UnicodeString appendTo;
8766 nf->format(999999999999999.9, appendTo);
8767 assertEquals("Should render all digits", u"999,999,999,999,999.9", appendTo);
8768}
2ca993e8 8769
0f5d89e8
A
8770void 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);
8777
8778 {
8779 ParsePosition ppos;
8780 Formattable result;
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));
8784 }
8785 {
8786 ParsePosition ppos;
8787 Formattable result;
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));
8791 }
8792 {
8793 ParsePosition ppos;
8794 Formattable result;
8795 df2->parse("50", result, ppos);
8796 assertEquals("df2 should return the number as 0.5 even though the percent sign is missing",
8797 0.5,
8798 result.getDouble(status));
8799 }
8800}
8801
8802void NumberFormatTest::TestMultiplierWithScale() {
3d1f044b
A
8803 IcuTestErrorCode status(*this, "TestMultiplierWithScale");
8804
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
8811 }
0f5d89e8
A
8812}
8813
8814void NumberFormatTest::TestFastFormatInt32() {
8815 IcuTestErrorCode status(*this, "TestFastFormatInt32");
8816
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;}
8822
8823 double nums[] = {
8824 0.0,
8825 -0.0,
8826 NAN,
8827 INFINITY,
8828 0.1,
8829 1.0,
8830 1.1,
8831 2.0,
8832 3.0,
8833 9.0,
8834 10.0,
8835 99.0,
8836 100.0,
8837 999.0,
8838 1000.0,
8839 9999.0,
8840 10000.0,
8841 99999.0,
8842 100000.0,
8843 999999.0,
8844 1000000.0,
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};
8851
8852 for (auto num : nums) {
3d1f044b 8853 UnicodeString expected = lnf.formatDouble(num, status).toString(status);
0f5d89e8
A
8854 UnicodeString actual;
8855 df->format(num, actual);
8856 assertEquals(UnicodeString("d = ") + num, expected, actual);
8857 }
8858}
8859
8860void 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;
8866
8867 // Test equality with affixes. set affix methods can't capture special
8868 // characters which is why equality should fail.
8869 {
8870 DecimalFormat fmtCopy(fmt);
8871 assertTrue("", fmt == fmtCopy);
8872 UnicodeString positivePrefix;
8873 fmtCopy.setPositivePrefix(fmtCopy.getPositivePrefix(positivePrefix));
8874 assertFalse("", fmt == fmtCopy);
8875 }
8876 {
8877 DecimalFormat fmtCopy = DecimalFormat(fmt);
8878 assertTrue("", fmt == fmtCopy);
8879 UnicodeString positivePrefix;
8880 fmtCopy.setPositiveSuffix(fmtCopy.getPositiveSuffix(positivePrefix));
8881 assertFalse("", fmt == fmtCopy);
8882 }
8883 {
8884 DecimalFormat fmtCopy(fmt);
8885 assertTrue("", fmt == fmtCopy);
8886 UnicodeString negativePrefix;
8887 fmtCopy.setNegativePrefix(fmtCopy.getNegativePrefix(negativePrefix));
8888 assertFalse("", fmt == fmtCopy);
8889 }
8890 {
8891 DecimalFormat fmtCopy(fmt);
8892 assertTrue("", fmt == fmtCopy);
8893 UnicodeString negativePrefix;
8894 fmtCopy.setNegativeSuffix(fmtCopy.getNegativeSuffix(negativePrefix));
8895 assertFalse("", fmt == fmtCopy);
8896 }
8897}
8898
8899void NumberFormatTest::TestParseNaN() {
8900 IcuTestErrorCode status(*this, "TestParseNaN");
8901
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);
8911}
8912
3d1f044b
A
8913void NumberFormatTest::TestFormatFailIfMoreThanMaxDigits() {
8914 IcuTestErrorCode status(*this, "TestFormatFailIfMoreThanMaxDigits");
8915
8916 DecimalFormat df("0", {"en-US", status}, status);
8917 if (status.errDataIfFailureAndReset()) {
8918 return;
8919 }
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);
8927}
8928
8929void NumberFormatTest::TestParseCaseSensitive() {
8930 IcuTestErrorCode status(*this, "TestParseCaseSensitive");
8931
8932 DecimalFormat df(u"0", {"en-US", status}, status);
8933 if (status.errDataIfFailureAndReset()) {
8934 return;
8935 }
8936 assertEquals("Coverage for getter 1", (UBool) FALSE, df.isParseCaseSensitive());
8937 df.setParseCaseSensitive(TRUE);
8938 assertEquals("Coverage for getter 1", (UBool) TRUE, df.isParseCaseSensitive());
8939 Formattable result;
8940 ParsePosition ppos;
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));
8944}
8945
8946void NumberFormatTest::TestParseNoExponent() {
8947 IcuTestErrorCode status(*this, "TestParseNoExponent");
8948
8949 DecimalFormat df(u"0", {"en-US", status}, status);
8950 if (status.errDataIfFailureAndReset()) {
8951 return;
8952 }
8953 assertEquals("Coverage for getter 1", (UBool) FALSE, df.isParseNoExponent());
8954 df.setParseNoExponent(TRUE);
8955 assertEquals("Coverage for getter 1", (UBool) TRUE, df.isParseNoExponent());
8956 Formattable result;
8957 ParsePosition ppos;
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));
8961}
8962
8963void NumberFormatTest::TestSignAlwaysShown() {
8964 IcuTestErrorCode status(*this, "TestSignAlwaysShown");
8965
8966 DecimalFormat df(u"0", {"en-US", status}, status);
8967 if (status.errDataIfFailureAndReset()) {
8968 return;
8969 }
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);
8977}
8978
8979void NumberFormatTest::TestMinimumGroupingDigits() {
8980 IcuTestErrorCode status(*this, "TestMinimumGroupingDigits");
8981
8982 DecimalFormat df(u"#,##0", {"en-US", status}, status);
8983 if (status.errDataIfFailureAndReset()) {
8984 return;
8985 }
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);
8996}
8997
0f5d89e8
A
8998void NumberFormatTest::Test11897_LocalizedPatternSeparator() {
8999 IcuTestErrorCode status(*this, "Test11897_LocalizedPatternSeparator");
9000
9001 // In a locale with a different <list> symbol, like arabic,
9002 // kPatternSeparatorSymbol should still be ';'
9003 {
9004 DecimalFormatSymbols dfs("ar", status);
9005 assertEquals("pattern separator symbol should be ;",
9006 u";",
9007 dfs.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
9008 }
9009
9010 // However, the custom symbol should be used in localized notation
9011 // when set manually via API
9012 {
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()),
9021 "b");
9022 df.applyLocalizedPattern(u"c0!d0", status); // should not throw
9023 assertEquals("should apply the localized pattern",
9024 df.getNegativePrefix(result.remove()),
9025 "d");
9026 }
9027}
9028
9029void 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));
9035 return;
9036 }
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);
9041}
9042
9043void 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∔");
9059}
9060
9061void 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");
9073 FieldPosition fp;
9074 while (positions.next(fp)) {
9075 // Should not loop forever
9076 }
9077}
9078
9079void 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;
9086
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);
3d1f044b
A
9093 assertEquals("Value after applyPattern", fmtCopy->getMultiplier(), newMultiplier);
9094 assertFalse("multiplier", *fmt == *fmtCopy);
0f5d89e8
A
9095
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);
9104
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);
9113
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);
9122}
9123
9124void 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);
3d1f044b
A
9135 assertTrue("df1 == df2", *df1 == *df2);
9136 assertTrue("df2 == df1", *df2 == *df1);
0f5d89e8
A
9137 df2->setPositivePrefix(u"abc");
9138 assertTrue("df1 != df2", *df1 != *df2);
9139 assertTrue("df2 != df1", *df2 != *df1);
9140}
9141
9142void 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);
9157
9158 UnicodeString result;
3d1f044b
A
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));
0f5d89e8
A
9161 assertEquals("Plural other", u"99 америчких долара", df.format(99, result.remove(), errorCode));
9162
9163 info.setPluralRules(u"few: n is 1; one: n in 2..4", errorCode);
9164 df.setCurrencyPluralInfo(info);
3d1f044b
A
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));
0f5d89e8
A
9167 assertEquals("Plural other", u"99 америчких долара", df.format(99, result.remove(), errorCode));
9168}
9169
3d1f044b
A
9170void 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.");
9176 return;
9177 }
9178 df.setLenient(FALSE);
9179 Formattable result;
9180 df.parse(u"%2%", result, parsePosition);
9181 assertEquals("", 0, parsePosition.getIndex());
9182 assertEquals("", 0, parsePosition.getErrorIndex());
9183}
9184
0f5d89e8
A
9185void 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());
9197}
9198
9199
9200void 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);
9210}
9211
9212void NumberFormatTest::Test11648_ExpDecFormatMalPattern() {
9213 UErrorCode status = U_ZERO_ERROR;
9214
9215 DecimalFormat fmt("0.00", {"en", status}, status);
9216 if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
9217 fmt.setScientificNotation(TRUE);
9218 UnicodeString pattern;
9219
9220 assertEquals("A valid scientific notation pattern should be produced",
9221 "0.00E0",
9222 fmt.toPattern(pattern));
9223
9224 DecimalFormat fmt2(pattern, status);
9225 assertSuccess("", status);
9226}
9227
9228void 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;
9237
9238 assertEquals("", "US dollars 12.34", fmt.format(12.34, appendTo));
9239 UnicodeString topattern;
9240
3d1f044b 9241 assertEquals("", pattern, fmt.toPattern(topattern));
0f5d89e8
A
9242 DecimalFormat fmt2(topattern, status);
9243 fmt2.setCurrency(USD);
9244
9245 appendTo.remove();
9246 assertEquals("", "US dollars 12.34", fmt2.format(12.34, appendTo));
9247}
9248
9249void 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; }
9254
9255 DecimalFormatSymbols symbols = *fmt->getDecimalFormatSymbols();
9256
9257 symbols.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u'.');
9258 symbols.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, u',');
9259 fmt->setDecimalFormatSymbols(symbols);
9260 Formattable number;
9261 fmt->parse(u"300,000", number, status);
9262 assertEquals("Should parse as 300000", 300000LL, number.getInt64(status));
9263}
9264
9265void 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);
9272 Formattable result;
9273 df.parse(u"123",result, status);
9274 assertEquals("Parsing integer succeeded even though setDecimalPatternMatchRequired was set",
9275 U_INVALID_FORMAT_ERROR, status);
9276 }
9277
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);
3d1f044b 9285 assertEquals("Should replace 4 currency signs with U+FFFD", u"\uFFFD123", actual);
0f5d89e8
A
9286}
9287
9288void 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());
9297}
9298
9299void 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);
9308}
9309
9310void 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));
9316 return;
9317 }
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);
9323}
9324
9325
9326void 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);
9333
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,
9339 };
9340 int32_t tupleCount = UPRV_LENGTHOF(expected)/3;
9341 expectPositions(fpi, expected, tupleCount, result);
9342}
9343
9344void NumberFormatTest::Test13777_ParseLongNameNonCurrencyMode() {
9345 IcuTestErrorCode status(*this, "Test13777_ParseLongNameNonCurrencyMode");
9346
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");
9351}
9352
9353void NumberFormatTest::Test13804_EmptyStringsWhenParsing() {
9354 IcuTestErrorCode status(*this, "Test13804_EmptyStringsWhenParsing");
9355
9356 DecimalFormatSymbols dfs("en", status);
9357 if (status.errIfFailureAndReset()) {
9358 return;
9359 }
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);
9386
9387 DecimalFormat df("0", dfs, status);
9388 if (status.errIfFailureAndReset()) {
9389 return;
9390 }
9391 df.setGroupingUsed(TRUE);
9392 df.setScientificNotation(TRUE);
9393 df.setLenient(TRUE); // enable all matchers
9394 {
9395 UnicodeString result;
9396 df.format(0, result); // should not crash or hit infinite loop
9397 }
9398 const char16_t* samples[] = {
9399 u"",
9400 u"123",
9401 u"$123",
9402 u"-",
9403 u"+",
9404 u"44%",
9405 u"1E+2.3"
9406 };
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.
9411 Formattable result;
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();
9417 }
9418
9419 // Test with a nonempty exponent separator symbol to cover more code
9420 dfs.setSymbol(DecimalFormatSymbols::kExponentialSymbol, u"E", FALSE);
9421 df.setDecimalFormatSymbols(dfs);
9422 {
9423 Formattable result;
9424 ParsePosition ppos(0);
9425 df.parse(u"1E+2.3", result, ppos);
9426 }
2ca993e8 9427}
b331163b 9428
3d1f044b
A
9429void NumberFormatTest::Test20037_ScientificIntegerOverflow() {
9430 IcuTestErrorCode status(*this, "Test20037_ScientificIntegerOverflow");
9431
9432 LocalPointer<NumberFormat> nf(NumberFormat::createInstance(status));
9433 if (U_FAILURE(status)) {
9434 dataerrln("Unable to create NumberFormat instance.");
9435 return;
9436 }
9437 Formattable result;
9438
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",
9443 u"0",
9444 {sp.data(), sp.length(), US_INV});
9445
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",
9451 u"1E-2147483647",
9452 {sp.data(), sp.length(), US_INV});
9453
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",
9459 u"3E-2147483648",
9460 {sp.data(), sp.length(), US_INV});
9461
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});
9469
9470 // Test max value as well
9471 const char16_t* infinityInputs[] = {
9472 u"9876e2147483644",
9473 u"9876e2147483645",
9474 u"9876e2147483646",
9475 u"9876e2147483647",
9476 u"9876e2147483648",
9477 u"9876e2147483649",
9478 };
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,
9484 u"Infinity",
9485 {sp.data(), sp.length(), US_INV});
9486 }
9487}
9488
9489void NumberFormatTest::Test13840_ParseLongStringCrash() {
9490 IcuTestErrorCode status(*this, "Test13840_ParseLongStringCrash");
9491
9492 LocalPointer<NumberFormat> nf(NumberFormat::createInstance("en", status), status);
9493 if (status.errIfFailureAndReset()) { return; }
9494
9495 Formattable result;
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);
9504
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();
9511
9512 // Get the output string:
9513 StringPiece actualChars = result.getDecimalNumber(status);
9514 UnicodeString actualUString = UnicodeString(actualChars.data(), actualChars.length(), US_INV);
9515
9516 assertEquals("Should round-trip without crashing", expectedUString, actualUString);
9517}
9518
9519void NumberFormatTest::Test13850_EmptyStringCurrency() {
9520 IcuTestErrorCode status(*this, "Test13840_EmptyStringCurrency");
9521
9522 struct TestCase {
9523 const char16_t* currencyArg;
9524 UErrorCode expectedError;
9525 } cases[] = {
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}
9532 };
9533 for (const auto& cas : cases) {
9534 UnicodeString message(u"with currency arg: ");
9535 if (cas.currencyArg == nullptr) {
9536 message += u"nullptr";
9537 } else {
9538 message += UnicodeString(cas.currencyArg);
9539 }
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.
9550 continue;
9551 }
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);
9556 } else {
9557 assertEquals(u"Should unset the currency " + message, u"\u00A41.00", actual);
9558 }
9559 status.errIfFailureAndReset();
9560 }
9561}
9562
9563void 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));
9577
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));
9587
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));
9597}
9598
9599void 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));
9611
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));
9619
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));
9627}
9628
9629void NumberFormatTest::Test13731_DefaultCurrency() {
9630 IcuTestErrorCode status(*this, "Test13731_DefaultCurrency");
9631 UnicodeString result;
9632 {
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
9639 }
9640 {
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
9647 }
9648 {
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
9655 }
9656}
9657
9658void 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),
9667 expected, actual);
9668 }
9669}
9670
b75a7d8f 9671#endif /* #if !UCONFIG_NO_FORMATTING */