1 /********************************************************************
3 * Copyright (c) 1997-2003, 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"
24 static const UChar EUR
[] = {69,85,82,0}; // "EUR"
26 // *****************************************************************************
27 // class NumberFormatTest
28 // *****************************************************************************
30 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
32 #define CHECK(status,str) if (U_FAILURE(status)) { errln(UnicodeString("FAIL: ") + str); return; }
34 void NumberFormatTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
36 // if (exec) logln((UnicodeString)"TestSuite DateFormatTest");
38 CASE(0,TestCurrencySign
);
41 CASE(3,TestRounding487
);
43 CASE(5,TestExponential
);
46 // Upgrade to alphaWorks - liu 5/99
48 CASE(8,TestScientific
);
50 CASE(10,TestPatterns2
);
51 CASE(11,TestSecondaryGrouping
);
52 CASE(12,TestSurrogateSupport
);
55 CASE(14,TestCurrencyObject
);
56 CASE(15,TestCurrencyPatterns
);
57 CASE(16,TestDigitList
);
58 CASE(17,TestWhiteSpaceParsing
);
59 CASE(18,TestComplexCurrency
);
60 CASE(19,TestRegCurrency
);
61 CASE(20,TestSymbolsWithBadLocale
);
62 CASE(21,TestAdoptDecimalFormatSymbols
);
64 default: name
= ""; break;
68 // -------------------------------------
70 // Test API (increase code coverage)
72 NumberFormatTest::TestAPI(void)
75 UErrorCode status
= U_ZERO_ERROR
;
76 NumberFormat
*test
= NumberFormat::createInstance("root", status
);
77 if(U_FAILURE(status
)) {
78 errln("unable to create format object");
81 test
->setMinimumIntegerDigits(10);
82 test
->setMaximumIntegerDigits(2);
84 test
->setMinimumFractionDigits(10);
85 test
->setMaximumFractionDigits(2);
89 Formattable
bla("Paja Patak"); // Donald Duck for non Serbian speakers
90 test
->format(bla
, result
, pos
, status
);
91 if(U_SUCCESS(status
)) {
92 errln("Yuck... Formatted a duck... As a number!");
94 status
= U_ZERO_ERROR
;
104 // Test various patterns
106 NumberFormatTest::TestPatterns(void)
108 UErrorCode status
= U_ZERO_ERROR
;
109 DecimalFormatSymbols
sym(Locale::getUS(), status
);
110 if (U_FAILURE(status
)) { errln("FAIL: Could not construct DecimalFormatSymbols"); return; }
112 const char* pat
[] = { "#.#", "#.", ".#", "#" };
113 int32_t pat_length
= (int32_t)(sizeof(pat
) / sizeof(pat
[0]));
114 const char* newpat
[] = { "#0.#", "#0.", "#.0", "#" };
115 const char* num
[] = { "0", "0.", ".0", "0" };
116 for (int32_t i
=0; i
<pat_length
; ++i
)
118 status
= U_ZERO_ERROR
;
119 DecimalFormat
fmt(pat
[i
], sym
, status
);
120 if (U_FAILURE(status
)) { errln((UnicodeString
)"FAIL: DecimalFormat constructor failed for " + pat
[i
]); continue; }
121 UnicodeString newp
; fmt
.toPattern(newp
);
122 if (!(newp
== newpat
[i
]))
123 errln((UnicodeString
)"FAIL: Pattern " + pat
[i
] + " should transmute to " + newpat
[i
] +
124 "; " + newp
+ " seen instead");
126 UnicodeString s
; (*(NumberFormat
*)&fmt
).format((int32_t)0, s
);
129 errln((UnicodeString
)"FAIL: Pattern " + pat
[i
] + " should format zero as " + num
[i
] +
130 "; " + s
+ " seen instead");
131 logln((UnicodeString
)"Min integer digits = " + fmt
.getMinimumIntegerDigits());
137 NumberFormatTest::TestDigitList(void)
139 // API coverage for DigitList
141 icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
142 icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
143 icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
147 list1
.fDecimalAt
= 1;
150 if (list1
!= list2
) {
151 errln("digitlist append, operator!= or set failed ");
153 if (!(list1
== list2
)) {
154 errln("digitlist append, operator== or set failed ");
158 // -------------------------------------
160 // Test exponential pattern
162 NumberFormatTest::TestExponential(void)
164 UErrorCode status
= U_ZERO_ERROR
;
165 DecimalFormatSymbols
sym(Locale::getUS(), status
);
166 if (U_FAILURE(status
)) { errln("FAIL: Bad status returned by DecimalFormatSymbols ct"); return; }
167 const char* pat
[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
168 int32_t pat_length
= (int32_t)(sizeof(pat
) / sizeof(pat
[0]));
170 // The following #if statements allow this test to be built and run on
171 // platforms that do not have standard IEEE numerics. For example,
172 // S/390 doubles have an exponent range of -78 to +75. For the
173 // following #if statements to work, float.h must define
174 // DBL_MAX_10_EXP to be a compile-time constant.
176 // This section may be expanded as needed.
178 #if DBL_MAX_10_EXP > 300
179 double val
[] = { 0.01234, 123456789, 1.23e300
, -3.141592653e-271 };
180 int32_t val_length
= (int32_t)(sizeof(val
) / sizeof(val
[0]));
181 const char* valFormat
[] =
184 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
186 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
188 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
190 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
194 0.01234, 123460000, 1.23E300
, -3.1416E-271,
195 0.01234, 123460000, 1.23E300
, -3.1416E-271,
196 0.01234, 123456800, 1.23E300
, -3.141593E-271,
197 0.01234, 123500000, 1.23E300
, -3.142E-271,
199 #elif DBL_MAX_10_EXP > 70
200 double val
[] = { 0.01234, 123456789, 1.23e70
, -3.141592653e-71 };
201 int32_t val_length
= sizeof(val
) / sizeof(val
[0]);
205 "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
207 "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
209 "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
211 "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
215 0.01234, 123460000, 1.23E70
, -3.1416E-71,
216 0.01234, 123460000, 1.23E70
, -3.1416E-71,
217 0.01234, 123456800, 1.23E70
, -3.141593E-71,
218 0.01234, 123500000, 1.23E70
, -3.142E-71,
221 // Don't test double conversion
223 int32_t val_length
= 0;
224 char** valFormat
= 0;
225 double* valParse
= 0;
226 logln("Warning: Skipping double conversion tests");
229 int32_t lval
[] = { 0, -1, 1, 123456789 };
230 int32_t lval_length
= (int32_t)(sizeof(lval
) / sizeof(lval
[0]));
231 const char* lvalFormat
[] =
234 "0E0", "-1E0", "1E0", "1.2346E8",
236 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
238 "0E000", "-1E000", "1E000", "123.4568E006",
240 "0E0", "[1E0]", "1E0", "1.235E8"
242 int32_t lvalParse
[] =
249 int32_t ival
= 0, ilval
= 0;
250 for (int32_t p
=0; p
<pat_length
; ++p
)
252 DecimalFormat
fmt(pat
[p
], sym
, status
);
253 if (U_FAILURE(status
)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
254 UnicodeString pattern
;
255 logln((UnicodeString
)"Pattern \"" + pat
[p
] + "\" -toPattern-> \"" +
256 fmt
.toPattern(pattern
) + "\"");
258 for (v
=0; v
<val_length
; ++v
)
260 UnicodeString s
; (*(NumberFormat
*)&fmt
).format(val
[v
], s
);
261 logln((UnicodeString
)" " + val
[v
] + " -format-> " + s
);
262 if (s
!= valFormat
[v
+ival
])
263 errln((UnicodeString
)"FAIL: Expected " + valFormat
[v
+ival
]);
265 ParsePosition
pos(0);
267 fmt
.parse(s
, af
, pos
);
269 UBool useEpsilon
= FALSE
;
270 if (af
.getType() == Formattable::kLong
)
272 else if (af
.getType() == Formattable::kDouble
) {
274 #if defined(OS390) || defined(OS400)
275 // S/390 will show a failure like this:
276 //| -3.141592652999999e-271 -format-> -3.1416E-271
277 //| -parse-> -3.1416e-271
278 //| FAIL: Expected -3.141599999999999e-271
279 // To compensate, we use an epsilon-based equality
280 // test on S/390 only. We don't want to do this in
281 // general because it's less exacting.
286 errln((UnicodeString
)"FAIL: Non-numeric Formattable returned");
289 if (pos
.getIndex() == s
.length())
291 logln((UnicodeString
)" -parse-> " + a
);
292 // Use epsilon comparison as necessary
294 (uprv_fabs(a
- valParse
[v
+ival
]) / a
> (2*DBL_EPSILON
))) ||
295 (!useEpsilon
&& a
!= valParse
[v
+ival
]))
297 errln((UnicodeString
)"FAIL: Expected " + valParse
[v
+ival
]);
301 errln((UnicodeString
)"FAIL: Partial parse (" + pos
.getIndex() + " chars) -> " + a
);
302 errln((UnicodeString
)" should be (" + s
.length() + " chars) -> " + valParse
[v
+ival
]);
305 for (v
=0; v
<lval_length
; ++v
)
308 (*(NumberFormat
*)&fmt
).format(lval
[v
], s
);
309 logln((UnicodeString
)" " + lval
[v
] + "L -format-> " + s
);
310 if (s
!= lvalFormat
[v
+ilval
])
311 errln((UnicodeString
)"ERROR: Expected " + lvalFormat
[v
+ilval
] + " Got: " + s
);
313 ParsePosition
pos(0);
315 fmt
.parse(s
, af
, pos
);
316 if (af
.getType() == Formattable::kLong
) {
317 int32_t a
= af
.getLong();
318 if (pos
.getIndex() == s
.length())
320 logln((UnicodeString
)" -parse-> " + a
);
321 if (a
!= lvalParse
[v
+ilval
])
322 errln((UnicodeString
)"FAIL: Expected " + lvalParse
[v
+ilval
]);
325 errln((UnicodeString
)"FAIL: Partial parse (" + pos
.getIndex() + " chars) -> " + a
);
328 errln((UnicodeString
)"FAIL: Non-long Formattable returned for " + s
329 + " Double: " + af
.getDouble()
330 + ", Long: " + af
.getLong());
333 ilval
+= lval_length
;
337 // -------------------------------------
339 // Test the handling of quotes
341 NumberFormatTest::TestQuotes(void)
343 UErrorCode status
= U_ZERO_ERROR
;
345 DecimalFormatSymbols
*sym
= new DecimalFormatSymbols(Locale::getUS(), status
);
346 pat
= new UnicodeString("a'fo''o'b#");
347 DecimalFormat
*fmt
= new DecimalFormat(*pat
, *sym
, status
);
349 ((NumberFormat
*)fmt
)->format((int32_t)123, s
);
350 logln((UnicodeString
)"Pattern \"" + *pat
+ "\"");
351 logln((UnicodeString
)" Format 123 -> " + escape(s
));
352 if (!(s
=="afo'ob123"))
353 errln((UnicodeString
)"FAIL: Expected afo'ob123");
359 pat
= new UnicodeString("a''b#");
360 fmt
= new DecimalFormat(*pat
, *sym
, status
);
361 ((NumberFormat
*)fmt
)->format((int32_t)123, s
);
362 logln((UnicodeString
)"Pattern \"" + *pat
+ "\"");
363 logln((UnicodeString
)" Format 123 -> " + escape(s
));
365 errln((UnicodeString
)"FAIL: Expected a'b123");
372 * Test the handling of the currency symbol in patterns.
375 NumberFormatTest::TestCurrencySign(void)
377 UErrorCode status
= U_ZERO_ERROR
;
378 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols(Locale::getUS(), status
);
380 UChar currency
= 0x00A4;
381 // "\xA4#,##0.00;-\xA4#,##0.00"
382 pat
.append(currency
).append("#,##0.00;-").
383 append(currency
).append("#,##0.00");
384 DecimalFormat
*fmt
= new DecimalFormat(pat
, *sym
, status
);
385 UnicodeString s
; ((NumberFormat
*)fmt
)->format(1234.56, s
);
387 logln((UnicodeString
)"Pattern \"" + fmt
->toPattern(pat
) + "\"");
388 logln((UnicodeString
)" Format " + 1234.56 + " -> " + escape(s
));
389 if (s
!= "$1,234.56") errln((UnicodeString
)"FAIL: Expected $1,234.56");
391 ((NumberFormat
*)fmt
)->format(- 1234.56, s
);
392 logln((UnicodeString
)" Format " + (-1234.56) + " -> " + escape(s
));
393 if (s
!= "-$1,234.56") errln((UnicodeString
)"FAIL: Expected -$1,234.56");
396 // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
397 pat
.append(currency
).append(currency
).
398 append(" #,##0.00;").
399 append(currency
).append(currency
).
400 append(" -#,##0.00");
401 fmt
= new DecimalFormat(pat
, *sym
, status
);
403 ((NumberFormat
*)fmt
)->format(1234.56, s
);
404 logln((UnicodeString
)"Pattern \"" + fmt
->toPattern(pat
) + "\"");
405 logln((UnicodeString
)" Format " + 1234.56 + " -> " + escape(s
));
406 if (s
!= "USD 1,234.56") errln((UnicodeString
)"FAIL: Expected USD 1,234.56");
408 ((NumberFormat
*)fmt
)->format(-1234.56, s
);
409 logln((UnicodeString
)" Format " + (-1234.56) + " -> " + escape(s
));
410 if (s
!= "USD -1,234.56") errln((UnicodeString
)"FAIL: Expected USD -1,234.56");
413 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
416 // -------------------------------------
418 static UChar
toHexString(int32_t i
) { return (UChar
)(i
+ (i
< 10 ? 0x30 : (0x41 - 10))); }
421 NumberFormatTest::escape(UnicodeString
& s
)
424 for (int32_t i
=0; i
<s
.length(); ++i
)
426 UChar c
= s
[(int32_t)i
];
427 if (c
<= (UChar
)0x7F) buf
+= c
;
429 buf
+= (UChar
)0x5c; buf
+= (UChar
)0x55;
430 buf
+= toHexString((c
& 0xF000) >> 12);
431 buf
+= toHexString((c
& 0x0F00) >> 8);
432 buf
+= toHexString((c
& 0x00F0) >> 4);
433 buf
+= toHexString(c
& 0x000F);
440 // -------------------------------------
443 * Test localized currency patterns.
446 NumberFormatTest::TestCurrency(void)
448 UErrorCode status
= U_ZERO_ERROR
;
449 NumberFormat
* currencyFmt
= NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status
);
450 UnicodeString s
; currencyFmt
->format(1.50, s
);
451 logln((UnicodeString
)"Un pauvre ici a..........." + s
);
453 errln((UnicodeString
)"FAIL: Expected 1,50 $");
456 currencyFmt
= NumberFormat::createCurrencyInstance(Locale("de_DE_PREEURO"),status
);
457 currencyFmt
->format(1.50, s
);
458 logln((UnicodeString
)"Un pauvre en Allemagne a.." + s
);
460 errln((UnicodeString
)"FAIL: Expected 1,50 DM");
463 currencyFmt
= NumberFormat::createCurrencyInstance(Locale("fr_FR_PREEURO"), status
);
464 currencyFmt
->format(1.50, s
);
465 logln((UnicodeString
)"Un pauvre en France a....." + s
);
467 errln((UnicodeString
)"FAIL: Expected 1,50 F");
469 if (U_FAILURE(status
))
470 errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
473 // -------------------------------------
476 * Test the Currency object handling, new as of ICU 2.2.
478 void NumberFormatTest::TestCurrencyObject() {
479 UErrorCode ec
= U_ZERO_ERROR
;
481 NumberFormat::createCurrencyInstance(Locale::getUS(), ec
);
484 errln("FAIL: getCurrencyInstance(US)");
489 Locale
null("", "", "");
491 expectCurrency(*fmt
, null
, 1234.56, "$1,234.56");
493 expectCurrency(*fmt
, Locale::getFrance(),
494 1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
496 expectCurrency(*fmt
, Locale::getJapan(),
497 1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
499 expectCurrency(*fmt
, Locale("fr", "CH", ""),
500 1234.56, "SwF1,234.55"); // 0.05 rounding
502 expectCurrency(*fmt
, Locale::getUS(),
503 1234.56, "$1,234.56");
506 fmt
= NumberFormat::createCurrencyInstance(Locale::getFrance(), ec
);
509 errln("FAIL: getCurrencyInstance(FRANCE)");
514 expectCurrency(*fmt
, null
, 1234.56, CharsToUnicodeString("1 234,56 \\u20AC"));
516 expectCurrency(*fmt
, Locale::getJapan(),
517 1234.56, CharsToUnicodeString("1 235 \\u00A5")); // Yen
519 expectCurrency(*fmt
, Locale("fr", "CH", ""),
520 1234.56, "1 234,55 sFr."); // 0.05 rounding
522 expectCurrency(*fmt
, Locale::getUS(),
523 1234.56, "1 234,56 $");
525 expectCurrency(*fmt
, Locale::getFrance(),
526 1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); // Euro
531 // -------------------------------------
534 * Do rudimentary testing of parsing.
537 NumberFormatTest::TestParse(void)
539 UErrorCode status
= U_ZERO_ERROR
;
540 UnicodeString
arg("0");
541 DecimalFormat
* format
= new DecimalFormat("00", status
);
543 Formattable n
; format
->parse(arg
, n
, status
);
544 logln((UnicodeString
)"parse(" + arg
+ ") = " + n
.getLong());
545 if (n
.getType() != Formattable::kLong
||
546 n
.getLong() != 0) errln((UnicodeString
)"FAIL: Expected 0");
548 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
550 //catch(Exception e) {
551 // errln((UnicodeString)"Exception caught: " + e);
555 // -------------------------------------
558 * Test proper rounding by the format method.
561 NumberFormatTest::TestRounding487(void)
563 UErrorCode status
= U_ZERO_ERROR
;
564 NumberFormat
*nf
= NumberFormat::createInstance(status
);
565 roundingTest(*nf
, 0.00159999, 4, "0.0016");
566 roundingTest(*nf
, 0.00995, 4, "0.01");
568 roundingTest(*nf
, 12.3995, 3, "12.4");
570 roundingTest(*nf
, 12.4999, 0, "12");
571 roundingTest(*nf
, - 19.5, 0, "-20");
573 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: Status " + (int32_t)status
);
577 * Test the functioning of the secondary grouping value.
579 void NumberFormatTest::TestSecondaryGrouping(void) {
580 UErrorCode status
= U_ZERO_ERROR
;
581 DecimalFormatSymbols
US(Locale::getUS(), status
);
582 CHECK(status
, "DecimalFormatSymbols ct");
584 DecimalFormat
f("#,##,###", US
, status
);
585 CHECK(status
, "DecimalFormat ct");
587 expect2(f
, (int32_t)123456789L, "12,34,56,789");
588 expectPat(f
, "#,##,###");
589 f
.applyPattern("#,###", status
);
590 CHECK(status
, "applyPattern");
592 f
.setSecondaryGroupingSize(4);
593 expect2(f
, (int32_t)123456789L, "12,3456,789");
594 expectPat(f
, "#,####,###");
595 NumberFormat
*g
= NumberFormat::createInstance(Locale("hi", "IN"), status
);
596 CHECK(status
, "createInstance(hi_IN)");
599 int32_t l
= (int32_t)1876543210L;
602 // expect "1,87,65,43,210", but with Hindi digits
605 if (out
.length() != 14) {
608 for (int32_t i
=0; i
<out
.length(); ++i
) {
609 UBool expectGroup
= FALSE
;
618 // Later -- fix this to get the actual grouping
619 // character from the resource bundle.
620 UBool isGroup
= (out
.charAt(i
) == 0x002C);
621 if (isGroup
!= expectGroup
) {
628 errln((UnicodeString
)"FAIL Expected " + l
+
629 " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
632 logln((UnicodeString
)"Ok " + l
+
638 void NumberFormatTest::TestWhiteSpaceParsing(void) {
639 UErrorCode ec
= U_ZERO_ERROR
;
640 DecimalFormatSymbols
US(Locale::getUS(), ec
);
641 DecimalFormat
fmt("a b#0c ", US
, ec
);
643 errln("FAIL: Constructor");
647 expect(fmt
, "a b1234c ", n
);
648 expect(fmt
, "a b1234c ", n
);
652 * Test currencies whose display name is a ChoiceFormat.
654 void NumberFormatTest::TestComplexCurrency() {
655 UErrorCode ec
= U_ZERO_ERROR
;
656 Locale
loc("en", "IN", "");
657 NumberFormat
* fmt
= NumberFormat::createCurrencyInstance(loc
, ec
);
659 expect2(*fmt
, 1.0, "Re. 1.00");
660 // Use .00392625 because that's 2^-8. Any value less than 0.005 is fine.
661 expect(*fmt
, 1.00390625, "Re. 1.00"); // tricky
662 expect2(*fmt
, 12345678.0, "Rs. 1,23,45,678.00");
663 expect2(*fmt
, 0.5, "Rs. 0.50");
664 expect2(*fmt
, -1.0, "-Re. 1.00");
665 expect2(*fmt
, -10.0, "-Rs. 10.00");
667 errln("FAIL: getCurrencyInstance(en_IN)");
672 // -------------------------------------
675 NumberFormatTest::roundingTest(NumberFormat
& nf
, double x
, int32_t maxFractionDigits
, const char* expected
)
677 nf
.setMaximumFractionDigits(maxFractionDigits
);
678 UnicodeString out
; nf
.format(x
, out
);
679 logln((UnicodeString
)"" + x
+ " formats with " + maxFractionDigits
+ " fractional digits to " + out
);
680 if (!(out
==expected
)) errln((UnicodeString
)"FAIL: Expected " + expected
);
684 * Upgrade to alphaWorks
686 void NumberFormatTest::TestExponent(void) {
687 UErrorCode status
= U_ZERO_ERROR
;
688 DecimalFormatSymbols
US(Locale::getUS(), status
);
689 CHECK(status
, "DecimalFormatSymbols constructor");
690 DecimalFormat
fmt1(UnicodeString("0.###E0"), US
, status
);
691 CHECK(status
, "DecimalFormat(0.###E0)");
692 DecimalFormat
fmt2(UnicodeString("0.###E+0"), US
, status
);
693 CHECK(status
, "DecimalFormat(0.###E+0)");
695 expect2(fmt1
, n
, "1.234E3");
696 expect2(fmt2
, n
, "1.234E+3");
697 expect(fmt1
, "1.234E+3", n
); // Either format should parse "E+3"
701 * Upgrade to alphaWorks
703 void NumberFormatTest::TestScientific(void) {
704 UErrorCode status
= U_ZERO_ERROR
;
705 DecimalFormatSymbols
US(Locale::getUS(), status
);
706 CHECK(status
, "DecimalFormatSymbols constructor");
708 // Test pattern round-trip
709 const char* PAT
[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
710 "0.###E0;[0.###E0]" };
711 int32_t PAT_length
= (int32_t)(sizeof(PAT
) / sizeof(PAT
[0]));
713 // min int, max int, min frac, max frac
715 1, 1, 0, 4, // "0.####E0"
716 2, 2, 3, 3, // "00.000E00"
717 1, 3, 0, 4, // "##0.####E000"
718 1, 1, 0, 3, // "0.###E0;[0.###E0]"
720 for (int32_t i
=0; i
<PAT_length
; ++i
) {
721 UnicodeString
pat(PAT
[i
]);
722 DecimalFormat
df(pat
, US
, status
);
723 CHECK(status
, "DecimalFormat constructor");
727 logln(UnicodeString("Ok Pattern rt \"") +
731 errln(UnicodeString("FAIL Pattern rt \"") +
735 // Make sure digit counts match what we expect
736 if (df
.getMinimumIntegerDigits() != DIGITS
[4*i
] ||
737 df
.getMaximumIntegerDigits() != DIGITS
[4*i
+1] ||
738 df
.getMinimumFractionDigits() != DIGITS
[4*i
+2] ||
739 df
.getMaximumFractionDigits() != DIGITS
[4*i
+3]) {
740 errln(UnicodeString("FAIL \"" + pat
+
741 "\" min/max int; min/max frac = ") +
742 df
.getMinimumIntegerDigits() + "/" +
743 df
.getMaximumIntegerDigits() + ";" +
744 df
.getMinimumFractionDigits() + "/" +
745 df
.getMaximumFractionDigits() + ", expect " +
747 DIGITS
[4*i
+1] + ";" +
748 DIGITS
[4*i
+2] + "/" +
754 // Test the constructor for default locale. We have to
755 // manually set the default locale, as there is no
756 // guarantee that the default locale has the same
757 // scientific format.
758 Locale def
= Locale::getDefault();
759 Locale::setDefault(Locale::getUS(), status
);
760 expect2(NumberFormat::createScientificInstance(status
),
762 "1.2345678901E4", status
);
763 Locale::setDefault(def
, status
);
765 expect2(new DecimalFormat("#E0", US
, status
),
768 expect(new DecimalFormat("0E0", US
, status
),
771 expect2(NumberFormat::createScientificInstance(Locale::getUS(), status
),
773 "1.2345678901E4", status
);
774 expect(new DecimalFormat("##0.###E0", US
, status
),
777 expect(new DecimalFormat("##0.###E0", US
, status
),
780 expect2(new DecimalFormat("##0.####E0", US
, status
),
783 expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status
),
785 "1,2345678901E4", status
);
786 expect(new DecimalFormat("##0.####E0", US
, status
),
788 "789.12E-9", status
);
789 expect2(new DecimalFormat("##0.####E0", US
, status
),
792 expect(new DecimalFormat(".###E0", US
, status
),
795 expect2(new DecimalFormat(".###E0", US
, status
),
799 expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
800 new DecimalFormat("##E0", US),
801 new DecimalFormat("####E0", US),
802 new DecimalFormat("0E0", US),
803 new DecimalFormat("00E0", US),
804 new DecimalFormat("000E0", US),
807 new String[] { "4.5678E7",
816 ! Unroll this test into individual tests below...
819 expect2(new DecimalFormat("#E0", US
, status
),
820 (int32_t) 45678000, "4.5678E7", status
);
821 expect2(new DecimalFormat("##E0", US
, status
),
822 (int32_t) 45678000, "45.678E6", status
);
823 expect2(new DecimalFormat("####E0", US
, status
),
824 (int32_t) 45678000, "4567.8E4", status
);
825 expect(new DecimalFormat("0E0", US
, status
),
826 (int32_t) 45678000, "5E7", status
);
827 expect(new DecimalFormat("00E0", US
, status
),
828 (int32_t) 45678000, "46E6", status
);
829 expect(new DecimalFormat("000E0", US
, status
),
830 (int32_t) 45678000, "457E5", status
);
832 expect(new DecimalFormat("###E0", US, status),
833 new Object[] { new Double(0.0000123), "12.3E-6",
834 new Double(0.000123), "123E-6",
835 new Double(0.00123), "1.23E-3",
836 new Double(0.0123), "12.3E-3",
837 new Double(0.123), "123E-3",
838 new Double(1.23), "1.23E0",
839 new Double(12.3), "12.3E0",
840 new Double(123), "123E0",
841 new Double(1230), "1.23E3",
844 ! Unroll this test into individual tests below...
847 expect2(new DecimalFormat("###E0", US
, status
),
848 0.0000123, "12.3E-6", status
);
849 expect2(new DecimalFormat("###E0", US
, status
),
850 0.000123, "123E-6", status
);
851 expect2(new DecimalFormat("###E0", US
, status
),
852 0.00123, "1.23E-3", status
);
853 expect2(new DecimalFormat("###E0", US
, status
),
854 0.0123, "12.3E-3", status
);
855 expect2(new DecimalFormat("###E0", US
, status
),
856 0.123, "123E-3", status
);
857 expect2(new DecimalFormat("###E0", US
, status
),
858 1.23, "1.23E0", status
);
859 expect2(new DecimalFormat("###E0", US
, status
),
860 12.3, "12.3E0", status
);
861 expect2(new DecimalFormat("###E0", US
, status
),
862 123.0, "123E0", status
);
863 expect2(new DecimalFormat("###E0", US
, status
),
864 1230.0, "1.23E3", status
);
866 expect(new DecimalFormat("0.#E+00", US, status),
867 new Object[] { new Double(0.00012), "1.2E-04",
868 new Long(12000), "1.2E+04",
871 ! Unroll this test into individual tests below...
874 expect2(new DecimalFormat("0.#E+00", US
, status
),
875 0.00012, "1.2E-04", status
);
876 expect2(new DecimalFormat("0.#E+00", US
, status
),
877 (int32_t) 12000, "1.2E+04", status
);
881 * Upgrade to alphaWorks
883 void NumberFormatTest::TestPad(void) {
884 UErrorCode status
= U_ZERO_ERROR
;
885 DecimalFormatSymbols
US(Locale::getUS(), status
);
886 CHECK(status
, "DecimalFormatSymbols constructor");
888 expect2(new DecimalFormat("*^##.##", US
, status
),
889 int32_t(0), "^^^^0", status
);
890 expect2(new DecimalFormat("*^##.##", US
, status
),
891 -1.3, "^-1.3", status
);
892 expect2(new DecimalFormat("##0.0####E0*_ g-m/s^2", US
, status
),
893 int32_t(0), "0.0E0______ g-m/s^2", status
);
894 expect(new DecimalFormat("##0.0####E0*_ g-m/s^2", US
, status
),
895 1.0/3, "333.333E-3_ g-m/s^2", status
);
896 expect2(new DecimalFormat("##0.0####*_ g-m/s^2", US
, status
),
897 int32_t(0), "0.0______ g-m/s^2", status
);
898 expect(new DecimalFormat("##0.0####*_ g-m/s^2", US
, status
),
899 1.0/3, "0.33333__ g-m/s^2", status
);
901 // Test padding before a sign
902 const char *formatStr
= "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
903 expect2(new DecimalFormat(formatStr
, US
, status
),
904 int32_t(-10), "xxxxxxxxxx(10.0)", status
);
905 expect2(new DecimalFormat(formatStr
, US
, status
),
906 int32_t(-1000),"xxxxxxx(1,000.0)", status
);
907 expect2(new DecimalFormat(formatStr
, US
, status
),
908 int32_t(-1000000),"xxx(1,000,000.0)", status
);
909 expect2(new DecimalFormat(formatStr
, US
, status
),
910 -100.37, "xxxxxxxx(100.37)", status
);
911 expect2(new DecimalFormat(formatStr
, US
, status
),
912 -10456.37, "xxxxx(10,456.37)", status
);
913 expect2(new DecimalFormat(formatStr
, US
, status
),
914 -1120456.37, "xx(1,120,456.37)", status
);
915 expect2(new DecimalFormat(formatStr
, US
, status
),
916 -112045600.37, "(112,045,600.37)", status
);
917 expect2(new DecimalFormat(formatStr
, US
, status
),
918 -1252045600.37,"(1,252,045,600.37)", status
);
920 expect2(new DecimalFormat(formatStr
, US
, status
),
921 int32_t(10), "xxxxxxxxxxxx10.0", status
);
922 expect2(new DecimalFormat(formatStr
, US
, status
),
923 int32_t(1000),"xxxxxxxxx1,000.0", status
);
924 expect2(new DecimalFormat(formatStr
, US
, status
),
925 int32_t(1000000),"xxxxx1,000,000.0", status
);
926 expect2(new DecimalFormat(formatStr
, US
, status
),
927 100.37, "xxxxxxxxxx100.37", status
);
928 expect2(new DecimalFormat(formatStr
, US
, status
),
929 10456.37, "xxxxxxx10,456.37", status
);
930 expect2(new DecimalFormat(formatStr
, US
, status
),
931 1120456.37, "xxxx1,120,456.37", status
);
932 expect2(new DecimalFormat(formatStr
, US
, status
),
933 112045600.37, "xx112,045,600.37", status
);
934 expect2(new DecimalFormat(formatStr
, US
, status
),
935 10252045600.37,"10,252,045,600.37", status
);
938 // Test padding between a sign and a number
939 const char *formatStr2
= "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
940 expect2(new DecimalFormat(formatStr2
, US
, status
),
941 int32_t(-10), "(10.0xxxxxxxxxx)", status
);
942 expect2(new DecimalFormat(formatStr2
, US
, status
),
943 int32_t(-1000),"(1,000.0xxxxxxx)", status
);
944 expect2(new DecimalFormat(formatStr2
, US
, status
),
945 int32_t(-1000000),"(1,000,000.0xxx)", status
);
946 expect2(new DecimalFormat(formatStr2
, US
, status
),
947 -100.37, "(100.37xxxxxxxx)", status
);
948 expect2(new DecimalFormat(formatStr2
, US
, status
),
949 -10456.37, "(10,456.37xxxxx)", status
);
950 expect2(new DecimalFormat(formatStr2
, US
, status
),
951 -1120456.37, "(1,120,456.37xx)", status
);
952 expect2(new DecimalFormat(formatStr2
, US
, status
),
953 -112045600.37, "(112,045,600.37)", status
);
954 expect2(new DecimalFormat(formatStr2
, US
, status
),
955 -1252045600.37,"(1,252,045,600.37)", status
);
957 expect2(new DecimalFormat(formatStr2
, US
, status
),
958 int32_t(10), "10.0xxxxxxxxxxxx", status
);
959 expect2(new DecimalFormat(formatStr2
, US
, status
),
960 int32_t(1000),"1,000.0xxxxxxxxx", status
);
961 expect2(new DecimalFormat(formatStr2
, US
, status
),
962 int32_t(1000000),"1,000,000.0xxxxx", status
);
963 expect2(new DecimalFormat(formatStr2
, US
, status
),
964 100.37, "100.37xxxxxxxxxx", status
);
965 expect2(new DecimalFormat(formatStr2
, US
, status
),
966 10456.37, "10,456.37xxxxxxx", status
);
967 expect2(new DecimalFormat(formatStr2
, US
, status
),
968 1120456.37, "1,120,456.37xxxx", status
);
969 expect2(new DecimalFormat(formatStr2
, US
, status
),
970 112045600.37, "112,045,600.37xx", status
);
971 expect2(new DecimalFormat(formatStr2
, US
, status
),
972 10252045600.37,"10,252,045,600.37", status
);
974 //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
975 DecimalFormat
fmt("#", US
, status
);
976 CHECK(status
, "DecimalFormat constructor");
977 UnicodeString
padString("P");
978 fmt
.setPadCharacter(padString
);
979 expectPad(fmt
, "*P##.##", DecimalFormat::kPadBeforePrefix
, 5, padString
);
980 fmt
.setPadCharacter((UnicodeString
)"^");
981 expectPad(fmt
, "*^#", DecimalFormat::kPadBeforePrefix
, 1, (UnicodeString
)"^");
982 //commented untill implementation is complete
983 /* fmt.setPadCharacter((UnicodeString)"^^^");
984 expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
986 padString.append((UChar)0x0061);
987 padString.append((UChar)0x0302);
988 fmt.setPadCharacter(padString);
989 UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
990 UnicodeString pattern(patternChars);
991 expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
997 * Upgrade to alphaWorks
999 void NumberFormatTest::TestPatterns2(void) {
1000 UErrorCode status
= U_ZERO_ERROR
;
1001 DecimalFormatSymbols
US(Locale::getUS(), status
);
1002 CHECK(status
, "DecimalFormatSymbols constructor");
1004 DecimalFormat
fmt("#", US
, status
);
1005 CHECK(status
, "DecimalFormat constructor");
1007 UChar hat
= 0x005E; /*^*/
1009 expectPad(fmt
, "*^#", DecimalFormat::kPadBeforePrefix
, 1, hat
);
1010 expectPad(fmt
, "$*^#", DecimalFormat::kPadAfterPrefix
, 2, hat
);
1011 expectPad(fmt
, "#*^", DecimalFormat::kPadBeforeSuffix
, 1, hat
);
1012 expectPad(fmt
, "#$*^", DecimalFormat::kPadAfterSuffix
, 2, hat
);
1013 expectPad(fmt
, "$*^$#", ILLEGAL
);
1014 expectPad(fmt
, "#$*^$", ILLEGAL
);
1015 expectPad(fmt
, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix
,
1016 12, (UChar
)0x0078 /*x*/);
1017 expectPad(fmt
, "''#0*x", DecimalFormat::kPadBeforeSuffix
,
1018 3, (UChar
)0x0078 /*x*/);
1019 expectPad(fmt
, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix
,
1020 10, (UChar
)0x0061 /*a*/);
1022 fmt
.applyPattern("AA#,##0.00ZZ", status
);
1023 CHECK(status
, "applyPattern");
1024 fmt
.setPadCharacter(hat
);
1026 fmt
.setFormatWidth(10);
1028 fmt
.setPadPosition(DecimalFormat::kPadBeforePrefix
);
1029 expectPat(fmt
, "*^AA#,##0.00ZZ");
1031 fmt
.setPadPosition(DecimalFormat::kPadBeforeSuffix
);
1032 expectPat(fmt
, "AA#,##0.00*^ZZ");
1034 fmt
.setPadPosition(DecimalFormat::kPadAfterSuffix
);
1035 expectPat(fmt
, "AA#,##0.00ZZ*^");
1038 UnicodeString
exp("AA*^#,##0.00ZZ", "");
1039 fmt
.setFormatWidth(12);
1040 fmt
.setPadPosition(DecimalFormat::kPadAfterPrefix
);
1041 expectPat(fmt
, exp
);
1043 fmt
.setFormatWidth(13);
1045 expectPat(fmt
, "AA*^##,##0.00ZZ");
1047 fmt
.setFormatWidth(14);
1049 expectPat(fmt
, "AA*^###,##0.00ZZ");
1051 fmt
.setFormatWidth(15);
1053 expectPat(fmt
, "AA*^####,##0.00ZZ"); // This is the interesting case
1055 fmt
.setFormatWidth(16);
1056 // 12 34567890123456
1057 expectPat(fmt
, "AA*^#,###,##0.00ZZ");
1060 void NumberFormatTest::TestSurrogateSupport(void) {
1061 UErrorCode status
= U_ZERO_ERROR
;
1062 DecimalFormatSymbols
custom(Locale::getUS(), status
);
1063 CHECK(status
, "DecimalFormatSymbols constructor");
1065 custom
.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
, "decimal");
1066 custom
.setSymbol(DecimalFormatSymbols::kPlusSignSymbol
, "plus");
1067 custom
.setSymbol(DecimalFormatSymbols::kMinusSignSymbol
, " minus ");
1068 custom
.setSymbol(DecimalFormatSymbols::kExponentialSymbol
, "exponent");
1070 UnicodeString
patternStr("*\\U00010000##.##", "");
1071 patternStr
= patternStr
.unescape();
1072 UnicodeString
expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
1073 expStr
= expStr
.unescape();
1074 expect2(new DecimalFormat(patternStr
, custom
, status
),
1075 int32_t(0), expStr
, status
);
1077 status
= U_ZERO_ERROR
;
1078 expect2(new DecimalFormat("*^##.##", custom
, status
),
1079 int32_t(0), "^^^^0", status
);
1080 status
= U_ZERO_ERROR
;
1081 expect2(new DecimalFormat("##.##", custom
, status
),
1082 -1.3, " minus 1decimal3", status
);
1083 status
= U_ZERO_ERROR
;
1084 expect2(new DecimalFormat("##0.0####E0 g'-'m/s^2", custom
, status
),
1085 int32_t(0), "0decimal0exponent0 g-m/s^2", status
);
1086 status
= U_ZERO_ERROR
;
1087 expect(new DecimalFormat("##0.0####E0 g'-'m/s^2", custom
, status
),
1088 1.0/3, "333decimal333exponent minus 3 g-m/s^2", status
);
1089 status
= U_ZERO_ERROR
;
1090 expect2(new DecimalFormat("##0.0#### g'-'m/s^2", custom
, status
),
1091 int32_t(0), "0decimal0 g-m/s^2", status
);
1092 status
= U_ZERO_ERROR
;
1093 expect(new DecimalFormat("##0.0#### g'-'m/s^2", custom
, status
),
1094 1.0/3, "0decimal33333 g-m/s^2", status
);
1096 UnicodeString
zero((UChar32
)0x10000);
1097 custom
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, zero
);
1098 expStr
= UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
1099 expStr
= expStr
.unescape();
1100 status
= U_ZERO_ERROR
;
1101 expect2(new DecimalFormat("##0.000", custom
, status
),
1102 1.25, expStr
, status
);
1104 custom
.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol
, (UChar
)0x30);
1105 custom
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "units of money");
1106 custom
.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
, "money separator");
1107 patternStr
= "0.00 \\u00A4' in your bank account'";
1108 patternStr
= patternStr
.unescape();
1109 expStr
= UnicodeString(" minus 20money separator00 units of money in your bank account", "");
1110 status
= U_ZERO_ERROR
;
1111 expect2(new DecimalFormat(patternStr
, custom
, status
),
1112 int32_t(-20), expStr
, status
);
1114 custom
.setSymbol(DecimalFormatSymbols::kPercentSymbol
, "percent");
1115 patternStr
= "'You''ve lost ' -0.00 %' of your money today'";
1116 patternStr
= patternStr
.unescape();
1117 expStr
= UnicodeString(" minus You've lost minus 2000decimal00 percent of your money today", "");
1118 status
= U_ZERO_ERROR
;
1119 expect2(new DecimalFormat(patternStr
, custom
, status
),
1120 int32_t(-20), expStr
, status
);
1123 void NumberFormatTest::TestCurrencyPatterns(void) {
1124 int32_t i
, locCount
;
1125 const Locale
* locs
= NumberFormat::getAvailableLocales(locCount
);
1126 for (i
=0; i
<locCount
; ++i
) {
1127 UErrorCode ec
= U_ZERO_ERROR
;
1128 NumberFormat
* nf
= NumberFormat::createCurrencyInstance(locs
[i
], ec
);
1129 if (U_FAILURE(ec
)) {
1130 errln("FAIL: Can't create NumberFormat");
1132 // Make sure currency formats do not have a variable number
1133 // of fraction digits
1134 int32_t min
= nf
->getMinimumFractionDigits();
1135 int32_t max
= nf
->getMaximumFractionDigits();
1139 nf
->format(1.125, b
);
1140 errln((UnicodeString
)"FAIL: " + locs
[i
].getName() +
1141 " min fraction digits != max fraction digits; "
1142 "x 1.0 => " + escape(a
) +
1143 "; x 1.125 => " + escape(b
));
1146 // Make sure EURO currency formats have exactly 2 fraction digits
1147 if (nf
->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
1148 DecimalFormat
* df
= (DecimalFormat
*) nf
;
1149 if (u_strcmp(EUR
, df
->getCurrency()) == 0) {
1150 if (min
!= 2 || max
!= 2) {
1153 errln((UnicodeString
)"FAIL: " + locs
[i
].getName() +
1154 " is a EURO format but it does not have 2 fraction digits; "
1165 void NumberFormatTest::TestRegCurrency(void) {
1166 UErrorCode status
= U_ZERO_ERROR
;
1167 const UChar
* USD
= ucurr_forLocale("en_US", &status
);
1168 const UChar
* YEN
= ucurr_forLocale("ja_JP", &status
);
1169 if(U_FAILURE(status
)) {
1170 errln("Unable to get currency for locale, error %s", u_errorName(status
));
1174 UCurrRegistryKey enkey
= ucurr_register(YEN
, "en_US", &status
);
1175 UCurrRegistryKey enUSEUROkey
= ucurr_register(EUR
, "en_US_EURO", &status
);
1177 if (u_strcmp(YEN
, ucurr_forLocale("en_US", &status
)) != 0) {
1178 errln("FAIL: didn't return YEN registered for en_US");
1181 if (u_strcmp(EUR
, ucurr_forLocale("en_US_EURO", &status
)) != 0) {
1182 errln("FAIL: didn't return EUR for en_US_EURO");
1185 if (ucurr_forLocale("en_XX_BAR", &status
) != NULL
) {
1186 errln("FAIL: tried to fallback en_XX_BAR");
1188 status
= U_ZERO_ERROR
; // reset
1190 if (!ucurr_unregister(enkey
, &status
)) {
1191 errln("FAIL: couldn't unregister enkey");
1194 if (u_strcmp(USD
, ucurr_forLocale("en_US", &status
)) != 0) {
1195 errln("FAIL: didn't return USD for en_US after unregister of en_US");
1197 status
= U_ZERO_ERROR
; // reset
1199 if (u_strcmp(EUR
, ucurr_forLocale("en_US_EURO", &status
)) != 0) {
1200 errln("FAIL: didn't return EUR for en_US_EURO after unregister of en_US");
1203 if (u_strcmp(USD
, ucurr_forLocale("en_US_BLAH", &status
)) != 0) {
1204 errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
1206 status
= U_ZERO_ERROR
; // reset
1208 if (!ucurr_unregister(enUSEUROkey
, &status
)) {
1209 errln("FAIL: couldn't unregister enUSEUROkey");
1212 if (ucurr_forLocale("en_US_EURO", &status
) != NULL
) {
1213 errln("FAIL: didn't return NULL for en_US_EURO after unregister of en_US_EURO");
1215 status
= U_ZERO_ERROR
; // reset
1218 void NumberFormatTest::TestSymbolsWithBadLocale(void) {
1220 Locale
locBad("x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME");
1221 UErrorCode status
= U_ZERO_ERROR
;
1222 UnicodeString
intlCurrencySymbol((UChar
)0xa4);
1224 intlCurrencySymbol
.append((UChar
)0xa4);
1226 logln("Current locale is %s", Locale::getDefault().getName());
1227 Locale::setDefault(locBad
, status
);
1228 logln("Current locale is %s", Locale::getDefault().getName());
1229 DecimalFormatSymbols
mySymbols(status
);
1230 if (status
!= U_USING_FALLBACK_WARNING
) {
1231 errln("DecimalFormatSymbols should returned U_USING_FALLBACK_WARNING.");
1233 if (strcmp(mySymbols
.getLocale().getName(), locBad
.getName()) != 0) {
1234 errln("DecimalFormatSymbols does not have the right locale.");
1236 DecimalFormatSymbols::ENumberFormatSymbol symbolEnum
;
1237 int *symbolEnumPtr
= (int*)(&symbolEnum
);
1238 for (symbolEnum
= DecimalFormatSymbols::kDecimalSeparatorSymbol
; symbolEnum
< DecimalFormatSymbols::kFormatSymbolCount
; (*symbolEnumPtr
)++) {
1239 if (mySymbols
.getSymbol(symbolEnum
).length() == 0 && symbolEnum
!= DecimalFormatSymbols::kGroupingSeparatorSymbol
) {
1240 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum
);
1243 status
= U_ZERO_ERROR
;
1244 Locale::setDefault(locDefault
, status
);
1245 logln("Current locale is %s", Locale::getDefault().getName());
1249 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
1250 * behave the same, except for memory ownership semantics. (No
1251 * version of this test on Java, since Java has only one method.)
1253 void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
1254 UErrorCode ec
= U_ZERO_ERROR
;
1255 DecimalFormatSymbols
*sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
1256 if (U_FAILURE(ec
)) {
1257 errln("Fail: DecimalFormatSymbols constructor");
1261 UnicodeString
pat(" #,##0.00");
1262 pat
.insert(0, (UChar
)0x00A4);
1263 DecimalFormat
fmt(pat
, sym
, ec
);
1264 if (U_FAILURE(ec
)) {
1265 errln("Fail: DecimalFormat constructor");
1270 fmt
.format(2350.75, str
);
1271 if (str
== "$ 2,350.75") {
1274 errln("Fail: " + str
+ ", expected $ 2,350.75");
1277 sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
1278 if (U_FAILURE(ec
)) {
1279 errln("Fail: DecimalFormatSymbols constructor");
1283 sym
->setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "Q");
1284 fmt
.adoptDecimalFormatSymbols(sym
);
1287 fmt
.format(2350.75, str
);
1288 if (str
== "Q 2,350.75") {
1291 errln("Fail: adoptDecimalFormatSymbols -> " + str
+ ", expected Q 2,350.75");
1294 sym
= new DecimalFormatSymbols(Locale::getUS(), ec
);
1295 if (U_FAILURE(ec
)) {
1296 errln("Fail: DecimalFormatSymbols constructor");
1300 DecimalFormat
fmt2(pat
, sym
, ec
);
1301 if (U_FAILURE(ec
)) {
1302 errln("Fail: DecimalFormat constructor");
1306 DecimalFormatSymbols
sym2(Locale::getUS(), ec
);
1307 if (U_FAILURE(ec
)) {
1308 errln("Fail: DecimalFormatSymbols constructor");
1311 sym2
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, "Q");
1312 fmt2
.setDecimalFormatSymbols(sym2
);
1315 fmt2
.format(2350.75, str
);
1316 if (str
== "Q 2,350.75") {
1319 errln("Fail: setDecimalFormatSymbols -> " + str
+ ", expected Q 2,350.75");
1323 //----------------------------------------------------------------------
1325 //----------------------------------------------------------------------
1327 UBool
NumberFormatTest::equalValue(const Formattable
& a
, const Formattable
& b
) {
1328 if (a
.getType() == Formattable::kLong
) {
1329 if (b
.getType() == Formattable::kLong
) {
1330 return a
.getLong() == b
.getLong();
1331 } else if (b
.getType() == Formattable::kDouble
) {
1332 return (double) a
.getLong() == b
.getDouble();
1334 } else if (a
.getType() == Formattable::kDouble
) {
1335 if (b
.getType() == Formattable::kLong
) {
1336 return a
.getDouble() == (double) b
.getLong();
1337 } else if (b
.getType() == Formattable::kDouble
) {
1338 return a
.getDouble() == b
.getDouble();
1344 void NumberFormatTest::expect2(NumberFormat
& fmt
, const Formattable
& n
, const UnicodeString
& str
) {
1345 // Don't round-trip format test, since we explicitly do it
1346 expect(fmt
, n
, str
, FALSE
);
1347 expect(fmt
, str
, n
);
1350 void NumberFormatTest::expect2(NumberFormat
* fmt
, const Formattable
& n
,
1351 const UnicodeString
& exp
,
1352 UErrorCode status
) {
1353 if (U_FAILURE(status
)) {
1354 errln("FAIL: NumberFormat constructor");
1356 expect2(*fmt
, n
, exp
);
1361 void NumberFormatTest::expect(NumberFormat
& fmt
, const UnicodeString
& str
, const Formattable
& n
) {
1362 UErrorCode status
= U_ZERO_ERROR
;
1364 fmt
.parse(str
, num
, status
);
1365 if (U_FAILURE(status
)) {
1366 errln(UnicodeString("FAIL: Parse failed for \"") + str
+ "\"");
1370 ((DecimalFormat
*) &fmt
)->toPattern(pat
);
1371 if (equalValue(num
, n
)) {
1372 logln(UnicodeString("Ok \"") + str
+ "\" x " +
1376 errln(UnicodeString("FAIL \"") + str
+ "\" x " +
1378 toString(num
) + ", expected " + toString(n
));
1382 void NumberFormatTest::expect(NumberFormat
& fmt
, const Formattable
& n
,
1383 const UnicodeString
& exp
, UBool rt
) {
1386 UErrorCode status
= U_ZERO_ERROR
;
1387 fmt
.format(n
, saw
, pos
, status
);
1388 CHECK(status
, "NumberFormat::format");
1390 ((DecimalFormat
*) &fmt
)->toPattern(pat
);
1392 logln(UnicodeString("Ok ") + toString(n
) + " x " +
1393 escape(pat
) + " = \"" +
1394 escape(saw
) + "\"");
1395 // We should be able to round-trip the formatted string =>
1396 // number => string (but not the other way around: number
1397 // => string => number2, might have number2 != number):
1400 fmt
.parse(exp
, n2
, status
);
1401 if (U_FAILURE(status
)) {
1402 errln(UnicodeString("FAIL: Parse failed for \"") + exp
+ "\"");
1406 fmt
.format(n2
, saw2
, pos
, status
);
1407 CHECK(status
, "NumberFormat::format");
1409 errln((UnicodeString
)"FAIL \"" + exp
+ "\" => " + toString(n2
) +
1410 " => \"" + saw2
+ "\"");
1414 errln(UnicodeString("FAIL ") + toString(n
) + " x " +
1415 escape(pat
) + " = \"" +
1416 escape(saw
) + "\", expected \"" + exp
+ "\"");
1420 void NumberFormatTest::expect(NumberFormat
* fmt
, const Formattable
& n
,
1421 const UnicodeString
& exp
,
1422 UErrorCode status
) {
1423 if (U_FAILURE(status
)) {
1424 errln("FAIL: NumberFormat constructor");
1426 expect(*fmt
, n
, exp
);
1431 void NumberFormatTest::expectCurrency(NumberFormat
& nf
, const Locale
& locale
,
1432 double value
, const UnicodeString
& string
) {
1433 UErrorCode ec
= U_ZERO_ERROR
;
1434 DecimalFormat
& fmt
= * (DecimalFormat
*) &nf
;
1435 const UChar DEFAULT_CURR
[] = {45/*-*/,0};
1436 const UChar
* curr
= DEFAULT_CURR
;
1437 if (*locale
.getLanguage() != 0) {
1438 curr
= ucurr_forLocale(locale
.getName(), &ec
);
1439 if (U_FAILURE(ec
)) {
1440 errln("FAIL: UCurrency::forLocale");
1443 fmt
.setCurrency(curr
);
1446 fmt
.format(value
, s
);
1447 s
.findAndReplace((UChar32
)0x00A0, (UChar32
)0x0020);
1449 // Default display of the number yields "1234.5599999999999"
1450 // instead of "1234.56". Use a formatter to fix this.
1452 NumberFormat::createInstance(Locale::getUS(), ec
);
1454 if (U_FAILURE(ec
)) {
1455 // Oops; bad formatter. Use default op+= display.
1456 v
= (UnicodeString
)"" + value
;
1458 f
->setMaximumFractionDigits(4);
1459 f
->setGroupingUsed(FALSE
);
1460 f
->format(value
, v
);
1465 logln((UnicodeString
)"Ok: " + v
+ " x " + curr
+ " => " + prettify(s
));
1467 errln((UnicodeString
)"FAIL: " + v
+ " x " + curr
+ " => " + prettify(s
) +
1468 ", expected " + prettify(string
));
1472 void NumberFormatTest::expectPat(DecimalFormat
& fmt
, const UnicodeString
& exp
) {
1476 logln(UnicodeString("Ok \"") + pat
+ "\"");
1478 errln(UnicodeString("FAIL \"") + pat
+ "\", expected \"" + exp
+ "\"");
1482 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
1484 expectPad(fmt
, pat
, pos
, 0, (UnicodeString
)"");
1486 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
1487 int32_t pos
, int32_t width
, UChar pad
) {
1488 expectPad(fmt
, pat
, pos
, width
, UnicodeString(pad
));
1490 void NumberFormatTest::expectPad(DecimalFormat
& fmt
, const UnicodeString
& pat
,
1491 int32_t pos
, int32_t width
, const UnicodeString
& pad
) {
1492 int32_t apos
= 0, awidth
= 0;
1493 UnicodeString apadStr
;
1494 UErrorCode status
= U_ZERO_ERROR
;
1495 fmt
.applyPattern(pat
, status
);
1496 if (U_SUCCESS(status
)) {
1497 apos
= fmt
.getPadPosition();
1498 awidth
= fmt
.getFormatWidth();
1499 apadStr
=fmt
.getPadCharacterString();
1505 if (apos
== pos
&& awidth
== width
&& apadStr
== pad
) {
1506 logln(UnicodeString("Ok \"") + pat
+ "\" pos=" + apos
+
1507 ((pos
== ILLEGAL
) ? UnicodeString() :
1508 (UnicodeString(" width=") + awidth
+ " pad=" + apadStr
)));
1510 errln(UnicodeString("FAIL \"") + pat
+ "\" pos=" + apos
+
1511 " width=" + awidth
+ " pad=" + apadStr
+
1512 ", expected " + pos
+ " " + width
+ " " + pad
);
1516 #endif /* #if !UCONFIG_NO_FORMATTING */