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