1 /********************************************************************
3 * Copyright (c) 1997-2004, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /* Modification History:
7 * Date Name Description
8 * 07/15/99 helena Ported to HPUX 10/11 CC.
11 #include "unicode/utypes.h"
13 #if !UCONFIG_NO_FORMATTING
16 #include "unicode/dcfmtsym.h"
17 #include "unicode/decimfmt.h"
18 #include "unicode/ucurr.h"
19 #include "unicode/ustring.h"
20 #include "unicode/measfmt.h"
21 #include "unicode/curramt.h"
30 static const UChar EUR
[] = {69,85,82,0}; // "EUR"
32 // *****************************************************************************
33 // class NumberFormatTest
34 // *****************************************************************************
36 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
38 #define CHECK(status,str) if (U_FAILURE(status)) { errln(UnicodeString("FAIL: ") + str); return; }
40 void NumberFormatTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
42 // if (exec) logln((UnicodeString)"TestSuite DateFormatTest");
44 CASE(0,TestCurrencySign
);
47 CASE(3,TestRounding487
);
49 CASE(5,TestExponential
);
52 // Upgrade to alphaWorks - liu 5/99
54 CASE(8,TestScientific
);
56 CASE(10,TestPatterns2
);
57 CASE(11,TestSecondaryGrouping
);
58 CASE(12,TestSurrogateSupport
);
61 CASE(14,TestCurrencyObject
);
62 CASE(15,TestCurrencyPatterns
);
63 CASE(16,TestDigitList
);
64 CASE(17,TestWhiteSpaceParsing
);
65 CASE(18,TestComplexCurrency
);
66 CASE(19,TestRegCurrency
);
67 CASE(20,TestSymbolsWithBadLocale
);
68 CASE(21,TestAdoptDecimalFormatSymbols
);
70 CASE(22,TestScientific2
);
71 CASE(23,TestScientificGrouping
);
75 CASE(26,TestIllegalPatterns
);
78 CASE(28,TestCurrencyNames
);
80 default: name
= ""; break;
84 // -------------------------------------
86 // Test API (increase code coverage)
88 NumberFormatTest::TestAPI(void)
91 UErrorCode status
= U_ZERO_ERROR
;
92 NumberFormat
*test
= NumberFormat::createInstance("root", status
);
93 if(U_FAILURE(status
)) {
94 errln("unable to create format object");
97 test
->setMinimumIntegerDigits(10);
98 test
->setMaximumIntegerDigits(2);
100 test
->setMinimumFractionDigits(10);
101 test
->setMaximumFractionDigits(2);
103 UnicodeString result
;
105 Formattable
bla("Paja Patak"); // Donald Duck for non Serbian speakers
106 test
->format(bla
, result
, pos
, status
);
107 if(U_SUCCESS(status
)) {
108 errln("Yuck... Formatted a duck... As a number!");
110 status
= U_ZERO_ERROR
;
117 // Test various patterns
119 NumberFormatTest::TestPatterns(void)
121 UErrorCode status
= U_ZERO_ERROR
;
122 DecimalFormatSymbols
sym(Locale::getUS(), status
);
123 if (U_FAILURE(status
)) { errln("FAIL: Could not construct DecimalFormatSymbols"); return; }
125 const char* pat
[] = { "#.#", "#.", ".#", "#" };
126 int32_t pat_length
= (int32_t)(sizeof(pat
) / sizeof(pat
[0]));
127 const char* newpat
[] = { "#0.#", "#0.", "#.0", "#" };
128 const char* num
[] = { "0", "0.", ".0", "0" };
129 for (int32_t i
=0; i
<pat_length
; ++i
)
131 status
= U_ZERO_ERROR
;
132 DecimalFormat
fmt(pat
[i
], sym
, status
);
133 if (U_FAILURE(status
)) { errln((UnicodeString
)"FAIL: DecimalFormat constructor failed for " + pat
[i
]); continue; }
134 UnicodeString newp
; fmt
.toPattern(newp
);
135 if (!(newp
== newpat
[i
]))
136 errln((UnicodeString
)"FAIL: Pattern " + pat
[i
] + " should transmute to " + newpat
[i
] +
137 "; " + newp
+ " seen instead");
139 UnicodeString s
; (*(NumberFormat
*)&fmt
).format((int32_t)0, s
);
142 errln((UnicodeString
)"FAIL: Pattern " + pat
[i
] + " should format zero as " + num
[i
] +
143 "; " + s
+ " seen instead");
144 logln((UnicodeString
)"Min integer digits = " + fmt
.getMinimumIntegerDigits());
150 NumberFormatTest::TestDigitList(void)
152 // API coverage for DigitList
154 icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
155 icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
156 icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
160 list1
.fDecimalAt
= 1;
162 list2
.set((int32_t)1);
163 if (list1
!= list2
) {
164 errln("digitlist append, operator!= or set failed ");
166 if (!(list1
== list2
)) {
167 errln("digitlist append, operator== or set failed ");
171 // -------------------------------------
173 // Test exponential pattern
175 NumberFormatTest::TestExponential(void)
177 UErrorCode status
= U_ZERO_ERROR
;
178 DecimalFormatSymbols
sym(Locale::getUS(), status
);
179 if (U_FAILURE(status
)) { errln("FAIL: Bad status returned by DecimalFormatSymbols ct"); return; }
180 const char* pat
[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
181 int32_t pat_length
= (int32_t)(sizeof(pat
) / sizeof(pat
[0]));
183 // The following #if statements allow this test to be built and run on
184 // platforms that do not have standard IEEE numerics. For example,
185 // S/390 doubles have an exponent range of -78 to +75. For the
186 // following #if statements to work, float.h must define
187 // DBL_MAX_10_EXP to be a compile-time constant.
189 // This section may be expanded as needed.
191 #if DBL_MAX_10_EXP > 300
192 double val
[] = { 0.01234, 123456789, 1.23e300
, -3.141592653e-271 };
193 int32_t val_length
= (int32_t)(sizeof(val
) / sizeof(val
[0]));
194 const char* valFormat
[] =
197 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
199 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
201 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
203 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
207 0.01234, 123460000, 1.23E300
, -3.1416E-271,
208 0.01234, 123460000, 1.23E300
, -3.1416E-271,
209 0.01234, 123456800, 1.23E300
, -3.141593E-271,
210 0.01234, 123500000, 1.23E300
, -3.142E-271,
212 #elif DBL_MAX_10_EXP > 70
213 double val
[] = { 0.01234, 123456789, 1.23e70
, -3.141592653e-71 };
214 int32_t val_length
= sizeof(val
) / sizeof(val
[0]);
218 "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
220 "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
222 "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
224 "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
228 0.01234, 123460000, 1.23E70
, -3.1416E-71,
229 0.01234, 123460000, 1.23E70
, -3.1416E-71,
230 0.01234, 123456800, 1.23E70
, -3.141593E-71,
231 0.01234, 123500000, 1.23E70
, -3.142E-71,
234 // Don't test double conversion
236 int32_t val_length
= 0;
237 char** valFormat
= 0;
238 double* valParse
= 0;
239 logln("Warning: Skipping double conversion tests");
242 int32_t lval
[] = { 0, -1, 1, 123456789 };
243 int32_t lval_length
= (int32_t)(sizeof(lval
) / sizeof(lval
[0]));
244 const char* lvalFormat
[] =
247 "0E0", "-1E0", "1E0", "1.2346E8",
249 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
251 "0E000", "-1E000", "1E000", "123.4568E006",
253 "0E0", "[1E0]", "1E0", "1.235E8"
255 int32_t lvalParse
[] =
262 int32_t ival
= 0, ilval
= 0;
263 for (int32_t p
=0; p
<pat_length
; ++p
)
265 DecimalFormat
fmt(pat
[p
], sym
, status
);
266 if (U_FAILURE(status
)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
267 UnicodeString pattern
;
268 logln((UnicodeString
)"Pattern \"" + pat
[p
] + "\" -toPattern-> \"" +
269 fmt
.toPattern(pattern
) + "\"");
271 for (v
=0; v
<val_length
; ++v
)
273 UnicodeString s
; (*(NumberFormat
*)&fmt
).format(val
[v
], s
);
274 logln((UnicodeString
)" " + val
[v
] + " -format-> " + s
);
275 if (s
!= valFormat
[v
+ival
])
276 errln((UnicodeString
)"FAIL: Expected " + valFormat
[v
+ival
]);
278 ParsePosition
pos(0);
280 fmt
.parse(s
, af
, pos
);
282 UBool useEpsilon
= FALSE
;
283 if (af
.getType() == Formattable::kLong
)
285 else if (af
.getType() == Formattable::kDouble
) {
287 #if defined(OS390) || defined(OS400)
288 // S/390 will show a failure like this:
289 //| -3.141592652999999e-271 -format-> -3.1416E-271
290 //| -parse-> -3.1416e-271
291 //| FAIL: Expected -3.141599999999999e-271
292 // To compensate, we use an epsilon-based equality
293 // test on S/390 only. We don't want to do this in
294 // general because it's less exacting.
299 errln((UnicodeString
)"FAIL: Non-numeric Formattable returned");
302 if (pos
.getIndex() == s
.length())
304 logln((UnicodeString
)" -parse-> " + a
);
305 // Use epsilon comparison as necessary
307 (uprv_fabs(a
- valParse
[v
+ival
]) / a
> (2*DBL_EPSILON
))) ||
308 (!useEpsilon
&& a
!= valParse
[v
+ival
]))
310 errln((UnicodeString
)"FAIL: Expected " + valParse
[v
+ival
]);
314 errln((UnicodeString
)"FAIL: Partial parse (" + pos
.getIndex() + " chars) -> " + a
);
315 errln((UnicodeString
)" should be (" + s
.length() + " chars) -> " + valParse
[v
+ival
]);
318 for (v
=0; v
<lval_length
; ++v
)
321 (*(NumberFormat
*)&fmt
).format(lval
[v
], s
);
322 logln((UnicodeString
)" " + lval
[v
] + "L -format-> " + s
);
323 if (s
!= lvalFormat
[v
+ilval
])
324 errln((UnicodeString
)"ERROR: Expected " + lvalFormat
[v
+ilval
] + " Got: " + s
);
326 ParsePosition
pos(0);
328 fmt
.parse(s
, af
, pos
);
329 if (af
.getType() == Formattable::kLong
||
330 af
.getType() == Formattable::kInt64
) {
331 UErrorCode status
= U_ZERO_ERROR
;
332 int32_t a
= af
.getLong(status
);
333 if (pos
.getIndex() == s
.length())
335 logln((UnicodeString
)" -parse-> " + a
);
336 if (a
!= lvalParse
[v
+ilval
])
337 errln((UnicodeString
)"FAIL: Expected " + lvalParse
[v
+ilval
]);
340 errln((UnicodeString
)"FAIL: Partial parse (" + pos
.getIndex() + " chars) -> " + a
);
343 errln((UnicodeString
)"FAIL: Non-long Formattable returned for " + s
344 + " Double: " + af
.getDouble()
345 + ", Long: " + af
.getLong());
348 ilval
+= lval_length
;
353 NumberFormatTest::TestScientific2() {
355 UErrorCode status
= U_ZERO_ERROR
;
356 DecimalFormat
* fmt
= (DecimalFormat
*)NumberFormat::createCurrencyInstance("en_US", status
);
357 if (U_SUCCESS(status
)) {
359 expect(*fmt
, num
, "$12.34");
360 fmt
->setScientificNotation(TRUE
);
361 expect(*fmt
, num
, "$1.23E1");
362 fmt
->setScientificNotation(FALSE
);
363 expect(*fmt
, num
, "$12.34");
369 NumberFormatTest::TestScientificGrouping() {
371 UErrorCode status
= U_ZERO_ERROR
;
372 DecimalFormat
fmt("##0.00E0",status
);
373 if (U_SUCCESS(status
)) {
374 expect(fmt
, .01234, "12.3E-3");
375 expect(fmt
, .1234, "123E-3");
376 expect(fmt
, 1.234, "1.23E0");
377 expect(fmt
, 12.34, "12.3E0");
378 expect(fmt
, 123.4, "123E0");
379 expect(fmt
, 1234., "1.23E3");
383 static void setFromString(DigitList
& dl
, const char* str
) {
385 UBool decimalSet
= FALSE
;
387 while ((c
= *str
++)) {
389 dl
.fIsPositive
= FALSE
;
390 } else if (c
== '+') {
391 dl
.fIsPositive
= TRUE
;
392 } else if (c
== '.') {
393 dl
.fDecimalAt
= dl
.fCount
;
400 dl
.fDecimalAt
= dl
.fCount
;
405 NumberFormatTest::TestInt64() {
406 UErrorCode status
= U_ZERO_ERROR
;
407 DecimalFormat
fmt("#.#E0",status
);
408 fmt
.setMaximumFractionDigits(20);
409 if (U_SUCCESS(status
)) {
410 expect(fmt
, (Formattable
)(int64_t)0, "0E0");
411 expect(fmt
, (Formattable
)(int64_t)-1, "-1E0");
412 expect(fmt
, (Formattable
)(int64_t)1, "1E0");
413 expect(fmt
, (Formattable
)(int64_t)2147483647, "2.147483647E9");
414 expect(fmt
, (Formattable
)((int64_t)-2147483647-1), "-2.147483648E9");
415 expect(fmt
, (Formattable
)(int64_t)U_INT64_MAX
, "9.223372036854775807E18");
416 expect(fmt
, (Formattable
)(int64_t)U_INT64_MIN
, "-9.223372036854775808E18");
419 // also test digitlist
420 int64_t int64max
= U_INT64_MAX
;
421 int64_t int64min
= U_INT64_MIN
;
422 const char* int64maxstr
= "9223372036854775807";
423 const char* int64minstr
= "-9223372036854775808";
424 UnicodeString
fail("fail: ");
426 // test max int64 value
428 setFromString(dl
, int64maxstr
);
430 if (!dl
.fitsIntoInt64(FALSE
)) {
431 errln(fail
+ int64maxstr
+ " didn't fit");
433 int64_t int64Value
= dl
.getInt64();
434 if (int64Value
!= int64max
) {
435 errln(fail
+ int64maxstr
);
438 int64Value
= dl
.getInt64();
439 if (int64Value
!= int64max
) {
440 errln(fail
+ int64maxstr
);
443 // test negative of max int64 value (1 shy of min int64 value)
444 dl
.fIsPositive
= FALSE
;
446 if (!dl
.fitsIntoInt64(FALSE
)) {
447 errln(fail
+ "-" + int64maxstr
+ " didn't fit");
449 int64_t int64Value
= dl
.getInt64();
450 if (int64Value
!= -int64max
) {
451 errln(fail
+ "-" + int64maxstr
);
454 int64Value
= dl
.getInt64();
455 if (int64Value
!= -int64max
) {
456 errln(fail
+ "-" + int64maxstr
);
459 // test min int64 value
460 setFromString(dl
, int64minstr
);
462 if (!dl
.fitsIntoInt64(FALSE
)) {
463 errln(fail
+ "-" + int64minstr
+ " didn't fit");
465 int64_t int64Value
= dl
.getInt64();
466 if (int64Value
!= int64min
) {
467 errln(fail
+ int64minstr
);
470 int64Value
= dl
.getInt64();
471 if (int64Value
!= int64min
) {
472 errln(fail
+ int64minstr
);
475 // test negative of min int 64 value (1 more than max int64 value)
476 dl
.fIsPositive
= TRUE
; // won't fit
478 if (dl
.fitsIntoInt64(FALSE
)) {
479 errln(fail
+ "-(" + int64minstr
+ ") didn't fit");
484 // -------------------------------------
486 // Test the handling of quotes
488 NumberFormatTest::TestQuotes(void)
490 UErrorCode status
= U_ZERO_ERROR
;
492 DecimalFormatSymbols
*sym
= new DecimalFormatSymbols(Locale::getUS(), status
);
493 pat
= new UnicodeString("a'fo''o'b#");
494 DecimalFormat
*fmt
= new DecimalFormat(*pat
, *sym
, status
);
496 ((NumberFormat
*)fmt
)->format((int32_t)123, s
);
497 logln((UnicodeString
)"Pattern \"" + *pat
+ "\"");
498 logln((UnicodeString
)" Format 123 -> " + escape(s
));
499 if (!(s
=="afo'ob123"))
500 errln((UnicodeString
)"FAIL: Expected afo'ob123");
506 pat
= new UnicodeString("a''b#");
507 fmt
= new DecimalFormat(*pat
, *sym
, status
);
508 ((NumberFormat
*)fmt
)->format((int32_t)123, s
);
509 logln((UnicodeString
)"Pattern \"" + *pat
+ "\"");
510 logln((UnicodeString
)" Format 123 -> " + escape(s
));
512 errln((UnicodeString
)"FAIL: Expected a'b123");
519 * Test the handling of the currency symbol in patterns.
522 NumberFormatTest::TestCurrencySign(void)
524 UErrorCode status
= U_ZERO_ERROR
;
525 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols(Locale::getUS(), status
);
527 UChar currency
= 0x00A4;
528 // "\xA4#,##0.00;-\xA4#,##0.00"
529 pat
.append(currency
).append("#,##0.00;-").
530 append(currency
).append("#,##0.00");
531 DecimalFormat
*fmt
= new DecimalFormat(pat
, *sym
, status
);
532 UnicodeString s
; ((NumberFormat
*)fmt
)->format(1234.56, s
);
534 logln((UnicodeString
)"Pattern \"" + fmt
->toPattern(pat
) + "\"");
535 logln((UnicodeString
)" Format " + 1234.56 + " -> " + escape(s
));
536 if (s
!= "$1,234.56") errln((UnicodeString
)"FAIL: Expected $1,234.56");
538 ((NumberFormat
*)fmt
)->format(- 1234.56, s
);
539 logln((UnicodeString
)" Format " + (-1234.56) + " -> " + escape(s
));
540 if (s
!= "-$1,234.56") errln((UnicodeString
)"FAIL: Expected -$1,234.56");
543 // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
544 pat
.append(currency
).append(currency
).
545 append(" #,##0.00;").
546 append(currency
).append(currency
).
547 append(" -#,##0.00");
548 fmt
= new DecimalFormat(pat
, *sym
, status
);
550 ((NumberFormat
*)fmt
)->format(1234.56, s
);
551 logln((UnicodeString
)"Pattern \"" + fmt
->toPattern(pat
) + "\"");
552 logln((UnicodeString
)" Format " + 1234.56 + " -> " + escape(s
));
553 if (s
!= "USD 1,234.56") errln((UnicodeString
)"FAIL: Expected USD 1,234.56");
555 ((NumberFormat
*)fmt
)->format(-1234.56, s
);
556 logln((UnicodeString
)" Format " + (-1234.56) + " -> " + escape(s
));
557 if (s
!= "USD -1,234.56") errln((UnicodeString
)"FAIL: Expected USD -1,234.56");
560 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
563 // -------------------------------------
565 static UChar
toHexString(int32_t i
) { return (UChar
)(i
+ (i
< 10 ? 0x30 : (0x41 - 10))); }
568 NumberFormatTest::escape(UnicodeString
& s
)
571 for (int32_t i
=0; i
<s
.length(); ++i
)
573 UChar c
= s
[(int32_t)i
];
574 if (c
<= (UChar
)0x7F) buf
+= c
;
576 buf
+= (UChar
)0x5c; buf
+= (UChar
)0x55;
577 buf
+= toHexString((c
& 0xF000) >> 12);
578 buf
+= toHexString((c
& 0x0F00) >> 8);
579 buf
+= toHexString((c
& 0x00F0) >> 4);
580 buf
+= toHexString(c
& 0x000F);
587 // -------------------------------------
588 static const char* testCases
[][2]= {
589 /* locale ID */ /* expected */
590 {"ca_ES_PREEURO", "\\u20A7 1.150" },
591 {"de_LU_PREEURO", "1,150 F" },
592 {"el_GR_PREEURO", "1.150,50 \\u0394\\u03C1\\u03C7" },
593 {"en_BE_PREEURO", "1.150,50 BF" },
594 {"es_ES_PREEURO", "1.150 \\u20A7" },
595 {"eu_ES_PREEURO", "\\u20A7 1.150" },
596 {"gl_ES_PREEURO", "\\u20A7 1.150" },
597 {"it_IT_PREEURO", "\\u20A4 1.150" },
598 {"pt_PT_PREEURO", "1,150$50 Esc."}
601 * Test localized currency patterns.
604 NumberFormatTest::TestCurrency(void)
606 UErrorCode status
= U_ZERO_ERROR
;
607 NumberFormat
* currencyFmt
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
608 UnicodeString s
; currencyFmt
->format(1.50, s
);
609 logln((UnicodeString
)"Un pauvre ici a..........." + s
);
611 errln((UnicodeString
)"FAIL: Expected 1,50 $");
615 int len
= uloc_canonicalize("de_DE_PREEURO", loc
, 256, &status
);
616 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
),status
);
617 currencyFmt
->format(1.50, s
);
618 logln((UnicodeString
)"Un pauvre en Allemagne a.." + s
);
620 errln((UnicodeString
)"FAIL: Expected 1,50 DM");
623 len
= uloc_canonicalize("fr_FR_PREEURO", loc
, 256, &status
);
624 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
625 currencyFmt
->format(1.50, s
);
626 logln((UnicodeString
)"Un pauvre en France a....." + s
);
628 errln((UnicodeString
)"FAIL: Expected 1,50 F");
630 if (U_FAILURE(status
))
631 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
633 for(int i
=0; i
< (int)(sizeof(testCases
)/sizeof(testCases
[i
])); i
++){
634 status
= U_ZERO_ERROR
;
635 const char *localeID
= testCases
[i
][0];
636 UnicodeString
expected(testCases
[i
][1]);
637 expected
= expected
.unescape();
640 uloc_canonicalize(localeID
, loc
, 256, &status
);
641 currencyFmt
= NumberFormat::createCurrencyInstance(Locale(loc
), status
);
642 if(U_FAILURE(status
)){
643 errln("Could not create currency formatter for locale %s",localeID
);
646 currencyFmt
->format(1150.50, s
);
648 errln(UnicodeString("FAIL: Expected: ")+expected
649 + UnicodeString(" Got: ") + s
650 + UnicodeString( " for locale: ")+ UnicodeString(localeID
) );
652 if (U_FAILURE(status
)){
653 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
659 // -------------------------------------
662 * Test the Currency object handling, new as of ICU 2.2.
664 void NumberFormatTest::TestCurrencyObject() {
665 UErrorCode ec
= U_ZERO_ERROR
;
667 NumberFormat::createCurrencyInstance(Locale::getUS(), ec
);
670 errln("FAIL: getCurrencyInstance(US)");
675 Locale
null("", "", "");
677 expectCurrency(*fmt
, null
, 1234.56, "$1,234.56");
679 expectCurrency(*fmt
, Locale::getFrance(),
680 1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
682 expectCurrency(*fmt
, Locale::getJapan(),
683 1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
685 expectCurrency(*fmt
, Locale("fr", "CH", ""),
686 1234.56, "SwF1,234.55"); // 0.05 rounding
688 expectCurrency(*fmt
, Locale::getUS(),
689 1234.56, "$1,234.56");
692 fmt
= NumberFormat::createCurrencyInstance(Locale::getFrance(), ec
);
695 errln("FAIL: getCurrencyInstance(FRANCE)");
700 expectCurrency(*fmt
, null
, 1234.56, CharsToUnicodeString("1 234,56 \\u20AC"));
702 expectCurrency(*fmt
, Locale::getJapan(),
703 1234.56, CharsToUnicodeString("1 235 \\u00A5")); // Yen
705 expectCurrency(*fmt
, Locale("fr", "CH", ""),
706 1234.56, "1 234,55 sFr."); // 0.05 rounding
708 expectCurrency(*fmt
, Locale::getUS(),
709 1234.56, "1 234,56 $");
711 expectCurrency(*fmt
, Locale::getFrance(),
712 1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); // Euro
717 // -------------------------------------
720 * Do rudimentary testing of parsing.
723 NumberFormatTest::TestParse(void)
725 UErrorCode status
= U_ZERO_ERROR
;
726 UnicodeString
arg("0");
727 DecimalFormat
* format
= new DecimalFormat("00", status
);
729 Formattable n
; format
->parse(arg
, n
, status
);
730 logln((UnicodeString
)"parse(" + arg
+ ") = " + n
.getLong());
731 if (n
.getType() != Formattable::kLong
||
732 n
.getLong() != 0) errln((UnicodeString
)"FAIL: Expected 0");
734 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
736 //catch(Exception e) {
737 // errln((UnicodeString)"Exception caught: " + e);
741 // -------------------------------------
744 * Test proper rounding by the format method.
747 NumberFormatTest::TestRounding487(void)
749 UErrorCode status
= U_ZERO_ERROR
;
750 NumberFormat
*nf
= NumberFormat::createInstance(status
);
751 roundingTest(*nf
, 0.00159999, 4, "0.0016");
752 roundingTest(*nf
, 0.00995, 4, "0.01");
754 roundingTest(*nf
, 12.3995, 3, "12.4");
756 roundingTest(*nf
, 12.4999, 0, "12");
757 roundingTest(*nf
, - 19.5, 0, "-20");
759 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
763 * Test the functioning of the secondary grouping value.
765 void NumberFormatTest::TestSecondaryGrouping(void) {
766 UErrorCode status
= U_ZERO_ERROR
;
767 DecimalFormatSymbols
US(Locale::getUS(), status
);
768 CHECK(status
, "DecimalFormatSymbols ct");
770 DecimalFormat
f("#,##,###", US
, status
);
771 CHECK(status
, "DecimalFormat ct");
773 expect2(f
, (int32_t)123456789L, "12,34,56,789");
774 expectPat(f
, "#,##,###");
775 f
.applyPattern("#,###", status
);
776 CHECK(status
, "applyPattern");
778 f
.setSecondaryGroupingSize(4);
779 expect2(f
, (int32_t)123456789L, "12,3456,789");
780 expectPat(f
, "#,####,###");
781 NumberFormat
*g
= NumberFormat::createInstance(Locale("hi", "IN"), status
);
782 CHECK(status
, "createInstance(hi_IN)");
785 int32_t l
= (int32_t)1876543210L;
788 // expect "1,87,65,43,210", but with Hindi digits
791 if (out
.length() != 14) {
794 for (int32_t i
=0; i
<out
.length(); ++i
) {
795 UBool expectGroup
= FALSE
;
804 // Later -- fix this to get the actual grouping
805 // character from the resource bundle.
806 UBool isGroup
= (out
.charAt(i
) == 0x002C);
807 if (isGroup
!= expectGroup
) {
814 errln((UnicodeString
)"FAIL Expected " + l
+
815 " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
818 logln((UnicodeString
)"Ok " + l
+
824 void NumberFormatTest::TestWhiteSpaceParsing(void) {
825 UErrorCode ec
= U_ZERO_ERROR
;
826 DecimalFormatSymbols
US(Locale::getUS(), ec
);
827 DecimalFormat
fmt("a b#0c ", US
, ec
);
829 errln("FAIL: Constructor");
833 expect(fmt
, "a b1234c ", n
);
834 expect(fmt
, "a b1234c ", n
);
838 * Test currencies whose display name is a ChoiceFormat.
840 void NumberFormatTest::TestComplexCurrency() {
841 UErrorCode ec
= U_ZERO_ERROR
;
842 Locale
loc("en", "IN", "");
843 NumberFormat
* fmt
= NumberFormat::createCurrencyInstance(loc
, ec
);
845 expect2(*fmt
, 1.0, "Re. 1.00");
846 // Use .00392625 because that's 2^-8. Any value less than 0.005 is fine.
847 expect(*fmt
, 1.00390625, "Re. 1.00"); // tricky
848 expect2(*fmt
, 12345678.0, "Rs. 1,23,45,678.00");
849 expect2(*fmt
, 0.5, "Rs. 0.50");
850 expect2(*fmt
, -1.0, "-Re. 1.00");
851 expect2(*fmt
, -10.0, "-Rs. 10.00");
853 errln("FAIL: getCurrencyInstance(en_IN)");
858 // -------------------------------------
861 NumberFormatTest::roundingTest(NumberFormat
& nf
, double x
, int32_t maxFractionDigits
, const char* expected
)
863 nf
.setMaximumFractionDigits(maxFractionDigits
);
864 UnicodeString out
; nf
.format(x
, out
);
865 logln((UnicodeString
)"" + x
+ " formats with " + maxFractionDigits
+ " fractional digits to " + out
);
866 if (!(out
==expected
)) errln((UnicodeString
)"FAIL: Expected " + expected
);
870 * Upgrade to alphaWorks
872 void NumberFormatTest::TestExponent(void) {
873 UErrorCode status
= U_ZERO_ERROR
;
874 DecimalFormatSymbols
US(Locale::getUS(), status
);
875 CHECK(status
, "DecimalFormatSymbols constructor");
876 DecimalFormat
fmt1(UnicodeString("0.###E0"), US
, status
);
877 CHECK(status
, "DecimalFormat(0.###E0)");
878 DecimalFormat
fmt2(UnicodeString("0.###E+0"), US
, status
);
879 CHECK(status
, "DecimalFormat(0.###E+0)");
881 expect2(fmt1
, n
, "1.234E3");
882 expect2(fmt2
, n
, "1.234E+3");
883 expect(fmt1
, "1.234E+3", n
); // Either format should parse "E+3"
887 * Upgrade to alphaWorks
889 void NumberFormatTest::TestScientific(void) {
890 UErrorCode status
= U_ZERO_ERROR
;
891 DecimalFormatSymbols
US(Locale::getUS(), status
);
892 CHECK(status
, "DecimalFormatSymbols constructor");
894 // Test pattern round-trip
895 const char* PAT
[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
896 "0.###E0;[0.###E0]" };
897 int32_t PAT_length
= (int32_t)(sizeof(PAT
) / sizeof(PAT
[0]));
899 // min int, max int, min frac, max frac
901 1, 1, 0, 4, // "0.####E0"
902 2, 2, 3, 3, // "00.000E00"
903 1, 3, 0, 4, // "##0.####E000"
904 1, 1, 0, 3, // "0.###E0;[0.###E0]"
906 for (int32_t i
=0; i
<PAT_length
; ++i
) {
907 UnicodeString
pat(PAT
[i
]);
908 DecimalFormat
df(pat
, US
, status
);
909 CHECK(status
, "DecimalFormat constructor");
913 logln(UnicodeString("Ok Pattern rt \"") +
917 errln(UnicodeString("FAIL Pattern rt \"") +
921 // Make sure digit counts match what we expect
922 if (df
.getMinimumIntegerDigits() != DIGITS
[4*i
] ||
923 df
.getMaximumIntegerDigits() != DIGITS
[4*i
+1] ||
924 df
.getMinimumFractionDigits() != DIGITS
[4*i
+2] ||
925 df
.getMaximumFractionDigits() != DIGITS
[4*i
+3]) {
926 errln(UnicodeString("FAIL \"" + pat
+
927 "\" min/max int; min/max frac = ") +
928 df
.getMinimumIntegerDigits() + "/" +
929 df
.getMaximumIntegerDigits() + ";" +
930 df
.getMinimumFractionDigits() + "/" +
931 df
.getMaximumFractionDigits() + ", expect " +
933 DIGITS
[4*i
+1] + ";" +
934 DIGITS
[4*i
+2] + "/" +
940 // Test the constructor for default locale. We have to
941 // manually set the default locale, as there is no
942 // guarantee that the default locale has the same
943 // scientific format.
944 Locale def
= Locale::getDefault();
945 Locale::setDefault(Locale::getUS(), status
);
946 expect2(NumberFormat::createScientificInstance(status
),
948 "1.2345678901E4", status
);
949 Locale::setDefault(def
, status
);
951 expect2(new DecimalFormat("#E0", US
, status
),
954 expect(new DecimalFormat("0E0", US
, status
),
957 expect2(NumberFormat::createScientificInstance(Locale::getUS(), status
),
959 "1.2345678901E4", status
);
960 expect(new DecimalFormat("##0.###E0", US
, status
),
963 expect(new DecimalFormat("##0.###E0", US
, status
),
966 expect2(new DecimalFormat("##0.####E0", US
, status
),
969 expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status
),
971 "1,2345678901E4", status
);
972 expect(new DecimalFormat("##0.####E0", US
, status
),
974 "789.12E-9", status
);
975 expect2(new DecimalFormat("##0.####E0", US
, status
),
978 expect(new DecimalFormat(".###E0", US
, status
),
981 expect2(new DecimalFormat(".###E0", US
, status
),
985 expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
986 new DecimalFormat("##E0", US),
987 new DecimalFormat("####E0", US),
988 new DecimalFormat("0E0", US),
989 new DecimalFormat("00E0", US),
990 new DecimalFormat("000E0", US),
993 new String[] { "4.5678E7",
1002 ! Unroll this test into individual tests below...
1005 expect2(new DecimalFormat("#E0", US
, status
),
1006 (int32_t) 45678000, "4.5678E7", status
);
1007 expect2(new DecimalFormat("##E0", US
, status
),
1008 (int32_t) 45678000, "45.678E6", status
);
1009 expect2(new DecimalFormat("####E0", US
, status
),
1010 (int32_t) 45678000, "4567.8E4", status
);
1011 expect(new DecimalFormat("0E0", US
, status
),
1012 (int32_t) 45678000, "5E7", status
);
1013 expect(new DecimalFormat("00E0", US
, status
),
1014 (int32_t) 45678000, "46E6", status
);
1015 expect(new DecimalFormat("000E0", US
, status
),
1016 (int32_t) 45678000, "457E5", status
);
1018 expect(new DecimalFormat("###E0", US, status),
1019 new Object[] { new Double(0.0000123), "12.3E-6",
1020 new Double(0.000123), "123E-6",
1021 new Double(0.00123), "1.23E-3",
1022 new Double(0.0123), "12.3E-3",
1023 new Double(0.123), "123E-3",
1024 new Double(1.23), "1.23E0",
1025 new Double(12.3), "12.3E0",
1026 new Double(123), "123E0",
1027 new Double(1230), "1.23E3",
1030 ! Unroll this test into individual tests below...
1033 expect2(new DecimalFormat("###E0", US
, status
),
1034 0.0000123, "12.3E-6", status
);
1035 expect2(new DecimalFormat("###E0", US
, status
),
1036 0.000123, "123E-6", status
);
1037 expect2(new DecimalFormat("###E0", US
, status
),
1038 0.00123, "1.23E-3", status
);
1039 expect2(new DecimalFormat("###E0", US
, status
),
1040 0.0123, "12.3E-3", status
);
1041 expect2(new DecimalFormat("###E0", US
, status
),
1042 0.123, "123E-3", status
);
1043 expect2(new DecimalFormat("###E0", US
, status
),
1044 1.23, "1.23E0", status
);
1045 expect2(new DecimalFormat("###E0", US
, status
),
1046 12.3, "12.3E0", status
);
1047 expect2(new DecimalFormat("###E0", US
, status
),
1048 123.0, "123E0", status
);
1049 expect2(new DecimalFormat("###E0", US
, status
),
1050 1230.0, "1.23E3", status
);
1052 expect(new DecimalFormat("0.#E+00", US, status),
1053 new Object[] { new Double(0.00012), "1.2E-04",
1054 new Long(12000), "1.2E+04",
1057 ! Unroll this test into individual tests below...
1060 expect2(new DecimalFormat("0.#E+00", US
, status
),
1061 0.00012, "1.2E-04", status
);
1062 expect2(new DecimalFormat("0.#E+00", US
, status
),
1063 (int32_t) 12000, "1.2E+04", status
);
1067 * Upgrade to alphaWorks
1069 void NumberFormatTest::TestPad(void) {
1070 UErrorCode status
= U_ZERO_ERROR
;
1071 DecimalFormatSymbols
US(Locale::getUS(), status
);
1072 CHECK(status
, "DecimalFormatSymbols constructor");
1074 expect2(new DecimalFormat("*^##.##", US
, status
),
1075 int32_t(0), "^^^^0", status
);
1076 expect2(new DecimalFormat("*^##.##", US
, status
),
1077 -1.3, "^-1.3", status
);
1078 expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US
, status
),
1079 int32_t(0), "0.0E0______ g-m/s^2", status
);
1080 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US
, status
),
1081 1.0/3, "333.333E-3_ g-m/s^2", status
);
1082 expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US
, status
),
1083 int32_t(0), "0.0______ g-m/s^2", status
);
1084 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US
, status
),
1085 1.0/3, "0.33333__ g-m/s^2", status
);
1087 // Test padding before a sign
1088 const char *formatStr
= "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
1089 expect2(new DecimalFormat(formatStr
, US
, status
),
1090 int32_t(-10), "xxxxxxxxxx(10.0)", status
);
1091 expect2(new DecimalFormat(formatStr
, US
, status
),
1092 int32_t(-1000),"xxxxxxx(1,000.0)", status
);
1093 expect2(new DecimalFormat(formatStr
, US
, status
),
1094 int32_t(-1000000),"xxx(1,000,000.0)", status
);
1095 expect2(new DecimalFormat(formatStr
, US
, status
),
1096 -100.37, "xxxxxxxx(100.37)", status
);
1097 expect2(new DecimalFormat(formatStr
, US
, status
),
1098 -10456.37, "xxxxx(10,456.37)", status
);
1099 expect2(new DecimalFormat(formatStr
, US
, status
),
1100 -1120456.37, "xx(1,120,456.37)", status
);
1101 expect2(new DecimalFormat(formatStr
, US
, status
),
1102 -112045600.37, "(112,045,600.37)", status
);
1103 expect2(new DecimalFormat(formatStr
, US
, status
),
1104 -1252045600.37,"(1,252,045,600.37)", status
);
1106 expect2(new DecimalFormat(formatStr
, US
, status
),
1107 int32_t(10), "xxxxxxxxxxxx10.0", status
);
1108 expect2(new DecimalFormat(formatStr
, US
, status
),
1109 int32_t(1000),"xxxxxxxxx1,000.0", status
);
1110 expect2(new DecimalFormat(formatStr
, US
, status
),
1111 int32_t(1000000),"xxxxx1,000,000.0", status
);
1112 expect2(new DecimalFormat(formatStr
, US
, status
),
1113 100.37, "xxxxxxxxxx100.37", status
);
1114 expect2(new DecimalFormat(formatStr
, US
, status
),
1115 10456.37, "xxxxxxx10,456.37", status
);
1116 expect2(new DecimalFormat(formatStr
, US
, status
),
1117 1120456.37, "xxxx1,120,456.37", status
);
1118 expect2(new DecimalFormat(formatStr
, US
, status
),
1119 112045600.37, "xx112,045,600.37", status
);
1120 expect2(new DecimalFormat(formatStr
, US
, status
),
1121 10252045600.37,"10,252,045,600.37", status
);
1124 // Test padding between a sign and a number
1125 const char *formatStr2
= "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
1126 expect2(new DecimalFormat(formatStr2
, US
, status
),
1127 int32_t(-10), "(10.0xxxxxxxxxx)", status
);
1128 expect2(new DecimalFormat(formatStr2
, US
, status
),
1129 int32_t(-1000),"(1,000.0xxxxxxx)", status
);
1130 expect2(new DecimalFormat(formatStr2
, US
, status
),
1131 int32_t(-1000000),"(1,000,000.0xxx)", status
);
1132 expect2(new DecimalFormat(formatStr2
, US
, status
),
1133 -100.37, "(100.37xxxxxxxx)", status
);
1134 expect2(new DecimalFormat(formatStr2
, US
, status
),
1135 -10456.37, "(10,456.37xxxxx)", status
);
1136 expect2(new DecimalFormat(formatStr2
, US
, status
),
1137 -1120456.37, "(1,120,456.37xx)", status
);
1138 expect2(new DecimalFormat(formatStr2
, US
, status
),
1139 -112045600.37, "(112,045,600.37)", status
);
1140 expect2(new DecimalFormat(formatStr2
, US
, status
),
1141 -1252045600.37,"(1,252,045,600.37)", status
);
1143 expect2(new DecimalFormat(formatStr2
, US
, status
),
1144 int32_t(10), "10.0xxxxxxxxxxxx", status
);
1145 expect2(new DecimalFormat(formatStr2
, US
, status
),
1146 int32_t(1000),"1,000.0xxxxxxxxx", status
);
1147 expect2(new DecimalFormat(formatStr2
, US
, status
),
1148 int32_t(1000000),"1,000,000.0xxxxx", status
);
1149 expect2(new DecimalFormat(formatStr2
, US
, status
),
1150 100.37, "100.37xxxxxxxxxx", status
);
1151 expect2(new DecimalFormat(formatStr2
, US
, status
),
1152 10456.37, "10,456.37xxxxxxx", status
);
1153 expect2(new DecimalFormat(formatStr2
, US
, status
),
1154 1120456.37, "1,120,456.37xxxx", status
);
1155 expect2(new DecimalFormat(formatStr2
, US
, status
),
1156 112045600.37, "112,045,600.37xx", status
);
1157 expect2(new DecimalFormat(formatStr2
, US
, status
),
1158 10252045600.37,"10,252,045,600.37", status
);
1160 //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
1161 DecimalFormat
fmt("#", US
, status
);
1162 CHECK(status
, "DecimalFormat constructor");
1163 UnicodeString
padString("P");
1164 fmt
.setPadCharacter(padString
);
1165 expectPad(fmt
, "*P##.##", DecimalFormat::kPadBeforePrefix
, 5, padString
);
1166 fmt
.setPadCharacter((UnicodeString
)"^");
1167 expectPad(fmt
, "*^#", DecimalFormat::kPadBeforePrefix
, 1, (UnicodeString
)"^");
1168 //commented untill implementation is complete
1169 /* fmt.setPadCharacter((UnicodeString)"^^^");
1170 expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
1172 padString.append((UChar)0x0061);
1173 padString.append((UChar)0x0302);
1174 fmt.setPadCharacter(padString);
1175 UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
1176 UnicodeString pattern(patternChars);
1177 expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
1183 * Upgrade to alphaWorks
1185 void NumberFormatTest::TestPatterns2(void) {
1186 UErrorCode status
= U_ZERO_ERROR
;
1187 DecimalFormatSymbols
US(Locale::getUS(), status
);
1188 CHECK(status
, "DecimalFormatSymbols constructor");
1190 DecimalFormat
fmt("#", US
, status
);
1191 CHECK(status
, "DecimalFormat constructor");
1193 UChar hat
= 0x005E; /*^*/
1195 expectPad(fmt
, "*^#", DecimalFormat::kPadBeforePrefix
, 1, hat
);
1196 expectPad(fmt
, "$*^#", DecimalFormat::kPadAfterPrefix
, 2, hat
);
1197 expectPad(fmt
, "#*^", DecimalFormat::kPadBeforeSuffix
, 1, hat
);
1198 expectPad(fmt
, "#$*^", DecimalFormat::kPadAfterSuffix
, 2, hat
);
1199 expectPad(fmt
, "$*^$#", ILLEGAL
);
1200 expectPad(fmt
, "#$*^$", ILLEGAL
);
1201 expectPad(fmt
, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix
,
1202 12, (UChar
)0x0078 /*x*/);
1203 expectPad(fmt
, "''#0*x", DecimalFormat::kPadBeforeSuffix
,
1204 3, (UChar
)0x0078 /*x*/);
1205 expectPad(fmt
, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix
,
1206 10, (UChar
)0x0061 /*a*/);
1208 fmt
.applyPattern("AA#,##0.00ZZ", status
);
1209 CHECK(status
, "applyPattern");
1210 fmt
.setPadCharacter(hat
);
1212 fmt
.setFormatWidth(10);
1214 fmt
.setPadPosition(DecimalFormat::kPadBeforePrefix
);
1215 expectPat(fmt
, "*^AA#,##0.00ZZ");
1217 fmt
.setPadPosition(DecimalFormat::kPadBeforeSuffix
);
1218 expectPat(fmt
, "AA#,##0.00*^ZZ");
1220 fmt
.setPadPosition(DecimalFormat::kPadAfterSuffix
);
1221 expectPat(fmt
, "AA#,##0.00ZZ*^");
1224 UnicodeString
exp("AA*^#,##0.00ZZ", "");
1225 fmt
.setFormatWidth(12);
1226 fmt
.setPadPosition(DecimalFormat::kPadAfterPrefix
);
1227 expectPat(fmt
, exp
);
1229 fmt
.setFormatWidth(13);
1231 expectPat(fmt
, "AA*^##,##0.00ZZ");
1233 fmt
.setFormatWidth(14);
1235 expectPat(fmt
, "AA*^###,##0.00ZZ");
1237 fmt
.setFormatWidth(15);
1239 expectPat(fmt
, "AA*^####,##0.00ZZ"); // This is the interesting case
1241 fmt
.setFormatWidth(16);
1242 // 12 34567890123456
1243 expectPat(fmt
, "AA*^#,###,##0.00ZZ");
1246 void NumberFormatTest::TestSurrogateSupport(void) {
1247 UErrorCode status
= U_ZERO_ERROR
;
1248 DecimalFormatSymbols
custom(Locale::getUS(), status
);
1249 CHECK(status
, "DecimalFormatSymbols constructor");
1251 custom
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, "decimal");
1252 custom
.setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, "plus");
1253 custom
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, " minus ");
1254 custom
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, "exponent");
1256 UnicodeString
patternStr("*\\U00010000##.##", "");
1257 patternStr
= patternStr
.unescape();
1258 UnicodeString
expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
1259 expStr
= expStr
.unescape();
1260 expect2(new DecimalFormat(patternStr
, custom
, status
),
1261 int32_t(0), expStr
, status
);
1263 status
= U_ZERO_ERROR
;
1264 expect2(new DecimalFormat("*^##.##", custom
, status
),
1265 int32_t(0), "^^^^0", status
);
1266 status
= U_ZERO_ERROR
;
1267 expect2(new DecimalFormat("##.##", custom
, status
),
1268 -1.3, " minus 1decimal3", status
);
1269 status
= U_ZERO_ERROR
;
1270 expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom
, status
),
1271 int32_t(0), "0decimal0exponent0 g-m/s^2", status
);
1272 status
= U_ZERO_ERROR
;
1273 expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom
, status
),
1274 1.0/3, "333decimal333exponent minus 3 g-m/s^2", status
);
1275 status
= U_ZERO_ERROR
;
1276 expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom
, status
),
1277 int32_t(0), "0decimal0 g-m/s^2", status
);
1278 status
= U_ZERO_ERROR
;
1279 expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom
, status
),
1280 1.0/3, "0decimal33333 g-m/s^2", status
);
1282 UnicodeString
zero((UChar32
)0x10000);
1283 custom
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, zero
);
1284 expStr
= UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
1285 expStr
= expStr
.unescape();
1286 status
= U_ZERO_ERROR
;
1287 expect2(new DecimalFormat("##0.000", custom
, status
),
1288 1.25, expStr
, status
);
1290 custom
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, (UChar
)0x30);
1291 custom
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "units of money");
1292 custom
.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, "money separator");
1293 patternStr
= "0.00 \\u00A4' in your bank account'";
1294 patternStr
= patternStr
.unescape();
1295 expStr
= UnicodeString(" minus 20money separator00 units of money in your bank account", "");
1296 status
= U_ZERO_ERROR
;
1297 expect2(new DecimalFormat(patternStr
, custom
, status
),
1298 int32_t(-20), expStr
, status
);
1300 custom
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, "percent");
1301 patternStr
= "'You''ve lost ' -0.00 %' of your money today'";
1302 patternStr
= patternStr
.unescape();
1303 expStr
= UnicodeString(" minus You've lost minus 2000decimal00 percent of your money today", "");
1304 status
= U_ZERO_ERROR
;
1305 expect2(new DecimalFormat(patternStr
, custom
, status
),
1306 int32_t(-20), expStr
, status
);
1309 void NumberFormatTest::TestCurrencyPatterns(void) {
1310 int32_t i
, locCount
;
1311 const Locale
* locs
= NumberFormat::getAvailableLocales(locCount
);
1312 for (i
=0; i
<locCount
; ++i
) {
1313 UErrorCode ec
= U_ZERO_ERROR
;
1314 NumberFormat
* nf
= NumberFormat::createCurrencyInstance(locs
[i
], ec
);
1315 if (U_FAILURE(ec
)) {
1316 errln("FAIL: Can't create NumberFormat(%s) - %s", locs
[i
].getName(), u_errorName(ec
));
1318 // Make sure currency formats do not have a variable number
1319 // of fraction digits
1320 int32_t min
= nf
->getMinimumFractionDigits();
1321 int32_t max
= nf
->getMaximumFractionDigits();
1325 nf
->format(1.125, b
);
1326 errln((UnicodeString
)"FAIL: " + locs
[i
].getName() +
1327 " min fraction digits != max fraction digits; "
1328 "x 1.0 => " + escape(a
) +
1329 "; x 1.125 => " + escape(b
));
1332 // Make sure EURO currency formats have exactly 2 fraction digits
1333 if (nf
->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
1334 DecimalFormat
* df
= (DecimalFormat
*) nf
;
1335 if (u_strcmp(EUR
, df
->getCurrency()) == 0) {
1336 if (min
!= 2 || max
!= 2) {
1339 errln((UnicodeString
)"FAIL: " + locs
[i
].getName() +
1340 " is a EURO format but it does not have 2 fraction digits; "
1351 void NumberFormatTest::TestRegCurrency(void) {
1352 #if !UCONFIG_NO_SERVICE
1353 UErrorCode status
= U_ZERO_ERROR
;
1355 ucurr_forLocale("en_US", USD
, 4, &status
);
1357 ucurr_forLocale("ja_JP", YEN
, 4, &status
);
1359 static const UChar QQQ
[] = {0x51, 0x51, 0x51, 0};
1360 if(U_FAILURE(status
)) {
1361 errln("Unable to get currency for locale, error %s", u_errorName(status
));
1365 UCurrRegistryKey enkey
= ucurr_register(YEN
, "en_US", &status
);
1366 UCurrRegistryKey enUSEUROkey
= ucurr_register(QQQ
, "en_US_EURO", &status
);
1368 ucurr_forLocale("en_US", TMP
, 4, &status
);
1369 if (u_strcmp(YEN
, TMP
) != 0) {
1370 errln("FAIL: didn't return YEN registered for en_US");
1373 ucurr_forLocale("en_US_EURO", TMP
, 4, &status
);
1374 if (u_strcmp(QQQ
, TMP
) != 0) {
1375 errln("FAIL: didn't return QQQ for en_US_EURO");
1378 int32_t fallbackLen
= ucurr_forLocale("en_XX_BAR", TMP
, 4, &status
);
1380 errln("FAIL: tried to fallback en_XX_BAR");
1382 status
= U_ZERO_ERROR
; // reset
1384 if (!ucurr_unregister(enkey
, &status
)) {
1385 errln("FAIL: couldn't unregister enkey");
1388 ucurr_forLocale("en_US", TMP
, 4, &status
);
1389 if (u_strcmp(USD
, TMP
) != 0) {
1390 errln("FAIL: didn't return USD for en_US after unregister of en_US");
1392 status
= U_ZERO_ERROR
; // reset
1394 ucurr_forLocale("en_US_EURO", TMP
, 4, &status
);
1395 if (u_strcmp(QQQ
, TMP
) != 0) {
1396 errln("FAIL: didn't return QQQ for en_US_EURO after unregister of en_US");
1399 ucurr_forLocale("en_US_BLAH", TMP
, 4, &status
);
1400 if (u_strcmp(USD
, TMP
) != 0) {
1401 errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
1403 status
= U_ZERO_ERROR
; // reset
1405 if (!ucurr_unregister(enUSEUROkey
, &status
)) {
1406 errln("FAIL: couldn't unregister enUSEUROkey");
1409 ucurr_forLocale("en_US_EURO", TMP
, 4, &status
);
1410 if (u_strcmp(EUR
, TMP
) != 0) {
1411 errln("FAIL: didn't return EUR for en_US_EURO after unregister of en_US_EURO");
1413 status
= U_ZERO_ERROR
; // reset
1417 void NumberFormatTest::TestCurrencyNames(void) {
1418 // Do a basic check of getName()
1419 // USD { "US$", "US Dollar" } // 04/04/1792-
1420 UErrorCode ec
= U_ZERO_ERROR
;
1421 static const UChar USD
[] = {85, 83, 68, 0}; /*USD*/
1422 UBool isChoiceFormat
;
1424 // Warning: HARD-CODED LOCALE DATA in this test. If it fails, CHECK
1425 // THE LOCALE DATA before diving into the code.
1426 assertEquals("USD.getName(SYMBOL_NAME)",
1427 UnicodeString("US$"),
1428 UnicodeString(ucurr_getName(USD
, "en",
1430 &isChoiceFormat
, &len
, &ec
)));
1431 assertEquals("USD.getName(LONG_NAME)",
1432 UnicodeString("US Dollar"),
1433 UnicodeString(ucurr_getName(USD
, "en",
1435 &isChoiceFormat
, &len
, &ec
)));
1436 assertSuccess("ucurr_getName", ec
);
1438 // TODO add more tests later
1441 void NumberFormatTest::TestSymbolsWithBadLocale(void) {
1443 Locale
locBad("x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME");
1444 UErrorCode status
= U_ZERO_ERROR
;
1445 UnicodeString
intlCurrencySymbol((UChar
)0xa4);
1447 intlCurrencySymbol
.append((UChar
)0xa4);
1449 logln("Current locale is %s", Locale::getDefault().getName());
1450 Locale::setDefault(locBad
, status
);
1451 logln("Current locale is %s", Locale::getDefault().getName());
1452 DecimalFormatSymbols
mySymbols(status
);
1453 if (status
!= U_USING_FALLBACK_WARNING
) {
1454 errln("DecimalFormatSymbols should returned U_USING_FALLBACK_WARNING.");
1456 if (strcmp(mySymbols
.getLocale().getName(), locBad
.getName()) != 0) {
1457 errln("DecimalFormatSymbols does not have the right locale.");
1459 int symbolEnum
= (int)DecimalFormatSymbols::kDecimalSeparatorSymbol
;
1460 for (; symbolEnum
< (int)DecimalFormatSymbols::kFormatSymbolCount
; symbolEnum
++) {
1461 logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum
+ UnicodeString("] = ")
1462 + prettify(mySymbols
.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbolEnum
)));
1464 if (mySymbols
.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbolEnum
).length() == 0
1465 && symbolEnum
!= (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
)
1467 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum
);
1470 status
= U_ZERO_ERROR
;
1471 Locale::setDefault(locDefault
, status
);
1472 logln("Current locale is %s", Locale::getDefault().getName());
1476 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
1477 * behave the same, except for memory ownership semantics. (No
1478 * version of this test on Java, since Java has only one method.)
1480 void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
1481 UErrorCode ec
= U_ZERO_ERROR
;
1482 DecimalFormatSymbols
*sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
1483 if (U_FAILURE(ec
)) {
1484 errln("Fail: DecimalFormatSymbols constructor");
1488 UnicodeString
pat(" #,##0.00");
1489 pat
.insert(0, (UChar
)0x00A4);
1490 DecimalFormat
fmt(pat
, sym
, ec
);
1491 if (U_FAILURE(ec
)) {
1492 errln("Fail: DecimalFormat constructor");
1497 fmt
.format(2350.75, str
);
1498 if (str
== "$ 2,350.75") {
1501 errln("Fail: " + str
+ ", expected $ 2,350.75");
1504 sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
1505 if (U_FAILURE(ec
)) {
1506 errln("Fail: DecimalFormatSymbols constructor");
1510 sym
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "Q");
1511 fmt
.adoptDecimalFormatSymbols(sym
);
1514 fmt
.format(2350.75, str
);
1515 if (str
== "Q 2,350.75") {
1518 errln("Fail: adoptDecimalFormatSymbols -> " + str
+ ", expected Q 2,350.75");
1521 sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
1522 if (U_FAILURE(ec
)) {
1523 errln("Fail: DecimalFormatSymbols constructor");
1527 DecimalFormat
fmt2(pat
, sym
, ec
);
1528 if (U_FAILURE(ec
)) {
1529 errln("Fail: DecimalFormat constructor");
1533 DecimalFormatSymbols
sym2(Locale::getUS(), ec
);
1534 if (U_FAILURE(ec
)) {
1535 errln("Fail: DecimalFormatSymbols constructor");
1538 sym2
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "Q");
1539 fmt2
.setDecimalFormatSymbols(sym2
);
1542 fmt2
.format(2350.75, str
);
1543 if (str
== "Q 2,350.75") {
1546 errln("Fail: setDecimalFormatSymbols -> " + str
+ ", expected Q 2,350.75");
1550 void NumberFormatTest::TestPerMill() {
1551 UErrorCode ec
= U_ZERO_ERROR
;
1553 DecimalFormat
fmt(ctou("###.###\\u2030"), ec
);
1554 if (!assertSuccess("DecimalFormat ct", ec
)) return;
1555 assertEquals("0.4857 x ###.###\\u2030",
1556 ctou("485.7\\u2030"), fmt
.format(0.4857, str
));
1558 DecimalFormatSymbols
sym(Locale::getUS(), ec
);
1559 sym
.setSymbol(DecimalFormatSymbols::kPerMillSymbol
, ctou("m"));
1560 DecimalFormat
fmt2("", sym
, ec
);
1561 fmt2
.applyLocalizedPattern("###.###m", ec
);
1562 if (!assertSuccess("setup", ec
)) return;
1564 assertEquals("0.4857 x ###.###m",
1565 "485.7m", fmt2
.format(0.4857, str
));
1569 * Generic test for patterns that should be legal/illegal.
1571 void NumberFormatTest::TestIllegalPatterns() {
1573 // Prefix with "-:" for illegal patterns
1574 // Prefix with "+:" for legal patterns
1575 const char* DATA
[] = {
1576 // Unquoted special characters in the suffix are illegal
1581 for (int32_t i
=0; DATA
[i
]; ++i
) {
1582 const char* pat
=DATA
[i
];
1583 UBool valid
= (*pat
) == '+';
1585 UErrorCode ec
= U_ZERO_ERROR
;
1586 DecimalFormat
fmt(pat
, ec
); // locale doesn't matter here
1587 if (U_SUCCESS(ec
) == valid
) {
1588 logln("Ok: pattern \"%s\": %s",
1589 pat
, u_errorName(ec
));
1591 errln("FAIL: pattern \"%s\" should have %s; got %s",
1592 pat
, (valid
?"succeeded":"failed"),
1598 //----------------------------------------------------------------------
1600 static const char* KEYWORDS
[] = {
1601 /*0*/ "ref=", // <reference pattern to parse numbers>
1602 /*1*/ "loc=", // <locale for formats>
1603 /*2*/ "f:", // <pattern or '-'> <number> <exp. string>
1604 /*3*/ "fp:", // <pattern or '-'> <number> <exp. string> <exp. number>
1605 /*4*/ "rt:", // <pattern or '-'> <(exp.) number> <(exp.) string>
1606 /*5*/ "p:", // <pattern or '-'> <string> <exp. number>
1607 /*6*/ "perr:", // <pattern or '-'> <invalid string>
1608 /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
1609 /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt>
1614 * Return an integer representing the next token from this
1615 * iterator. The integer will be an index into the given list, or
1616 * -1 if there are no more tokens, or -2 if the token is not on
1619 static int32_t keywordIndex(const UnicodeString
& tok
) {
1620 for (int32_t i
=0; KEYWORDS
[i
]!=0; ++i
) {
1621 if (tok
==KEYWORDS
[i
]) {
1629 * Parse a CurrencyAmount using the given NumberFormat, with
1630 * the 'delim' character separating the number and the currency.
1632 static void parseCurrencyAmount(const UnicodeString
& str
,
1633 const NumberFormat
& fmt
,
1635 Formattable
& result
,
1637 UnicodeString num
, cur
;
1638 int32_t i
= str
.indexOf(delim
);
1639 str
.extractBetween(0, i
, num
);
1640 str
.extractBetween(i
+1, INT32_MAX
, cur
);
1642 fmt
.parse(num
, n
, ec
);
1643 result
.adoptObject(new CurrencyAmount(n
, cur
.getTerminatedBuffer(), ec
));
1646 void NumberFormatTest::TestCases() {
1647 UErrorCode ec
= U_ZERO_ERROR
;
1648 TextFile
reader("NumberFormatTestCases.txt", "UTF8", ec
);
1649 if (U_FAILURE(ec
)) {
1650 errln("FAIL: Couldn't open NumberFormatTestCases.txt");
1653 TokenIterator
tokens(&reader
);
1655 Locale
loc("en", "US", "");
1656 DecimalFormat
*ref
= 0, *fmt
= 0;
1657 MeasureFormat
*mfmt
= 0;
1658 UnicodeString pat
, tok
, mloc
, str
, out
, where
, currAmt
;
1663 if (!tokens
.next(tok
, ec
)) {
1666 where
= UnicodeString("(") + tokens
.getLineNumber() + ") ";
1667 int32_t cmd
= keywordIndex(tok
);
1670 // ref= <reference pattern>
1671 if (!tokens
.next(tok
, ec
)) goto error
;
1673 ref
= new DecimalFormat(tok
,
1674 new DecimalFormatSymbols(Locale::getUS(), ec
), ec
);
1678 if (!tokens
.next(tok
, ec
)) goto error
;
1679 loc
= Locale::createFromName(CharString(tok
));
1685 if (!tokens
.next(tok
, ec
)) goto error
;
1689 fmt
= new DecimalFormat(pat
, new DecimalFormatSymbols(loc
, ec
), ec
);
1690 if (U_FAILURE(ec
)) {
1691 errln("FAIL: " + where
+ "Pattern \"" + pat
+ "\": " + u_errorName(ec
));
1693 if (!tokens
.next(tok
, ec
)) goto error
;
1694 if (!tokens
.next(tok
, ec
)) goto error
;
1696 if (!tokens
.next(tok
, ec
)) goto error
;
1701 if (cmd
== 2 || cmd
== 3 || cmd
== 4) {
1702 // f: <pattern or '-'> <number> <exp. string>
1703 // fp: <pattern or '-'> <number> <exp. string> <exp. number>
1704 // rt: <pattern or '-'> <number> <string>
1706 if (!tokens
.next(num
, ec
)) goto error
;
1707 if (!tokens
.next(str
, ec
)) goto error
;
1708 ref
->parse(num
, n
, ec
);
1709 assertSuccess("parse", ec
);
1710 assertEquals(where
+ "\"" + pat
+ "\".format(" + num
+ ")",
1711 str
, fmt
->format(n
, out
.remove(), ec
));
1712 assertSuccess("format", ec
);
1713 if (cmd
== 3) { // fp:
1714 if (!tokens
.next(num
, ec
)) goto error
;
1715 ref
->parse(num
, n
, ec
);
1716 assertSuccess("parse", ec
);
1718 if (cmd
!= 2) { // != f:
1720 fmt
->parse(str
, m
, ec
);
1721 assertSuccess("parse", ec
);
1722 assertEquals(where
+ "\"" + pat
+ "\".parse(\"" + str
+ "\")",
1726 // p: <pattern or '-'> <string to parse> <exp. number>
1728 UnicodeString expstr
;
1729 if (!tokens
.next(str
, ec
)) goto error
;
1730 if (!tokens
.next(expstr
, ec
)) goto error
;
1732 ref
->parse(expstr
, exp
, ec
);
1733 assertSuccess("parse", ec
);
1734 fmt
->parse(str
, n
, ec
);
1735 assertSuccess("parse", ec
);
1736 assertEquals(where
+ "\"" + pat
+ "\".parse(\"" + str
+ "\")",
1741 if (!tokens
.next(tok
, ec
)) goto error
;
1745 mfmt
= MeasureFormat::createCurrencyFormat(
1746 Locale::createFromName(CharString(mloc
)), ec
);
1747 if (U_FAILURE(ec
)) {
1748 errln("FAIL: " + where
+ "Loc \"" + mloc
+ "\": " + u_errorName(ec
));
1750 if (!tokens
.next(tok
, ec
)) goto error
;
1751 if (!tokens
.next(tok
, ec
)) goto error
;
1752 if (!tokens
.next(tok
, ec
)) goto error
;
1756 // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
1757 if (!tokens
.next(currAmt
, ec
)) goto error
;
1758 if (!tokens
.next(str
, ec
)) goto error
;
1759 parseCurrencyAmount(currAmt
, *ref
, (UChar
)0x2F/*'/'*/, n
, ec
);
1760 if (assertSuccess("parseCurrencyAmount", ec
)) {
1761 assertEquals(where
+ "getCurrencyFormat(" + mloc
+ ").format(" + currAmt
+ ")",
1762 str
, mfmt
->format(n
, out
.remove(), ec
));
1763 assertSuccess("format", ec
);
1765 if (!tokens
.next(currAmt
, ec
)) goto error
;
1766 parseCurrencyAmount(currAmt
, *ref
, (UChar
)0x2F/*'/'*/, n
, ec
);
1767 if (assertSuccess("parseCurrencyAmount", ec
)) {
1769 mfmt
->parseObject(str
, m
, ec
);
1770 if (assertSuccess("parseCurrency", ec
)) {
1771 assertEquals(where
+ "getCurrencyFormat(" + mloc
+ ").parse(\"" + str
+ "\")",
1777 // perr: <pattern or '-'> <invalid string>
1778 errln("FAIL: Under construction");
1781 // pat: <pattern> <exp. toPattern, or '-' or 'err'>
1782 UnicodeString testpat
;
1783 UnicodeString exppat
;
1784 if (!tokens
.next(testpat
, ec
)) goto error
;
1785 if (!tokens
.next(exppat
, ec
)) goto error
;
1786 UBool err
= exppat
== "err";
1787 UBool existingPat
= FALSE
;
1788 if (testpat
== "-") {
1790 errln("FAIL: " + where
+ "Invalid command \"pat: - err\"");
1796 if (exppat
== "-") exppat
= testpat
;
1797 DecimalFormat
* f
= 0;
1798 UErrorCode ec2
= U_ZERO_ERROR
;
1802 f
= new DecimalFormat(testpat
, ec2
);
1804 if (U_SUCCESS(ec2
)) {
1806 errln("FAIL: " + where
+ "Invalid pattern \"" + testpat
+
1810 assertEquals(where
+ "\"" + testpat
+ "\".toPattern()",
1811 exppat
, f
->toPattern(pat2
));
1815 logln("Ok: " + where
+ "Invalid pattern \"" + testpat
+
1816 "\" failed: " + u_errorName(ec2
));
1818 errln("FAIL: " + where
+ "Valid pattern \"" + testpat
+
1819 "\" failed: " + u_errorName(ec2
));
1822 if (!existingPat
) delete f
;
1825 errln("FAIL: " + where
+ "Unknown command \"" + tok
+ "\"");
1832 if (U_SUCCESS(ec
)) {
1833 errln("FAIL: Unexpected EOF");
1835 errln("FAIL: " + where
+ "Unexpected " + u_errorName(ec
));
1845 //----------------------------------------------------------------------
1847 //----------------------------------------------------------------------
1849 UBool
NumberFormatTest::equalValue(const Formattable
& a
, const Formattable
& b
) {
1850 if (a
.getType() == b
.getType()) {
1854 if (a
.getType() == Formattable::kLong
) {
1855 if (b
.getType() == Formattable::kInt64
) {
1856 return a
.getLong() == b
.getLong();
1857 } else if (b
.getType() == Formattable::kDouble
) {
1858 return (double) a
.getLong() == b
.getDouble(); // TODO check use of double instead of long
1860 } else if (a
.getType() == Formattable::kDouble
) {
1861 if (b
.getType() == Formattable::kLong
) {
1862 return a
.getDouble() == (double) b
.getLong();
1863 } else if (b
.getType() == Formattable::kInt64
) {
1864 return a
.getDouble() == (double)b
.getInt64();
1866 } else if (a
.getType() == Formattable::kInt64
) {
1867 if (b
.getType() == Formattable::kLong
) {
1868 return a
.getInt64() == (int64_t)b
.getLong();
1869 } else if (b
.getType() == Formattable::kDouble
) {
1870 return a
.getInt64() == (int64_t)b
.getDouble();
1876 void NumberFormatTest::expect2(NumberFormat
& fmt
, const Formattable
& n
, const UnicodeString
& str
) {
1877 // Don't round-trip format test, since we explicitly do it
1878 expect(fmt
, n
, str
, FALSE
);
1879 expect(fmt
, str
, n
);
1882 void NumberFormatTest::expect2(NumberFormat
* fmt
, const Formattable
& n
,
1883 const UnicodeString
& exp
,
1884 UErrorCode status
) {
1885 if (U_FAILURE(status
)) {
1886 errln("FAIL: NumberFormat constructor");
1888 expect2(*fmt
, n
, exp
);
1893 void NumberFormatTest::expect(NumberFormat
& fmt
, const UnicodeString
& str
, const Formattable
& n
) {
1894 UErrorCode status
= U_ZERO_ERROR
;
1896 fmt
.parse(str
, num
, status
);
1897 if (U_FAILURE(status
)) {
1898 errln(UnicodeString("FAIL: Parse failed for \"") + str
+ "\"");
1902 ((DecimalFormat
*) &fmt
)->toPattern(pat
);
1903 if (equalValue(num
, n
)) {
1904 logln(UnicodeString("Ok \"") + str
+ "\" x " +
1908 errln(UnicodeString("FAIL \"") + str
+ "\" x " +
1910 toString(num
) + ", expected " + toString(n
));
1914 void NumberFormatTest::expect(NumberFormat
& fmt
, const Formattable
& n
,
1915 const UnicodeString
& exp
, UBool rt
) {
1918 UErrorCode status
= U_ZERO_ERROR
;
1919 fmt
.format(n
, saw
, pos
, status
);
1920 CHECK(status
, "NumberFormat::format");
1922 ((DecimalFormat
*) &fmt
)->toPattern(pat
);
1924 logln(UnicodeString("Ok ") + toString(n
) + " x " +
1925 escape(pat
) + " = \"" +
1926 escape(saw
) + "\"");
1927 // We should be able to round-trip the formatted string =>
1928 // number => string (but not the other way around: number
1929 // => string => number2, might have number2 != number):
1932 fmt
.parse(exp
, n2
, status
);
1933 if (U_FAILURE(status
)) {
1934 errln(UnicodeString("FAIL: Parse failed for \"") + exp
+ "\"");
1938 fmt
.format(n2
, saw2
, pos
, status
);
1939 CHECK(status
, "NumberFormat::format");
1941 errln((UnicodeString
)"FAIL \"" + exp
+ "\" => " + toString(n2
) +
1942 " => \"" + saw2
+ "\"");
1946 errln(UnicodeString("FAIL ") + toString(n
) + " x " +
1947 escape(pat
) + " = \"" +
1948 escape(saw
) + "\", expected \"" + exp
+ "\"");
1952 void NumberFormatTest::expect(NumberFormat
* fmt
, const Formattable
& n
,
1953 const UnicodeString
& exp
,
1954 UErrorCode status
) {
1955 if (U_FAILURE(status
)) {
1956 errln("FAIL: NumberFormat constructor");
1958 expect(*fmt
, n
, exp
);
1963 void NumberFormatTest::expectCurrency(NumberFormat
& nf
, const Locale
& locale
,
1964 double value
, const UnicodeString
& string
) {
1965 UErrorCode ec
= U_ZERO_ERROR
;
1966 DecimalFormat
& fmt
= * (DecimalFormat
*) &nf
;
1967 const UChar DEFAULT_CURR
[] = {45/*-*/,0};
1969 u_strcpy(curr
, DEFAULT_CURR
);
1970 if (*locale
.getLanguage() != 0) {
1971 ucurr_forLocale(locale
.getName(), curr
, 4, &ec
);
1972 assertSuccess("ucurr_forLocale", ec
);
1973 fmt
.setCurrency(curr
, ec
);
1974 assertSuccess("DecimalFormat::setCurrency", ec
);
1977 fmt
.format(value
, s
);
1978 s
.findAndReplace((UChar32
)0x00A0, (UChar32
)0x0020);
1980 // Default display of the number yields "1234.5599999999999"
1981 // instead of "1234.56". Use a formatter to fix this.
1983 NumberFormat::createInstance(Locale::getUS(), ec
);
1985 if (U_FAILURE(ec
)) {
1986 // Oops; bad formatter. Use default op+= display.
1987 v
= (UnicodeString
)"" + value
;
1989 f
->setMaximumFractionDigits(4);
1990 f
->setGroupingUsed(FALSE
);
1991 f
->format(value
, v
);
1996 logln((UnicodeString
)"Ok: " + v
+ " x " + curr
+ " => " + prettify(s
));
1998 errln((UnicodeString
)"FAIL: " + v
+ " x " + curr
+ " => " + prettify(s
) +
1999 ", expected " + prettify(string
));
2003 void NumberFormatTest::expectPat(DecimalFormat
& fmt
, const UnicodeString
& exp
) {
2007 logln(UnicodeString("Ok \"") + pat
+ "\"");
2009 errln(UnicodeString("FAIL \"") + pat
+ "\", expected \"" + exp
+ "\"");
2013 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2015 expectPad(fmt
, pat
, pos
, 0, (UnicodeString
)"");
2017 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2018 int32_t pos
, int32_t width
, UChar pad
) {
2019 expectPad(fmt
, pat
, pos
, width
, UnicodeString(pad
));
2021 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
2022 int32_t pos
, int32_t width
, const UnicodeString
& pad
) {
2023 int32_t apos
= 0, awidth
= 0;
2024 UnicodeString apadStr
;
2025 UErrorCode status
= U_ZERO_ERROR
;
2026 fmt
.applyPattern(pat
, status
);
2027 if (U_SUCCESS(status
)) {
2028 apos
= fmt
.getPadPosition();
2029 awidth
= fmt
.getFormatWidth();
2030 apadStr
=fmt
.getPadCharacterString();
2036 if (apos
== pos
&& awidth
== width
&& apadStr
== pad
) {
2037 UnicodeString infoStr
;
2038 if (pos
== ILLEGAL
) {
2039 infoStr
= UnicodeString(" width=", "") + awidth
+ UnicodeString(" pad=", "") + apadStr
;
2041 logln(UnicodeString("Ok \"") + pat
+ "\" pos=" + apos
+ infoStr
);
2043 errln(UnicodeString("FAIL \"") + pat
+ "\" pos=" + apos
+
2044 " width=" + awidth
+ " pad=" + apadStr
+
2045 ", expected " + pos
+ " " + width
+ " " + pad
);
2049 #endif /* #if !UCONFIG_NO_FORMATTING */