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