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