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