]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/numfmtst.cpp
ICU-8.11.tar.gz
[apple/icu.git] / icuSources / test / intltest / numfmtst.cpp
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
73c04bcf 3 * Copyright (c) 1997-2006, International Business Machines Corporation and
b75a7d8f
A
4 * others. All Rights Reserved.
5 ********************************************************************/
6/* Modification History:
7* Date Name Description
8* 07/15/99 helena Ported to HPUX 10/11 CC.
9*/
10
11#include "unicode/utypes.h"
12
13#if !UCONFIG_NO_FORMATTING
14
15#include "numfmtst.h"
16#include "unicode/dcfmtsym.h"
17#include "unicode/decimfmt.h"
18#include "unicode/ucurr.h"
19#include "unicode/ustring.h"
374ca955
A
20#include "unicode/measfmt.h"
21#include "unicode/curramt.h"
22#include "digitlst.h"
23#include "textfile.h"
24#include "tokiter.h"
25#include "charstr.h"
26#include "putilimp.h"
73c04bcf 27#include "winnmtst.h"
b75a7d8f
A
28#include <float.h>
29#include <string.h>
b75a7d8f
A
30
31static const UChar EUR[] = {69,85,82,0}; // "EUR"
32
33// *****************************************************************************
34// class NumberFormatTest
35// *****************************************************************************
36
37#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
38
39#define CHECK(status,str) if (U_FAILURE(status)) { errln(UnicodeString("FAIL: ") + str); return; }
40
41void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
42{
43 // if (exec) logln((UnicodeString)"TestSuite DateFormatTest");
44 switch (index) {
45 CASE(0,TestCurrencySign);
46 CASE(1,TestCurrency);
47 CASE(2,TestParse);
48 CASE(3,TestRounding487);
49 CASE(4,TestQuotes);
50 CASE(5,TestExponential);
51 CASE(6,TestPatterns);
52
53 // Upgrade to alphaWorks - liu 5/99
54 CASE(7,TestExponent);
55 CASE(8,TestScientific);
56 CASE(9,TestPad);
57 CASE(10,TestPatterns2);
58 CASE(11,TestSecondaryGrouping);
59 CASE(12,TestSurrogateSupport);
60 CASE(13,TestAPI);
61
62 CASE(14,TestCurrencyObject);
63 CASE(15,TestCurrencyPatterns);
64 CASE(16,TestDigitList);
65 CASE(17,TestWhiteSpaceParsing);
66 CASE(18,TestComplexCurrency);
67 CASE(19,TestRegCurrency);
68 CASE(20,TestSymbolsWithBadLocale);
69 CASE(21,TestAdoptDecimalFormatSymbols);
70
374ca955
A
71 CASE(22,TestScientific2);
72 CASE(23,TestScientificGrouping);
73 CASE(24,TestInt64);
74
75 CASE(25,TestPerMill);
76 CASE(26,TestIllegalPatterns);
77 CASE(27,TestCases);
78
79 CASE(28,TestCurrencyNames);
73c04bcf
A
80 CASE(29,TestCurrencyAmount);
81 CASE(30,TestCurrencyUnit);
82 CASE(31,TestCoverage);
83 CASE(32,TestJB3832);
84 CASE(33,TestHost);
85 CASE(34,TestCurrencyFormat);
b75a7d8f
A
86 default: name = ""; break;
87 }
88}
89
90// -------------------------------------
91
92// Test API (increase code coverage)
93void
94NumberFormatTest::TestAPI(void)
95{
96 logln("Test API");
97 UErrorCode status = U_ZERO_ERROR;
98 NumberFormat *test = NumberFormat::createInstance("root", status);
99 if(U_FAILURE(status)) {
100 errln("unable to create format object");
101 }
102 if(test != NULL) {
103 test->setMinimumIntegerDigits(10);
104 test->setMaximumIntegerDigits(2);
105
106 test->setMinimumFractionDigits(10);
107 test->setMaximumFractionDigits(2);
108
109 UnicodeString result;
110 FieldPosition pos;
111 Formattable bla("Paja Patak"); // Donald Duck for non Serbian speakers
112 test->format(bla, result, pos, status);
113 if(U_SUCCESS(status)) {
114 errln("Yuck... Formatted a duck... As a number!");
115 } else {
116 status = U_ZERO_ERROR;
117 }
118
73c04bcf
A
119 result.remove();
120 int64_t ll = 12;
121 test->format(ll, result);
122 if (result != "12.00"){
123 errln("format int64_t error");
124 }
125
b75a7d8f
A
126 delete test;
127 }
b75a7d8f
A
128}
129
73c04bcf
A
130class StubNumberForamt :public NumberFormat{
131public:
132 StubNumberForamt(){};
133 virtual UnicodeString& format(double ,UnicodeString& appendTo,FieldPosition& ) const {
134 return appendTo;
135 }
136 virtual UnicodeString& format(int32_t ,UnicodeString& appendTo,FieldPosition& ) const {
137 return appendTo.append((UChar)0x0033);
138 }
139 virtual UnicodeString& format(int64_t number,UnicodeString& appendTo,FieldPosition& pos) const {
140 return NumberFormat::format(number, appendTo, pos);
141 }
142 virtual UnicodeString& format(const Formattable& , UnicodeString& appendTo, FieldPosition& , UErrorCode& ) const {
143 return appendTo;
144 }
145 virtual void parse(const UnicodeString& ,
146 Formattable& ,
147 ParsePosition& ) const {}
148 virtual void parse( const UnicodeString& ,
149 Formattable& ,
150 UErrorCode& ) const {}
151 virtual UClassID getDynamicClassID(void) const {
152 static char classID = 0;
153 return (UClassID)&classID;
154 }
155 virtual Format* clone() const {return NULL;}
156};
157
158void
159NumberFormatTest::TestCoverage(void){
160 StubNumberForamt stub;
161 UnicodeString agent("agent");
162 FieldPosition pos;
163 int64_t num = 4;
164 if (stub.format(num, agent, pos) != UnicodeString("agent3")){
165 errln("NumberFormat::format(int64, UnicodString&, FieldPosition&) should delegate to (int32, ,)");
166 };
167}
168
b75a7d8f
A
169// Test various patterns
170void
171NumberFormatTest::TestPatterns(void)
172{
173 UErrorCode status = U_ZERO_ERROR;
174 DecimalFormatSymbols sym(Locale::getUS(), status);
175 if (U_FAILURE(status)) { errln("FAIL: Could not construct DecimalFormatSymbols"); return; }
176
177 const char* pat[] = { "#.#", "#.", ".#", "#" };
178 int32_t pat_length = (int32_t)(sizeof(pat) / sizeof(pat[0]));
179 const char* newpat[] = { "#0.#", "#0.", "#.0", "#" };
180 const char* num[] = { "0", "0.", ".0", "0" };
181 for (int32_t i=0; i<pat_length; ++i)
182 {
183 status = U_ZERO_ERROR;
184 DecimalFormat fmt(pat[i], sym, status);
185 if (U_FAILURE(status)) { errln((UnicodeString)"FAIL: DecimalFormat constructor failed for " + pat[i]); continue; }
186 UnicodeString newp; fmt.toPattern(newp);
187 if (!(newp == newpat[i]))
188 errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] +
189 "; " + newp + " seen instead");
190
191 UnicodeString s; (*(NumberFormat*)&fmt).format((int32_t)0, s);
192 if (!(s == num[i]))
193 {
194 errln((UnicodeString)"FAIL: Pattern " + pat[i] + " should format zero as " + num[i] +
195 "; " + s + " seen instead");
196 logln((UnicodeString)"Min integer digits = " + fmt.getMinimumIntegerDigits());
197 }
198 }
199}
200
201void
202NumberFormatTest::TestDigitList(void)
203{
204 // API coverage for DigitList
205 /*
206 icu_2_4::DigitList::operator== 0 0 2 icuuc24d.dll digitlst.cpp Doug
207 icu_2_4::DigitList::append 0 0 4 icuin24d.dll digitlst.h Doug
208 icu_2_4::DigitList::operator!= 0 0 1 icuuc24d.dll digitlst.h Doug
209 */
210 DigitList list1;
211 list1.append('1');
212 list1.fDecimalAt = 1;
213 DigitList list2;
374ca955 214 list2.set((int32_t)1);
b75a7d8f
A
215 if (list1 != list2) {
216 errln("digitlist append, operator!= or set failed ");
217 }
218 if (!(list1 == list2)) {
219 errln("digitlist append, operator== or set failed ");
220 }
221}
222
223// -------------------------------------
224
225// Test exponential pattern
226void
227NumberFormatTest::TestExponential(void)
228{
229 UErrorCode status = U_ZERO_ERROR;
230 DecimalFormatSymbols sym(Locale::getUS(), status);
231 if (U_FAILURE(status)) { errln("FAIL: Bad status returned by DecimalFormatSymbols ct"); return; }
232 const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
233 int32_t pat_length = (int32_t)(sizeof(pat) / sizeof(pat[0]));
234
235// The following #if statements allow this test to be built and run on
236// platforms that do not have standard IEEE numerics. For example,
237// S/390 doubles have an exponent range of -78 to +75. For the
238// following #if statements to work, float.h must define
239// DBL_MAX_10_EXP to be a compile-time constant.
240
241// This section may be expanded as needed.
242
243#if DBL_MAX_10_EXP > 300
244 double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
245 int32_t val_length = (int32_t)(sizeof(val) / sizeof(val[0]));
246 const char* valFormat[] =
247 {
248 // 0.####E0
249 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
250 // 00.000E00
251 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
252 // ##0.######E000
253 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
254 // 0.###E0;[0.###E0]
255 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
256 };
257 double valParse[] =
258 {
259 0.01234, 123460000, 1.23E300, -3.1416E-271,
260 0.01234, 123460000, 1.23E300, -3.1416E-271,
261 0.01234, 123456800, 1.23E300, -3.141593E-271,
262 0.01234, 123500000, 1.23E300, -3.142E-271,
263 };
264#elif DBL_MAX_10_EXP > 70
265 double val[] = { 0.01234, 123456789, 1.23e70, -3.141592653e-71 };
266 int32_t val_length = sizeof(val) / sizeof(val[0]);
267 char* valFormat[] =
268 {
269 // 0.####E0
270 "1.234E-2", "1.2346E8", "1.23E70", "-3.1416E-71",
271 // 00.000E00
272 "12.340E-03", "12.346E07", "12.300E69", "-31.416E-72",
273 // ##0.######E000
274 "12.34E-003", "123.4568E006", "12.3E069", "-31.41593E-072",
275 // 0.###E0;[0.###E0]
276 "1.234E-2", "1.235E8", "1.23E70", "[3.142E-71]"
277 };
278 double valParse[] =
279 {
280 0.01234, 123460000, 1.23E70, -3.1416E-71,
281 0.01234, 123460000, 1.23E70, -3.1416E-71,
282 0.01234, 123456800, 1.23E70, -3.141593E-71,
283 0.01234, 123500000, 1.23E70, -3.142E-71,
284 };
285#else
286 // Don't test double conversion
287 double* val = 0;
288 int32_t val_length = 0;
289 char** valFormat = 0;
290 double* valParse = 0;
291 logln("Warning: Skipping double conversion tests");
292#endif
293
294 int32_t lval[] = { 0, -1, 1, 123456789 };
295 int32_t lval_length = (int32_t)(sizeof(lval) / sizeof(lval[0]));
296 const char* lvalFormat[] =
297 {
298 // 0.####E0
299 "0E0", "-1E0", "1E0", "1.2346E8",
300 // 00.000E00
301 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
302 // ##0.######E000
303 "0E000", "-1E000", "1E000", "123.4568E006",
304 // 0.###E0;[0.###E0]
305 "0E0", "[1E0]", "1E0", "1.235E8"
306 };
307 int32_t lvalParse[] =
308 {
309 0, -1, 1, 123460000,
310 0, -1, 1, 123460000,
311 0, -1, 1, 123456800,
312 0, -1, 1, 123500000,
313 };
314 int32_t ival = 0, ilval = 0;
315 for (int32_t p=0; p<pat_length; ++p)
316 {
317 DecimalFormat fmt(pat[p], sym, status);
318 if (U_FAILURE(status)) { errln("FAIL: Bad status returned by DecimalFormat ct"); continue; }
319 UnicodeString pattern;
320 logln((UnicodeString)"Pattern \"" + pat[p] + "\" -toPattern-> \"" +
321 fmt.toPattern(pattern) + "\"");
322 int32_t v;
323 for (v=0; v<val_length; ++v)
324 {
325 UnicodeString s; (*(NumberFormat*)&fmt).format(val[v], s);
326 logln((UnicodeString)" " + val[v] + " -format-> " + s);
327 if (s != valFormat[v+ival])
328 errln((UnicodeString)"FAIL: Expected " + valFormat[v+ival]);
329
330 ParsePosition pos(0);
331 Formattable af;
332 fmt.parse(s, af, pos);
333 double a;
334 UBool useEpsilon = FALSE;
335 if (af.getType() == Formattable::kLong)
336 a = af.getLong();
337 else if (af.getType() == Formattable::kDouble) {
338 a = af.getDouble();
339#if defined(OS390) || defined(OS400)
340 // S/390 will show a failure like this:
341 //| -3.141592652999999e-271 -format-> -3.1416E-271
342 //| -parse-> -3.1416e-271
343 //| FAIL: Expected -3.141599999999999e-271
344 // To compensate, we use an epsilon-based equality
345 // test on S/390 only. We don't want to do this in
346 // general because it's less exacting.
347 useEpsilon = TRUE;
348#endif
349 }
350 else {
351 errln((UnicodeString)"FAIL: Non-numeric Formattable returned");
352 continue;
353 }
354 if (pos.getIndex() == s.length())
355 {
356 logln((UnicodeString)" -parse-> " + a);
357 // Use epsilon comparison as necessary
358 if ((useEpsilon &&
359 (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) ||
360 (!useEpsilon && a != valParse[v+ival]))
361 {
362 errln((UnicodeString)"FAIL: Expected " + valParse[v+ival]);
363 }
364 }
365 else {
366 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
367 errln((UnicodeString)" should be (" + s.length() + " chars) -> " + valParse[v+ival]);
368 }
369 }
370 for (v=0; v<lval_length; ++v)
371 {
372 UnicodeString s;
373 (*(NumberFormat*)&fmt).format(lval[v], s);
374 logln((UnicodeString)" " + lval[v] + "L -format-> " + s);
375 if (s != lvalFormat[v+ilval])
376 errln((UnicodeString)"ERROR: Expected " + lvalFormat[v+ilval] + " Got: " + s);
377
378 ParsePosition pos(0);
379 Formattable af;
380 fmt.parse(s, af, pos);
374ca955
A
381 if (af.getType() == Formattable::kLong ||
382 af.getType() == Formattable::kInt64) {
383 UErrorCode status = U_ZERO_ERROR;
384 int32_t a = af.getLong(status);
b75a7d8f
A
385 if (pos.getIndex() == s.length())
386 {
387 logln((UnicodeString)" -parse-> " + a);
388 if (a != lvalParse[v+ilval])
389 errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval]);
390 }
391 else
392 errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
393 }
394 else
395 errln((UnicodeString)"FAIL: Non-long Formattable returned for " + s
396 + " Double: " + af.getDouble()
397 + ", Long: " + af.getLong());
398 }
399 ival += val_length;
400 ilval += lval_length;
401 }
402}
403
374ca955
A
404void
405NumberFormatTest::TestScientific2() {
406 // jb 2552
407 UErrorCode status = U_ZERO_ERROR;
408 DecimalFormat* fmt = (DecimalFormat*)NumberFormat::createCurrencyInstance("en_US", status);
409 if (U_SUCCESS(status)) {
410 double num = 12.34;
411 expect(*fmt, num, "$12.34");
412 fmt->setScientificNotation(TRUE);
413 expect(*fmt, num, "$1.23E1");
414 fmt->setScientificNotation(FALSE);
415 expect(*fmt, num, "$12.34");
416 }
417 delete fmt;
418}
419
420void
421NumberFormatTest::TestScientificGrouping() {
422 // jb 2552
423 UErrorCode status = U_ZERO_ERROR;
424 DecimalFormat fmt("##0.00E0",status);
425 if (U_SUCCESS(status)) {
426 expect(fmt, .01234, "12.3E-3");
427 expect(fmt, .1234, "123E-3");
428 expect(fmt, 1.234, "1.23E0");
429 expect(fmt, 12.34, "12.3E0");
430 expect(fmt, 123.4, "123E0");
431 expect(fmt, 1234., "1.23E3");
432 }
433}
434
435static void setFromString(DigitList& dl, const char* str) {
436 char c;
437 UBool decimalSet = FALSE;
438 dl.clear();
439 while ((c = *str++)) {
440 if (c == '-') {
441 dl.fIsPositive = FALSE;
442 } else if (c == '+') {
443 dl.fIsPositive = TRUE;
444 } else if (c == '.') {
445 dl.fDecimalAt = dl.fCount;
446 decimalSet = TRUE;
447 } else {
448 dl.append(c);
449 }
450 }
451 if (!decimalSet) {
452 dl.fDecimalAt = dl.fCount;
453 }
454}
455
456void
457NumberFormatTest::TestInt64() {
458 UErrorCode status = U_ZERO_ERROR;
459 DecimalFormat fmt("#.#E0",status);
460 fmt.setMaximumFractionDigits(20);
461 if (U_SUCCESS(status)) {
462 expect(fmt, (Formattable)(int64_t)0, "0E0");
463 expect(fmt, (Formattable)(int64_t)-1, "-1E0");
464 expect(fmt, (Formattable)(int64_t)1, "1E0");
465 expect(fmt, (Formattable)(int64_t)2147483647, "2.147483647E9");
466 expect(fmt, (Formattable)((int64_t)-2147483647-1), "-2.147483648E9");
467 expect(fmt, (Formattable)(int64_t)U_INT64_MAX, "9.223372036854775807E18");
468 expect(fmt, (Formattable)(int64_t)U_INT64_MIN, "-9.223372036854775808E18");
469 }
470
471 // also test digitlist
472 int64_t int64max = U_INT64_MAX;
473 int64_t int64min = U_INT64_MIN;
474 const char* int64maxstr = "9223372036854775807";
475 const char* int64minstr = "-9223372036854775808";
476 UnicodeString fail("fail: ");
477
478 // test max int64 value
479 DigitList dl;
480 setFromString(dl, int64maxstr);
481 {
482 if (!dl.fitsIntoInt64(FALSE)) {
483 errln(fail + int64maxstr + " didn't fit");
484 }
485 int64_t int64Value = dl.getInt64();
486 if (int64Value != int64max) {
487 errln(fail + int64maxstr);
488 }
489 dl.set(int64Value);
490 int64Value = dl.getInt64();
491 if (int64Value != int64max) {
492 errln(fail + int64maxstr);
493 }
494 }
495 // test negative of max int64 value (1 shy of min int64 value)
496 dl.fIsPositive = FALSE;
497 {
498 if (!dl.fitsIntoInt64(FALSE)) {
499 errln(fail + "-" + int64maxstr + " didn't fit");
500 }
501 int64_t int64Value = dl.getInt64();
502 if (int64Value != -int64max) {
503 errln(fail + "-" + int64maxstr);
504 }
505 dl.set(int64Value);
506 int64Value = dl.getInt64();
507 if (int64Value != -int64max) {
508 errln(fail + "-" + int64maxstr);
509 }
510 }
511 // test min int64 value
512 setFromString(dl, int64minstr);
513 {
514 if (!dl.fitsIntoInt64(FALSE)) {
515 errln(fail + "-" + int64minstr + " didn't fit");
516 }
517 int64_t int64Value = dl.getInt64();
518 if (int64Value != int64min) {
519 errln(fail + int64minstr);
520 }
521 dl.set(int64Value);
522 int64Value = dl.getInt64();
523 if (int64Value != int64min) {
524 errln(fail + int64minstr);
525 }
526 }
527 // test negative of min int 64 value (1 more than max int64 value)
528 dl.fIsPositive = TRUE; // won't fit
529 {
530 if (dl.fitsIntoInt64(FALSE)) {
531 errln(fail + "-(" + int64minstr + ") didn't fit");
532 }
533 }
534}
535
b75a7d8f
A
536// -------------------------------------
537
538// Test the handling of quotes
539void
540NumberFormatTest::TestQuotes(void)
541{
542 UErrorCode status = U_ZERO_ERROR;
543 UnicodeString *pat;
544 DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), status);
545 pat = new UnicodeString("a'fo''o'b#");
546 DecimalFormat *fmt = new DecimalFormat(*pat, *sym, status);
547 UnicodeString s;
548 ((NumberFormat*)fmt)->format((int32_t)123, s);
549 logln((UnicodeString)"Pattern \"" + *pat + "\"");
550 logln((UnicodeString)" Format 123 -> " + escape(s));
551 if (!(s=="afo'ob123"))
552 errln((UnicodeString)"FAIL: Expected afo'ob123");
553
554 s.truncate(0);
555 delete fmt;
556 delete pat;
557
558 pat = new UnicodeString("a''b#");
559 fmt = new DecimalFormat(*pat, *sym, status);
560 ((NumberFormat*)fmt)->format((int32_t)123, s);
561 logln((UnicodeString)"Pattern \"" + *pat + "\"");
562 logln((UnicodeString)" Format 123 -> " + escape(s));
563 if (!(s=="a'b123"))
564 errln((UnicodeString)"FAIL: Expected a'b123");
565 delete fmt;
566 delete pat;
567 delete sym;
568}
569
570/**
571 * Test the handling of the currency symbol in patterns.
572 */
573void
574NumberFormatTest::TestCurrencySign(void)
575{
576 UErrorCode status = U_ZERO_ERROR;
577 DecimalFormatSymbols* sym = new DecimalFormatSymbols(Locale::getUS(), status);
578 UnicodeString pat;
579 UChar currency = 0x00A4;
580 // "\xA4#,##0.00;-\xA4#,##0.00"
581 pat.append(currency).append("#,##0.00;-").
582 append(currency).append("#,##0.00");
583 DecimalFormat *fmt = new DecimalFormat(pat, *sym, status);
584 UnicodeString s; ((NumberFormat*)fmt)->format(1234.56, s);
585 pat.truncate(0);
586 logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
587 logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
588 if (s != "$1,234.56") errln((UnicodeString)"FAIL: Expected $1,234.56");
589 s.truncate(0);
590 ((NumberFormat*)fmt)->format(- 1234.56, s);
591 logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
592 if (s != "-$1,234.56") errln((UnicodeString)"FAIL: Expected -$1,234.56");
593 delete fmt;
594 pat.truncate(0);
595 // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
596 pat.append(currency).append(currency).
597 append(" #,##0.00;").
598 append(currency).append(currency).
599 append(" -#,##0.00");
600 fmt = new DecimalFormat(pat, *sym, status);
601 s.truncate(0);
602 ((NumberFormat*)fmt)->format(1234.56, s);
603 logln((UnicodeString)"Pattern \"" + fmt->toPattern(pat) + "\"");
604 logln((UnicodeString)" Format " + 1234.56 + " -> " + escape(s));
605 if (s != "USD 1,234.56") errln((UnicodeString)"FAIL: Expected USD 1,234.56");
606 s.truncate(0);
607 ((NumberFormat*)fmt)->format(-1234.56, s);
608 logln((UnicodeString)" Format " + (-1234.56) + " -> " + escape(s));
609 if (s != "USD -1,234.56") errln((UnicodeString)"FAIL: Expected USD -1,234.56");
610 delete fmt;
611 delete sym;
612 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status);
613}
614
615// -------------------------------------
616
617static UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
618
619UnicodeString&
620NumberFormatTest::escape(UnicodeString& s)
621{
622 UnicodeString buf;
623 for (int32_t i=0; i<s.length(); ++i)
624 {
625 UChar c = s[(int32_t)i];
626 if (c <= (UChar)0x7F) buf += c;
627 else {
628 buf += (UChar)0x5c; buf += (UChar)0x55;
629 buf += toHexString((c & 0xF000) >> 12);
630 buf += toHexString((c & 0x0F00) >> 8);
631 buf += toHexString((c & 0x00F0) >> 4);
632 buf += toHexString(c & 0x000F);
633 }
634 }
635 return (s = buf);
636}
637
638
639// -------------------------------------
374ca955
A
640static const char* testCases[][2]= {
641 /* locale ID */ /* expected */
642 {"ca_ES_PREEURO", "\\u20A7 1.150" },
643 {"de_LU_PREEURO", "1,150 F" },
644 {"el_GR_PREEURO", "1.150,50 \\u0394\\u03C1\\u03C7" },
645 {"en_BE_PREEURO", "1.150,50 BF" },
646 {"es_ES_PREEURO", "1.150 \\u20A7" },
647 {"eu_ES_PREEURO", "\\u20A7 1.150" },
648 {"gl_ES_PREEURO", "\\u20A7 1.150" },
649 {"it_IT_PREEURO", "\\u20A4 1.150" },
73c04bcf
A
650 {"pt_PT_PREEURO", "1,150$50 Esc."},
651 {"en_US@currency=JPY", "\\u00A51,150"}
374ca955 652};
b75a7d8f
A
653/**
654 * Test localized currency patterns.
655 */
656void
657NumberFormatTest::TestCurrency(void)
658{
659 UErrorCode status = U_ZERO_ERROR;
660 NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
73c04bcf
A
661 if (U_FAILURE(status)) {
662 dataerrln("Error calling NumberFormat::createCurrencyInstance()");
663 return;
664 }
665
b75a7d8f
A
666 UnicodeString s; currencyFmt->format(1.50, s);
667 logln((UnicodeString)"Un pauvre ici a..........." + s);
668 if (!(s=="1,50 $"))
669 errln((UnicodeString)"FAIL: Expected 1,50 $");
670 delete currencyFmt;
671 s.truncate(0);
374ca955
A
672 char loc[256]={0};
673 int len = uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
674 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc),status);
b75a7d8f
A
675 currencyFmt->format(1.50, s);
676 logln((UnicodeString)"Un pauvre en Allemagne a.." + s);
677 if (!(s=="1,50 DM"))
678 errln((UnicodeString)"FAIL: Expected 1,50 DM");
679 delete currencyFmt;
680 s.truncate(0);
374ca955
A
681 len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
682 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
b75a7d8f
A
683 currencyFmt->format(1.50, s);
684 logln((UnicodeString)"Un pauvre en France a....." + s);
685 if (!(s=="1,50 F"))
686 errln((UnicodeString)"FAIL: Expected 1,50 F");
687 delete currencyFmt;
688 if (U_FAILURE(status))
689 errln((UnicodeString)"FAIL: Status " + (int32_t)status);
374ca955
A
690
691 for(int i=0; i < (int)(sizeof(testCases)/sizeof(testCases[i])); i++){
692 status = U_ZERO_ERROR;
693 const char *localeID = testCases[i][0];
694 UnicodeString expected(testCases[i][1]);
695 expected = expected.unescape();
696 s.truncate(0);
697 char loc[256]={0};
698 uloc_canonicalize(localeID, loc, 256, &status);
699 currencyFmt = NumberFormat::createCurrencyInstance(Locale(loc), status);
700 if(U_FAILURE(status)){
701 errln("Could not create currency formatter for locale %s",localeID);
702 continue;
703 }
704 currencyFmt->format(1150.50, s);
705 if(s!=expected){
706 errln(UnicodeString("FAIL: Expected: ")+expected
707 + UnicodeString(" Got: ") + s
708 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
709 }
710 if (U_FAILURE(status)){
711 errln((UnicodeString)"FAIL: Status " + (int32_t)status);
712 }
713 delete currencyFmt;
714 }
b75a7d8f
A
715}
716
717// -------------------------------------
718
719/**
720 * Test the Currency object handling, new as of ICU 2.2.
721 */
722void NumberFormatTest::TestCurrencyObject() {
723 UErrorCode ec = U_ZERO_ERROR;
724 NumberFormat* fmt =
725 NumberFormat::createCurrencyInstance(Locale::getUS(), ec);
726
727 if (U_FAILURE(ec)) {
728 errln("FAIL: getCurrencyInstance(US)");
729 delete fmt;
730 return;
731 }
732
733 Locale null("", "", "");
734
735 expectCurrency(*fmt, null, 1234.56, "$1,234.56");
736
737 expectCurrency(*fmt, Locale::getFrance(),
738 1234.56, CharsToUnicodeString("\\u20AC1,234.56")); // Euro
739
740 expectCurrency(*fmt, Locale::getJapan(),
741 1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
742
743 expectCurrency(*fmt, Locale("fr", "CH", ""),
744 1234.56, "SwF1,234.55"); // 0.05 rounding
745
746 expectCurrency(*fmt, Locale::getUS(),
747 1234.56, "$1,234.56");
748
749 delete fmt;
750 fmt = NumberFormat::createCurrencyInstance(Locale::getFrance(), ec);
751
752 if (U_FAILURE(ec)) {
753 errln("FAIL: getCurrencyInstance(FRANCE)");
754 delete fmt;
755 return;
756 }
757
758 expectCurrency(*fmt, null, 1234.56, CharsToUnicodeString("1 234,56 \\u20AC"));
759
760 expectCurrency(*fmt, Locale::getJapan(),
761 1234.56, CharsToUnicodeString("1 235 \\u00A5")); // Yen
762
763 expectCurrency(*fmt, Locale("fr", "CH", ""),
764 1234.56, "1 234,55 sFr."); // 0.05 rounding
765
766 expectCurrency(*fmt, Locale::getUS(),
767 1234.56, "1 234,56 $");
768
769 expectCurrency(*fmt, Locale::getFrance(),
770 1234.56, CharsToUnicodeString("1 234,56 \\u20AC")); // Euro
771
772 delete fmt;
773}
774
775// -------------------------------------
776
777/**
778 * Do rudimentary testing of parsing.
779 */
780void
781NumberFormatTest::TestParse(void)
782{
783 UErrorCode status = U_ZERO_ERROR;
784 UnicodeString arg("0");
785 DecimalFormat* format = new DecimalFormat("00", status);
786 //try {
787 Formattable n; format->parse(arg, n, status);
788 logln((UnicodeString)"parse(" + arg + ") = " + n.getLong());
789 if (n.getType() != Formattable::kLong ||
790 n.getLong() != 0) errln((UnicodeString)"FAIL: Expected 0");
791 delete format;
792 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status);
793 //}
794 //catch(Exception e) {
795 // errln((UnicodeString)"Exception caught: " + e);
796 //}
797}
798
799// -------------------------------------
800
801/**
802 * Test proper rounding by the format method.
803 */
804void
805NumberFormatTest::TestRounding487(void)
806{
807 UErrorCode status = U_ZERO_ERROR;
808 NumberFormat *nf = NumberFormat::createInstance(status);
73c04bcf
A
809 if (U_FAILURE(status)) {
810 dataerrln("Error calling NumberFormat::createInstance()");
811 return;
812 }
813
b75a7d8f
A
814 roundingTest(*nf, 0.00159999, 4, "0.0016");
815 roundingTest(*nf, 0.00995, 4, "0.01");
816
817 roundingTest(*nf, 12.3995, 3, "12.4");
818
819 roundingTest(*nf, 12.4999, 0, "12");
820 roundingTest(*nf, - 19.5, 0, "-20");
821 delete nf;
822 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: Status " + (int32_t)status);
823}
824
825/**
826 * Test the functioning of the secondary grouping value.
827 */
828void NumberFormatTest::TestSecondaryGrouping(void) {
829 UErrorCode status = U_ZERO_ERROR;
830 DecimalFormatSymbols US(Locale::getUS(), status);
831 CHECK(status, "DecimalFormatSymbols ct");
832
833 DecimalFormat f("#,##,###", US, status);
834 CHECK(status, "DecimalFormat ct");
835
836 expect2(f, (int32_t)123456789L, "12,34,56,789");
837 expectPat(f, "#,##,###");
838 f.applyPattern("#,###", status);
839 CHECK(status, "applyPattern");
840
841 f.setSecondaryGroupingSize(4);
842 expect2(f, (int32_t)123456789L, "12,3456,789");
843 expectPat(f, "#,####,###");
844 NumberFormat *g = NumberFormat::createInstance(Locale("hi", "IN"), status);
845 CHECK(status, "createInstance(hi_IN)");
846
847 UnicodeString out;
848 int32_t l = (int32_t)1876543210L;
849 g->format(l, out);
850 delete g;
851 // expect "1,87,65,43,210", but with Hindi digits
852 // 01234567890123
853 UBool ok = TRUE;
854 if (out.length() != 14) {
855 ok = FALSE;
856 } else {
857 for (int32_t i=0; i<out.length(); ++i) {
858 UBool expectGroup = FALSE;
859 switch (i) {
860 case 1:
861 case 4:
862 case 7:
863 case 10:
864 expectGroup = TRUE;
865 break;
866 }
867 // Later -- fix this to get the actual grouping
868 // character from the resource bundle.
869 UBool isGroup = (out.charAt(i) == 0x002C);
870 if (isGroup != expectGroup) {
871 ok = FALSE;
872 break;
873 }
874 }
875 }
876 if (!ok) {
877 errln((UnicodeString)"FAIL Expected " + l +
878 " x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got \"" +
879 escape(out) + "\"");
880 } else {
881 logln((UnicodeString)"Ok " + l +
882 " x hi_IN -> \"" +
883 escape(out) + "\"");
884 }
885}
886
887void NumberFormatTest::TestWhiteSpaceParsing(void) {
888 UErrorCode ec = U_ZERO_ERROR;
889 DecimalFormatSymbols US(Locale::getUS(), ec);
890 DecimalFormat fmt("a b#0c ", US, ec);
891 if (U_FAILURE(ec)) {
892 errln("FAIL: Constructor");
893 return;
894 }
895 int32_t n = 1234;
896 expect(fmt, "a b1234c ", n);
897 expect(fmt, "a b1234c ", n);
898}
899
900/**
901 * Test currencies whose display name is a ChoiceFormat.
902 */
903void NumberFormatTest::TestComplexCurrency() {
904 UErrorCode ec = U_ZERO_ERROR;
905 Locale loc("en", "IN", "");
906 NumberFormat* fmt = NumberFormat::createCurrencyInstance(loc, ec);
907 if (U_SUCCESS(ec)) {
908 expect2(*fmt, 1.0, "Re. 1.00");
909 // Use .00392625 because that's 2^-8. Any value less than 0.005 is fine.
910 expect(*fmt, 1.00390625, "Re. 1.00"); // tricky
911 expect2(*fmt, 12345678.0, "Rs. 1,23,45,678.00");
912 expect2(*fmt, 0.5, "Rs. 0.50");
913 expect2(*fmt, -1.0, "-Re. 1.00");
914 expect2(*fmt, -10.0, "-Rs. 10.00");
915 } else {
916 errln("FAIL: getCurrencyInstance(en_IN)");
917 }
918 delete fmt;
919}
920
921// -------------------------------------
922
923void
924NumberFormatTest::roundingTest(NumberFormat& nf, double x, int32_t maxFractionDigits, const char* expected)
925{
926 nf.setMaximumFractionDigits(maxFractionDigits);
927 UnicodeString out; nf.format(x, out);
928 logln((UnicodeString)"" + x + " formats with " + maxFractionDigits + " fractional digits to " + out);
929 if (!(out==expected)) errln((UnicodeString)"FAIL: Expected " + expected);
930}
931
932/**
933 * Upgrade to alphaWorks
934 */
935void NumberFormatTest::TestExponent(void) {
936 UErrorCode status = U_ZERO_ERROR;
937 DecimalFormatSymbols US(Locale::getUS(), status);
938 CHECK(status, "DecimalFormatSymbols constructor");
939 DecimalFormat fmt1(UnicodeString("0.###E0"), US, status);
940 CHECK(status, "DecimalFormat(0.###E0)");
941 DecimalFormat fmt2(UnicodeString("0.###E+0"), US, status);
942 CHECK(status, "DecimalFormat(0.###E+0)");
943 int32_t n = 1234;
944 expect2(fmt1, n, "1.234E3");
945 expect2(fmt2, n, "1.234E+3");
946 expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"
947}
948
949/**
950 * Upgrade to alphaWorks
951 */
952void NumberFormatTest::TestScientific(void) {
953 UErrorCode status = U_ZERO_ERROR;
954 DecimalFormatSymbols US(Locale::getUS(), status);
955 CHECK(status, "DecimalFormatSymbols constructor");
956
957 // Test pattern round-trip
958 const char* PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000",
959 "0.###E0;[0.###E0]" };
960 int32_t PAT_length = (int32_t)(sizeof(PAT) / sizeof(PAT[0]));
961 int32_t DIGITS[] = {
962 // min int, max int, min frac, max frac
963 0, 1, 0, 0, // "#E0"
964 1, 1, 0, 4, // "0.####E0"
965 2, 2, 3, 3, // "00.000E00"
966 1, 3, 0, 4, // "##0.####E000"
967 1, 1, 0, 3, // "0.###E0;[0.###E0]"
968 };
969 for (int32_t i=0; i<PAT_length; ++i) {
970 UnicodeString pat(PAT[i]);
971 DecimalFormat df(pat, US, status);
972 CHECK(status, "DecimalFormat constructor");
973 UnicodeString pat2;
974 df.toPattern(pat2);
975 if (pat == pat2) {
976 logln(UnicodeString("Ok Pattern rt \"") +
977 pat + "\" -> \"" +
978 pat2 + "\"");
979 } else {
980 errln(UnicodeString("FAIL Pattern rt \"") +
981 pat + "\" -> \"" +
982 pat2 + "\"");
983 }
984 // Make sure digit counts match what we expect
985 if (df.getMinimumIntegerDigits() != DIGITS[4*i] ||
986 df.getMaximumIntegerDigits() != DIGITS[4*i+1] ||
987 df.getMinimumFractionDigits() != DIGITS[4*i+2] ||
988 df.getMaximumFractionDigits() != DIGITS[4*i+3]) {
989 errln(UnicodeString("FAIL \"" + pat +
990 "\" min/max int; min/max frac = ") +
991 df.getMinimumIntegerDigits() + "/" +
992 df.getMaximumIntegerDigits() + ";" +
993 df.getMinimumFractionDigits() + "/" +
994 df.getMaximumFractionDigits() + ", expect " +
995 DIGITS[4*i] + "/" +
996 DIGITS[4*i+1] + ";" +
997 DIGITS[4*i+2] + "/" +
998 DIGITS[4*i+3]);
999 }
1000 }
1001
1002
1003 // Test the constructor for default locale. We have to
1004 // manually set the default locale, as there is no
1005 // guarantee that the default locale has the same
1006 // scientific format.
1007 Locale def = Locale::getDefault();
1008 Locale::setDefault(Locale::getUS(), status);
1009 expect2(NumberFormat::createScientificInstance(status),
1010 12345.678901,
1011 "1.2345678901E4", status);
1012 Locale::setDefault(def, status);
1013
1014 expect2(new DecimalFormat("#E0", US, status),
1015 12345.0,
1016 "1.2345E4", status);
1017 expect(new DecimalFormat("0E0", US, status),
1018 12345.0,
1019 "1E4", status);
1020 expect2(NumberFormat::createScientificInstance(Locale::getUS(), status),
1021 12345.678901,
1022 "1.2345678901E4", status);
1023 expect(new DecimalFormat("##0.###E0", US, status),
1024 12345.0,
1025 "12.34E3", status);
1026 expect(new DecimalFormat("##0.###E0", US, status),
1027 12345.00001,
1028 "12.35E3", status);
1029 expect2(new DecimalFormat("##0.####E0", US, status),
1030 (int32_t) 12345,
1031 "12.345E3", status);
1032 expect2(NumberFormat::createScientificInstance(Locale::getFrance(), status),
1033 12345.678901,
1034 "1,2345678901E4", status);
1035 expect(new DecimalFormat("##0.####E0", US, status),
1036 789.12345e-9,
1037 "789.12E-9", status);
1038 expect2(new DecimalFormat("##0.####E0", US, status),
1039 780.e-9,
1040 "780E-9", status);
1041 expect(new DecimalFormat(".###E0", US, status),
1042 45678.0,
1043 ".457E5", status);
1044 expect2(new DecimalFormat(".###E0", US, status),
1045 (int32_t) 0,
1046 ".0E0", status);
1047 /*
1048 expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
1049 new DecimalFormat("##E0", US),
1050 new DecimalFormat("####E0", US),
1051 new DecimalFormat("0E0", US),
1052 new DecimalFormat("00E0", US),
1053 new DecimalFormat("000E0", US),
1054 },
1055 new Long(45678000),
1056 new String[] { "4.5678E7",
1057 "45.678E6",
1058 "4567.8E4",
1059 "5E7",
1060 "46E6",
1061 "457E5",
1062 }
1063 );
1064 !
1065 ! Unroll this test into individual tests below...
1066 !
1067 */
1068 expect2(new DecimalFormat("#E0", US, status),
1069 (int32_t) 45678000, "4.5678E7", status);
1070 expect2(new DecimalFormat("##E0", US, status),
1071 (int32_t) 45678000, "45.678E6", status);
1072 expect2(new DecimalFormat("####E0", US, status),
1073 (int32_t) 45678000, "4567.8E4", status);
1074 expect(new DecimalFormat("0E0", US, status),
1075 (int32_t) 45678000, "5E7", status);
1076 expect(new DecimalFormat("00E0", US, status),
1077 (int32_t) 45678000, "46E6", status);
1078 expect(new DecimalFormat("000E0", US, status),
1079 (int32_t) 45678000, "457E5", status);
1080 /*
1081 expect(new DecimalFormat("###E0", US, status),
1082 new Object[] { new Double(0.0000123), "12.3E-6",
1083 new Double(0.000123), "123E-6",
1084 new Double(0.00123), "1.23E-3",
1085 new Double(0.0123), "12.3E-3",
1086 new Double(0.123), "123E-3",
1087 new Double(1.23), "1.23E0",
1088 new Double(12.3), "12.3E0",
1089 new Double(123), "123E0",
1090 new Double(1230), "1.23E3",
1091 });
1092 !
1093 ! Unroll this test into individual tests below...
1094 !
1095 */
1096 expect2(new DecimalFormat("###E0", US, status),
1097 0.0000123, "12.3E-6", status);
1098 expect2(new DecimalFormat("###E0", US, status),
1099 0.000123, "123E-6", status);
1100 expect2(new DecimalFormat("###E0", US, status),
1101 0.00123, "1.23E-3", status);
1102 expect2(new DecimalFormat("###E0", US, status),
1103 0.0123, "12.3E-3", status);
1104 expect2(new DecimalFormat("###E0", US, status),
1105 0.123, "123E-3", status);
1106 expect2(new DecimalFormat("###E0", US, status),
1107 1.23, "1.23E0", status);
1108 expect2(new DecimalFormat("###E0", US, status),
1109 12.3, "12.3E0", status);
1110 expect2(new DecimalFormat("###E0", US, status),
1111 123.0, "123E0", status);
1112 expect2(new DecimalFormat("###E0", US, status),
1113 1230.0, "1.23E3", status);
1114 /*
1115 expect(new DecimalFormat("0.#E+00", US, status),
1116 new Object[] { new Double(0.00012), "1.2E-04",
1117 new Long(12000), "1.2E+04",
1118 });
1119 !
1120 ! Unroll this test into individual tests below...
1121 !
1122 */
1123 expect2(new DecimalFormat("0.#E+00", US, status),
1124 0.00012, "1.2E-04", status);
1125 expect2(new DecimalFormat("0.#E+00", US, status),
1126 (int32_t) 12000, "1.2E+04", status);
1127}
1128
1129/**
1130 * Upgrade to alphaWorks
1131 */
1132void NumberFormatTest::TestPad(void) {
1133 UErrorCode status = U_ZERO_ERROR;
1134 DecimalFormatSymbols US(Locale::getUS(), status);
1135 CHECK(status, "DecimalFormatSymbols constructor");
1136
1137 expect2(new DecimalFormat("*^##.##", US, status),
1138 int32_t(0), "^^^^0", status);
1139 expect2(new DecimalFormat("*^##.##", US, status),
1140 -1.3, "^-1.3", status);
374ca955 1141 expect2(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
b75a7d8f 1142 int32_t(0), "0.0E0______ g-m/s^2", status);
374ca955 1143 expect(new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US, status),
b75a7d8f 1144 1.0/3, "333.333E-3_ g-m/s^2", status);
374ca955 1145 expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
b75a7d8f 1146 int32_t(0), "0.0______ g-m/s^2", status);
374ca955 1147 expect(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US, status),
b75a7d8f
A
1148 1.0/3, "0.33333__ g-m/s^2", status);
1149
1150 // Test padding before a sign
1151 const char *formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
1152 expect2(new DecimalFormat(formatStr, US, status),
1153 int32_t(-10), "xxxxxxxxxx(10.0)", status);
1154 expect2(new DecimalFormat(formatStr, US, status),
1155 int32_t(-1000),"xxxxxxx(1,000.0)", status);
1156 expect2(new DecimalFormat(formatStr, US, status),
1157 int32_t(-1000000),"xxx(1,000,000.0)", status);
1158 expect2(new DecimalFormat(formatStr, US, status),
1159 -100.37, "xxxxxxxx(100.37)", status);
1160 expect2(new DecimalFormat(formatStr, US, status),
1161 -10456.37, "xxxxx(10,456.37)", status);
1162 expect2(new DecimalFormat(formatStr, US, status),
1163 -1120456.37, "xx(1,120,456.37)", status);
1164 expect2(new DecimalFormat(formatStr, US, status),
1165 -112045600.37, "(112,045,600.37)", status);
1166 expect2(new DecimalFormat(formatStr, US, status),
1167 -1252045600.37,"(1,252,045,600.37)", status);
1168
1169 expect2(new DecimalFormat(formatStr, US, status),
1170 int32_t(10), "xxxxxxxxxxxx10.0", status);
1171 expect2(new DecimalFormat(formatStr, US, status),
1172 int32_t(1000),"xxxxxxxxx1,000.0", status);
1173 expect2(new DecimalFormat(formatStr, US, status),
1174 int32_t(1000000),"xxxxx1,000,000.0", status);
1175 expect2(new DecimalFormat(formatStr, US, status),
1176 100.37, "xxxxxxxxxx100.37", status);
1177 expect2(new DecimalFormat(formatStr, US, status),
1178 10456.37, "xxxxxxx10,456.37", status);
1179 expect2(new DecimalFormat(formatStr, US, status),
1180 1120456.37, "xxxx1,120,456.37", status);
1181 expect2(new DecimalFormat(formatStr, US, status),
1182 112045600.37, "xx112,045,600.37", status);
1183 expect2(new DecimalFormat(formatStr, US, status),
1184 10252045600.37,"10,252,045,600.37", status);
1185
1186
1187 // Test padding between a sign and a number
1188 const char *formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
1189 expect2(new DecimalFormat(formatStr2, US, status),
1190 int32_t(-10), "(10.0xxxxxxxxxx)", status);
1191 expect2(new DecimalFormat(formatStr2, US, status),
1192 int32_t(-1000),"(1,000.0xxxxxxx)", status);
1193 expect2(new DecimalFormat(formatStr2, US, status),
1194 int32_t(-1000000),"(1,000,000.0xxx)", status);
1195 expect2(new DecimalFormat(formatStr2, US, status),
1196 -100.37, "(100.37xxxxxxxx)", status);
1197 expect2(new DecimalFormat(formatStr2, US, status),
1198 -10456.37, "(10,456.37xxxxx)", status);
1199 expect2(new DecimalFormat(formatStr2, US, status),
1200 -1120456.37, "(1,120,456.37xx)", status);
1201 expect2(new DecimalFormat(formatStr2, US, status),
1202 -112045600.37, "(112,045,600.37)", status);
1203 expect2(new DecimalFormat(formatStr2, US, status),
1204 -1252045600.37,"(1,252,045,600.37)", status);
1205
1206 expect2(new DecimalFormat(formatStr2, US, status),
1207 int32_t(10), "10.0xxxxxxxxxxxx", status);
1208 expect2(new DecimalFormat(formatStr2, US, status),
1209 int32_t(1000),"1,000.0xxxxxxxxx", status);
1210 expect2(new DecimalFormat(formatStr2, US, status),
1211 int32_t(1000000),"1,000,000.0xxxxx", status);
1212 expect2(new DecimalFormat(formatStr2, US, status),
1213 100.37, "100.37xxxxxxxxxx", status);
1214 expect2(new DecimalFormat(formatStr2, US, status),
1215 10456.37, "10,456.37xxxxxxx", status);
1216 expect2(new DecimalFormat(formatStr2, US, status),
1217 1120456.37, "1,120,456.37xxxx", status);
1218 expect2(new DecimalFormat(formatStr2, US, status),
1219 112045600.37, "112,045,600.37xx", status);
1220 expect2(new DecimalFormat(formatStr2, US, status),
1221 10252045600.37,"10,252,045,600.37", status);
1222
1223 //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
1224 DecimalFormat fmt("#", US, status);
1225 CHECK(status, "DecimalFormat constructor");
1226 UnicodeString padString("P");
1227 fmt.setPadCharacter(padString);
1228 expectPad(fmt, "*P##.##", DecimalFormat::kPadBeforePrefix, 5, padString);
1229 fmt.setPadCharacter((UnicodeString)"^");
1230 expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, (UnicodeString)"^");
1231 //commented untill implementation is complete
1232 /* fmt.setPadCharacter((UnicodeString)"^^^");
1233 expectPad(fmt, "*^^^#", DecimalFormat::kPadBeforePrefix, 3, (UnicodeString)"^^^");
1234 padString.remove();
1235 padString.append((UChar)0x0061);
1236 padString.append((UChar)0x0302);
1237 fmt.setPadCharacter(padString);
1238 UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
1239 UnicodeString pattern(patternChars);
1240 expectPad(fmt, pattern , DecimalFormat::kPadBeforePrefix, 4, padString);
1241 */
1242
1243}
1244
1245/**
1246 * Upgrade to alphaWorks
1247 */
1248void NumberFormatTest::TestPatterns2(void) {
1249 UErrorCode status = U_ZERO_ERROR;
1250 DecimalFormatSymbols US(Locale::getUS(), status);
1251 CHECK(status, "DecimalFormatSymbols constructor");
1252
1253 DecimalFormat fmt("#", US, status);
1254 CHECK(status, "DecimalFormat constructor");
1255
1256 UChar hat = 0x005E; /*^*/
1257
1258 expectPad(fmt, "*^#", DecimalFormat::kPadBeforePrefix, 1, hat);
1259 expectPad(fmt, "$*^#", DecimalFormat::kPadAfterPrefix, 2, hat);
1260 expectPad(fmt, "#*^", DecimalFormat::kPadBeforeSuffix, 1, hat);
1261 expectPad(fmt, "#$*^", DecimalFormat::kPadAfterSuffix, 2, hat);
1262 expectPad(fmt, "$*^$#", ILLEGAL);
1263 expectPad(fmt, "#$*^$", ILLEGAL);
1264 expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat::kPadBeforeSuffix,
1265 12, (UChar)0x0078 /*x*/);
1266 expectPad(fmt, "''#0*x", DecimalFormat::kPadBeforeSuffix,
1267 3, (UChar)0x0078 /*x*/);
1268 expectPad(fmt, "'I''ll'*a###.##", DecimalFormat::kPadAfterPrefix,
1269 10, (UChar)0x0061 /*a*/);
1270
1271 fmt.applyPattern("AA#,##0.00ZZ", status);
1272 CHECK(status, "applyPattern");
1273 fmt.setPadCharacter(hat);
1274
1275 fmt.setFormatWidth(10);
1276
1277 fmt.setPadPosition(DecimalFormat::kPadBeforePrefix);
1278 expectPat(fmt, "*^AA#,##0.00ZZ");
1279
1280 fmt.setPadPosition(DecimalFormat::kPadBeforeSuffix);
1281 expectPat(fmt, "AA#,##0.00*^ZZ");
1282
1283 fmt.setPadPosition(DecimalFormat::kPadAfterSuffix);
1284 expectPat(fmt, "AA#,##0.00ZZ*^");
1285
1286 // 12 3456789012
1287 UnicodeString exp("AA*^#,##0.00ZZ", "");
1288 fmt.setFormatWidth(12);
1289 fmt.setPadPosition(DecimalFormat::kPadAfterPrefix);
1290 expectPat(fmt, exp);
1291
1292 fmt.setFormatWidth(13);
1293 // 12 34567890123
1294 expectPat(fmt, "AA*^##,##0.00ZZ");
1295
1296 fmt.setFormatWidth(14);
1297 // 12 345678901234
1298 expectPat(fmt, "AA*^###,##0.00ZZ");
1299
1300 fmt.setFormatWidth(15);
1301 // 12 3456789012345
1302 expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case
1303
1304 fmt.setFormatWidth(16);
1305 // 12 34567890123456
1306 expectPat(fmt, "AA*^#,###,##0.00ZZ");
1307}
1308
1309void NumberFormatTest::TestSurrogateSupport(void) {
1310 UErrorCode status = U_ZERO_ERROR;
1311 DecimalFormatSymbols custom(Locale::getUS(), status);
1312 CHECK(status, "DecimalFormatSymbols constructor");
1313
1314 custom.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, "decimal");
1315 custom.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, "plus");
1316 custom.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, " minus ");
1317 custom.setSymbol(DecimalFormatSymbols::kExponentialSymbol, "exponent");
1318
1319 UnicodeString patternStr("*\\U00010000##.##", "");
1320 patternStr = patternStr.unescape();
1321 UnicodeString expStr("\\U00010000\\U00010000\\U00010000\\U000100000", "");
1322 expStr = expStr.unescape();
1323 expect2(new DecimalFormat(patternStr, custom, status),
1324 int32_t(0), expStr, status);
1325
1326 status = U_ZERO_ERROR;
1327 expect2(new DecimalFormat("*^##.##", custom, status),
1328 int32_t(0), "^^^^0", status);
1329 status = U_ZERO_ERROR;
1330 expect2(new DecimalFormat("##.##", custom, status),
1331 -1.3, " minus 1decimal3", status);
1332 status = U_ZERO_ERROR;
374ca955 1333 expect2(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
b75a7d8f
A
1334 int32_t(0), "0decimal0exponent0 g-m/s^2", status);
1335 status = U_ZERO_ERROR;
374ca955 1336 expect(new DecimalFormat("##0.0####E0 'g-m/s^2'", custom, status),
b75a7d8f
A
1337 1.0/3, "333decimal333exponent minus 3 g-m/s^2", status);
1338 status = U_ZERO_ERROR;
374ca955 1339 expect2(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
b75a7d8f
A
1340 int32_t(0), "0decimal0 g-m/s^2", status);
1341 status = U_ZERO_ERROR;
374ca955 1342 expect(new DecimalFormat("##0.0#### 'g-m/s^2'", custom, status),
b75a7d8f
A
1343 1.0/3, "0decimal33333 g-m/s^2", status);
1344
1345 UnicodeString zero((UChar32)0x10000);
1346 custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, zero);
1347 expStr = UnicodeString("\\U00010001decimal\\U00010002\\U00010005\\U00010000", "");
1348 expStr = expStr.unescape();
1349 status = U_ZERO_ERROR;
1350 expect2(new DecimalFormat("##0.000", custom, status),
1351 1.25, expStr, status);
1352
1353 custom.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, (UChar)0x30);
1354 custom.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "units of money");
1355 custom.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, "money separator");
1356 patternStr = "0.00 \\u00A4' in your bank account'";
1357 patternStr = patternStr.unescape();
1358 expStr = UnicodeString(" minus 20money separator00 units of money in your bank account", "");
1359 status = U_ZERO_ERROR;
1360 expect2(new DecimalFormat(patternStr, custom, status),
1361 int32_t(-20), expStr, status);
1362
1363 custom.setSymbol(DecimalFormatSymbols::kPercentSymbol, "percent");
1364 patternStr = "'You''ve lost ' -0.00 %' of your money today'";
1365 patternStr = patternStr.unescape();
1366 expStr = UnicodeString(" minus You've lost minus 2000decimal00 percent of your money today", "");
1367 status = U_ZERO_ERROR;
1368 expect2(new DecimalFormat(patternStr, custom, status),
1369 int32_t(-20), expStr, status);
1370}
1371
1372void NumberFormatTest::TestCurrencyPatterns(void) {
1373 int32_t i, locCount;
1374 const Locale* locs = NumberFormat::getAvailableLocales(locCount);
1375 for (i=0; i<locCount; ++i) {
1376 UErrorCode ec = U_ZERO_ERROR;
1377 NumberFormat* nf = NumberFormat::createCurrencyInstance(locs[i], ec);
1378 if (U_FAILURE(ec)) {
374ca955 1379 errln("FAIL: Can't create NumberFormat(%s) - %s", locs[i].getName(), u_errorName(ec));
b75a7d8f
A
1380 } else {
1381 // Make sure currency formats do not have a variable number
1382 // of fraction digits
1383 int32_t min = nf->getMinimumFractionDigits();
1384 int32_t max = nf->getMaximumFractionDigits();
1385 if (min != max) {
1386 UnicodeString a, b;
1387 nf->format(1.0, a);
1388 nf->format(1.125, b);
1389 errln((UnicodeString)"FAIL: " + locs[i].getName() +
1390 " min fraction digits != max fraction digits; "
1391 "x 1.0 => " + escape(a) +
1392 "; x 1.125 => " + escape(b));
1393 }
1394
1395 // Make sure EURO currency formats have exactly 2 fraction digits
1396 if (nf->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
1397 DecimalFormat* df = (DecimalFormat*) nf;
1398 if (u_strcmp(EUR, df->getCurrency()) == 0) {
1399 if (min != 2 || max != 2) {
1400 UnicodeString a;
1401 nf->format(1.0, a);
1402 errln((UnicodeString)"FAIL: " + locs[i].getName() +
1403 " is a EURO format but it does not have 2 fraction digits; "
1404 "x 1.0 => " +
1405 escape(a));
1406 }
1407 }
1408 }
1409 }
1410 delete nf;
1411 }
1412}
1413
1414void NumberFormatTest::TestRegCurrency(void) {
374ca955
A
1415#if !UCONFIG_NO_SERVICE
1416 UErrorCode status = U_ZERO_ERROR;
1417 UChar USD[4];
1418 ucurr_forLocale("en_US", USD, 4, &status);
1419 UChar YEN[4];
1420 ucurr_forLocale("ja_JP", YEN, 4, &status);
1421 UChar TMP[4];
1422 static const UChar QQQ[] = {0x51, 0x51, 0x51, 0};
1423 if(U_FAILURE(status)) {
1424 errln("Unable to get currency for locale, error %s", u_errorName(status));
1425 return;
1426 }
1427
1428 UCurrRegistryKey enkey = ucurr_register(YEN, "en_US", &status);
1429 UCurrRegistryKey enUSEUROkey = ucurr_register(QQQ, "en_US_EURO", &status);
1430
1431 ucurr_forLocale("en_US", TMP, 4, &status);
1432 if (u_strcmp(YEN, TMP) != 0) {
1433 errln("FAIL: didn't return YEN registered for en_US");
1434 }
b75a7d8f 1435
374ca955
A
1436 ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1437 if (u_strcmp(QQQ, TMP) != 0) {
1438 errln("FAIL: didn't return QQQ for en_US_EURO");
1439 }
1440
1441 int32_t fallbackLen = ucurr_forLocale("en_XX_BAR", TMP, 4, &status);
1442 if (fallbackLen) {
1443 errln("FAIL: tried to fallback en_XX_BAR");
1444 }
1445 status = U_ZERO_ERROR; // reset
1446
1447 if (!ucurr_unregister(enkey, &status)) {
1448 errln("FAIL: couldn't unregister enkey");
1449 }
b75a7d8f 1450
374ca955
A
1451 ucurr_forLocale("en_US", TMP, 4, &status);
1452 if (u_strcmp(USD, TMP) != 0) {
1453 errln("FAIL: didn't return USD for en_US after unregister of en_US");
1454 }
1455 status = U_ZERO_ERROR; // reset
1456
1457 ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1458 if (u_strcmp(QQQ, TMP) != 0) {
1459 errln("FAIL: didn't return QQQ for en_US_EURO after unregister of en_US");
1460 }
1461
1462 ucurr_forLocale("en_US_BLAH", TMP, 4, &status);
1463 if (u_strcmp(USD, TMP) != 0) {
1464 errln("FAIL: could not find USD for en_US_BLAH after unregister of en");
1465 }
1466 status = U_ZERO_ERROR; // reset
1467
1468 if (!ucurr_unregister(enUSEUROkey, &status)) {
1469 errln("FAIL: couldn't unregister enUSEUROkey");
1470 }
1471
1472 ucurr_forLocale("en_US_EURO", TMP, 4, &status);
1473 if (u_strcmp(EUR, TMP) != 0) {
1474 errln("FAIL: didn't return EUR for en_US_EURO after unregister of en_US_EURO");
1475 }
1476 status = U_ZERO_ERROR; // reset
1477#endif
1478}
b75a7d8f 1479
374ca955
A
1480void NumberFormatTest::TestCurrencyNames(void) {
1481 // Do a basic check of getName()
1482 // USD { "US$", "US Dollar" } // 04/04/1792-
1483 UErrorCode ec = U_ZERO_ERROR;
1484 static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
73c04bcf
A
1485 static const UChar CAD[] = {0x43, 0x41, 0x44, 0}; /*CAD*/
1486 static const UChar ITL[] = {0x49, 0x54, 0x4C, 0}; /*ITL*/
374ca955
A
1487 UBool isChoiceFormat;
1488 int32_t len;
1489 // Warning: HARD-CODED LOCALE DATA in this test. If it fails, CHECK
1490 // THE LOCALE DATA before diving into the code.
1491 assertEquals("USD.getName(SYMBOL_NAME)",
1492 UnicodeString("US$"),
1493 UnicodeString(ucurr_getName(USD, "en",
1494 UCURR_SYMBOL_NAME,
1495 &isChoiceFormat, &len, &ec)));
1496 assertEquals("USD.getName(LONG_NAME)",
1497 UnicodeString("US Dollar"),
1498 UnicodeString(ucurr_getName(USD, "en",
1499 UCURR_LONG_NAME,
1500 &isChoiceFormat, &len, &ec)));
1501 assertSuccess("ucurr_getName", ec);
1502
73c04bcf
A
1503 // Test that a default or fallback warning is being returned. JB 4239.
1504 (void) ucurr_getName(CAD, "en_US", UCURR_LONG_NAME, &isChoiceFormat,
1505 &len, &ec);
1506 assertTrue("ucurr_getName (fallback)",
1507 U_USING_FALLBACK_WARNING == ec, TRUE);
1508 (void) ucurr_getName(CAD, "vi", UCURR_LONG_NAME, &isChoiceFormat,
1509 &len, &ec);
1510 assertTrue("ucurr_getName (default)",
1511 U_USING_DEFAULT_WARNING == ec, TRUE);
1512
1513 // Test that a default warning is being returned when falling back to root. JB 4536.
1514 (void) ucurr_getName(ITL, "cy", UCURR_LONG_NAME, &isChoiceFormat,
1515 &len, &ec);
1516 assertTrue("ucurr_getName (default to root)",
1517 U_USING_DEFAULT_WARNING == ec, TRUE);
1518
374ca955 1519 // TODO add more tests later
b75a7d8f
A
1520}
1521
73c04bcf
A
1522void NumberFormatTest::TestCurrencyUnit(void){
1523 UErrorCode ec = U_ZERO_ERROR;
1524 static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
1525 CurrencyUnit cu(USD, ec);
1526 assertSuccess("CurrencyUnit", ec);
1527
1528 const UChar * r = cu.getISOCurrency(); // who is the buffer owner ?
1529 assertEquals("getISOCurrency()", USD, r);
1530
1531 CurrencyUnit cu2(cu);
1532 if (!(cu2 == cu)){
1533 errln("CurrencyUnit copy constructed object should be same");
1534 }
1535
1536 CurrencyUnit * cu3 = (CurrencyUnit *)cu.clone();
1537 if (!(*cu3 == cu)){
1538 errln("CurrencyUnit cloned object should be same");
1539 }
1540 delete cu3;
1541}
1542
1543void NumberFormatTest::TestCurrencyAmount(void){
1544 UErrorCode ec = U_ZERO_ERROR;
1545 static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
1546 CurrencyAmount ca(9, USD, ec);
1547 assertSuccess("CurrencyAmount", ec);
1548
1549 CurrencyAmount ca2(ca);
1550 if (!(ca2 == ca)){
1551 errln("CurrencyAmount copy constructed object should be same");
1552 }
1553
1554 ca2=ca;
1555 if (!(ca2 == ca)){
1556 errln("CurrencyAmount assigned object should be same");
1557 }
1558
1559 CurrencyAmount *ca3 = (CurrencyAmount *)ca.clone();
1560 if (!(*ca3 == ca)){
1561 errln("CurrencyAmount cloned object should be same");
1562 }
1563 delete ca3;
1564}
1565
b75a7d8f
A
1566void NumberFormatTest::TestSymbolsWithBadLocale(void) {
1567 Locale locDefault;
1568 Locale locBad("x-crazy_ZZ_MY_SPECIAL_ADMINISTRATION_REGION_NEEDS_A_SPECIAL_VARIANT_WITH_A_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_REALLY_LONG_NAME");
1569 UErrorCode status = U_ZERO_ERROR;
1570 UnicodeString intlCurrencySymbol((UChar)0xa4);
1571
1572 intlCurrencySymbol.append((UChar)0xa4);
1573
1574 logln("Current locale is %s", Locale::getDefault().getName());
1575 Locale::setDefault(locBad, status);
1576 logln("Current locale is %s", Locale::getDefault().getName());
1577 DecimalFormatSymbols mySymbols(status);
1578 if (status != U_USING_FALLBACK_WARNING) {
1579 errln("DecimalFormatSymbols should returned U_USING_FALLBACK_WARNING.");
1580 }
1581 if (strcmp(mySymbols.getLocale().getName(), locBad.getName()) != 0) {
1582 errln("DecimalFormatSymbols does not have the right locale.");
1583 }
374ca955
A
1584 int symbolEnum = (int)DecimalFormatSymbols::kDecimalSeparatorSymbol;
1585 for (; symbolEnum < (int)DecimalFormatSymbols::kFormatSymbolCount; symbolEnum++) {
1586 logln(UnicodeString("DecimalFormatSymbols[") + symbolEnum + UnicodeString("] = ")
1587 + prettify(mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum)));
1588
1589 if (mySymbols.getSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbolEnum).length() == 0
73c04bcf
A
1590 && symbolEnum != (int)DecimalFormatSymbols::kGroupingSeparatorSymbol
1591 && symbolEnum != (int)DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol)
374ca955 1592 {
b75a7d8f
A
1593 errln("DecimalFormatSymbols has an empty string at index %d.", symbolEnum);
1594 }
1595 }
1596 status = U_ZERO_ERROR;
1597 Locale::setDefault(locDefault, status);
1598 logln("Current locale is %s", Locale::getDefault().getName());
1599}
1600
1601/**
1602 * Check that adoptDecimalFormatSymbols and setDecimalFormatSymbols
1603 * behave the same, except for memory ownership semantics. (No
1604 * version of this test on Java, since Java has only one method.)
1605 */
1606void NumberFormatTest::TestAdoptDecimalFormatSymbols(void) {
1607 UErrorCode ec = U_ZERO_ERROR;
1608 DecimalFormatSymbols *sym = new DecimalFormatSymbols(Locale::getUS(), ec);
1609 if (U_FAILURE(ec)) {
1610 errln("Fail: DecimalFormatSymbols constructor");
1611 delete sym;
1612 return;
1613 }
1614 UnicodeString pat(" #,##0.00");
1615 pat.insert(0, (UChar)0x00A4);
1616 DecimalFormat fmt(pat, sym, ec);
1617 if (U_FAILURE(ec)) {
1618 errln("Fail: DecimalFormat constructor");
1619 return;
1620 }
1621
1622 UnicodeString str;
1623 fmt.format(2350.75, str);
1624 if (str == "$ 2,350.75") {
1625 logln(str);
1626 } else {
1627 errln("Fail: " + str + ", expected $ 2,350.75");
1628 }
1629
1630 sym = new DecimalFormatSymbols(Locale::getUS(), ec);
1631 if (U_FAILURE(ec)) {
1632 errln("Fail: DecimalFormatSymbols constructor");
1633 delete sym;
1634 return;
1635 }
1636 sym->setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
1637 fmt.adoptDecimalFormatSymbols(sym);
1638
1639 str.truncate(0);
1640 fmt.format(2350.75, str);
1641 if (str == "Q 2,350.75") {
1642 logln(str);
1643 } else {
1644 errln("Fail: adoptDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
1645 }
1646
1647 sym = new DecimalFormatSymbols(Locale::getUS(), ec);
1648 if (U_FAILURE(ec)) {
1649 errln("Fail: DecimalFormatSymbols constructor");
1650 delete sym;
1651 return;
1652 }
1653 DecimalFormat fmt2(pat, sym, ec);
1654 if (U_FAILURE(ec)) {
1655 errln("Fail: DecimalFormat constructor");
1656 return;
1657 }
1658
1659 DecimalFormatSymbols sym2(Locale::getUS(), ec);
1660 if (U_FAILURE(ec)) {
1661 errln("Fail: DecimalFormatSymbols constructor");
1662 return;
1663 }
1664 sym2.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "Q");
1665 fmt2.setDecimalFormatSymbols(sym2);
1666
1667 str.truncate(0);
1668 fmt2.format(2350.75, str);
1669 if (str == "Q 2,350.75") {
1670 logln(str);
1671 } else {
1672 errln("Fail: setDecimalFormatSymbols -> " + str + ", expected Q 2,350.75");
1673 }
1674}
1675
374ca955
A
1676void NumberFormatTest::TestPerMill() {
1677 UErrorCode ec = U_ZERO_ERROR;
1678 UnicodeString str;
1679 DecimalFormat fmt(ctou("###.###\\u2030"), ec);
1680 if (!assertSuccess("DecimalFormat ct", ec)) return;
1681 assertEquals("0.4857 x ###.###\\u2030",
1682 ctou("485.7\\u2030"), fmt.format(0.4857, str));
1683
1684 DecimalFormatSymbols sym(Locale::getUS(), ec);
1685 sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, ctou("m"));
1686 DecimalFormat fmt2("", sym, ec);
1687 fmt2.applyLocalizedPattern("###.###m", ec);
1688 if (!assertSuccess("setup", ec)) return;
1689 str.truncate(0);
1690 assertEquals("0.4857 x ###.###m",
1691 "485.7m", fmt2.format(0.4857, str));
1692}
1693
1694/**
1695 * Generic test for patterns that should be legal/illegal.
1696 */
1697void NumberFormatTest::TestIllegalPatterns() {
1698 // Test cases:
1699 // Prefix with "-:" for illegal patterns
1700 // Prefix with "+:" for legal patterns
1701 const char* DATA[] = {
1702 // Unquoted special characters in the suffix are illegal
1703 "-:000.000|###",
1704 "+:000.000'|###'",
1705 0
1706 };
1707 for (int32_t i=0; DATA[i]; ++i) {
1708 const char* pat=DATA[i];
1709 UBool valid = (*pat) == '+';
1710 pat += 2;
1711 UErrorCode ec = U_ZERO_ERROR;
1712 DecimalFormat fmt(pat, ec); // locale doesn't matter here
1713 if (U_SUCCESS(ec) == valid) {
1714 logln("Ok: pattern \"%s\": %s",
1715 pat, u_errorName(ec));
1716 } else {
1717 errln("FAIL: pattern \"%s\" should have %s; got %s",
1718 pat, (valid?"succeeded":"failed"),
1719 u_errorName(ec));
1720 }
1721 }
1722}
1723
1724//----------------------------------------------------------------------
1725
1726static const char* KEYWORDS[] = {
1727 /*0*/ "ref=", // <reference pattern to parse numbers>
1728 /*1*/ "loc=", // <locale for formats>
1729 /*2*/ "f:", // <pattern or '-'> <number> <exp. string>
1730 /*3*/ "fp:", // <pattern or '-'> <number> <exp. string> <exp. number>
1731 /*4*/ "rt:", // <pattern or '-'> <(exp.) number> <(exp.) string>
1732 /*5*/ "p:", // <pattern or '-'> <string> <exp. number>
1733 /*6*/ "perr:", // <pattern or '-'> <invalid string>
1734 /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
1735 /*8*/ "fpc:", // <pattern or '-'> <curr.amt> <exp. string> <exp. curr.amt>
1736 0
1737};
1738
1739/**
1740 * Return an integer representing the next token from this
1741 * iterator. The integer will be an index into the given list, or
1742 * -1 if there are no more tokens, or -2 if the token is not on
1743 * the list.
1744 */
1745static int32_t keywordIndex(const UnicodeString& tok) {
1746 for (int32_t i=0; KEYWORDS[i]!=0; ++i) {
1747 if (tok==KEYWORDS[i]) {
1748 return i;
1749 }
1750 }
1751 return -1;
1752}
1753
1754/**
1755 * Parse a CurrencyAmount using the given NumberFormat, with
1756 * the 'delim' character separating the number and the currency.
1757 */
1758static void parseCurrencyAmount(const UnicodeString& str,
1759 const NumberFormat& fmt,
1760 UChar delim,
1761 Formattable& result,
1762 UErrorCode& ec) {
1763 UnicodeString num, cur;
1764 int32_t i = str.indexOf(delim);
1765 str.extractBetween(0, i, num);
1766 str.extractBetween(i+1, INT32_MAX, cur);
1767 Formattable n;
1768 fmt.parse(num, n, ec);
1769 result.adoptObject(new CurrencyAmount(n, cur.getTerminatedBuffer(), ec));
1770}
1771
1772void NumberFormatTest::TestCases() {
1773 UErrorCode ec = U_ZERO_ERROR;
1774 TextFile reader("NumberFormatTestCases.txt", "UTF8", ec);
1775 if (U_FAILURE(ec)) {
1776 errln("FAIL: Couldn't open NumberFormatTestCases.txt");
1777 return;
1778 }
1779 TokenIterator tokens(&reader);
1780
1781 Locale loc("en", "US", "");
1782 DecimalFormat *ref = 0, *fmt = 0;
1783 MeasureFormat *mfmt = 0;
1784 UnicodeString pat, tok, mloc, str, out, where, currAmt;
1785 Formattable n;
1786
1787 for (;;) {
1788 ec = U_ZERO_ERROR;
1789 if (!tokens.next(tok, ec)) {
1790 break;
1791 }
1792 where = UnicodeString("(") + tokens.getLineNumber() + ") ";
1793 int32_t cmd = keywordIndex(tok);
1794 switch (cmd) {
1795 case 0:
1796 // ref= <reference pattern>
1797 if (!tokens.next(tok, ec)) goto error;
1798 delete ref;
1799 ref = new DecimalFormat(tok,
1800 new DecimalFormatSymbols(Locale::getUS(), ec), ec);
73c04bcf
A
1801 if (U_FAILURE(ec)) {
1802 dataerrln("Error constructing DecimalFormat");
1803 goto error;
1804 }
374ca955
A
1805 break;
1806 case 1:
1807 // loc= <locale>
1808 if (!tokens.next(tok, ec)) goto error;
1809 loc = Locale::createFromName(CharString(tok));
1810 break;
1811 case 2: // f:
1812 case 3: // fp:
1813 case 4: // rt:
1814 case 5: // p:
1815 if (!tokens.next(tok, ec)) goto error;
1816 if (tok != "-") {
1817 pat = tok;
1818 delete fmt;
1819 fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc, ec), ec);
1820 if (U_FAILURE(ec)) {
1821 errln("FAIL: " + where + "Pattern \"" + pat + "\": " + u_errorName(ec));
1822 ec = U_ZERO_ERROR;
1823 if (!tokens.next(tok, ec)) goto error;
1824 if (!tokens.next(tok, ec)) goto error;
1825 if (cmd == 3) {
1826 if (!tokens.next(tok, ec)) goto error;
1827 }
1828 continue;
1829 }
1830 }
1831 if (cmd == 2 || cmd == 3 || cmd == 4) {
1832 // f: <pattern or '-'> <number> <exp. string>
1833 // fp: <pattern or '-'> <number> <exp. string> <exp. number>
1834 // rt: <pattern or '-'> <number> <string>
1835 UnicodeString num;
1836 if (!tokens.next(num, ec)) goto error;
1837 if (!tokens.next(str, ec)) goto error;
1838 ref->parse(num, n, ec);
1839 assertSuccess("parse", ec);
1840 assertEquals(where + "\"" + pat + "\".format(" + num + ")",
1841 str, fmt->format(n, out.remove(), ec));
1842 assertSuccess("format", ec);
1843 if (cmd == 3) { // fp:
1844 if (!tokens.next(num, ec)) goto error;
1845 ref->parse(num, n, ec);
1846 assertSuccess("parse", ec);
1847 }
1848 if (cmd != 2) { // != f:
1849 Formattable m;
1850 fmt->parse(str, m, ec);
1851 assertSuccess("parse", ec);
1852 assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
1853 n, m);
1854 }
1855 }
1856 // p: <pattern or '-'> <string to parse> <exp. number>
1857 else {
1858 UnicodeString expstr;
1859 if (!tokens.next(str, ec)) goto error;
1860 if (!tokens.next(expstr, ec)) goto error;
1861 Formattable exp, n;
1862 ref->parse(expstr, exp, ec);
1863 assertSuccess("parse", ec);
1864 fmt->parse(str, n, ec);
1865 assertSuccess("parse", ec);
1866 assertEquals(where + "\"" + pat + "\".parse(\"" + str + "\")",
1867 exp, n);
1868 }
1869 break;
1870 case 8: // fpc:
1871 if (!tokens.next(tok, ec)) goto error;
1872 if (tok != "-") {
1873 mloc = tok;
1874 delete mfmt;
1875 mfmt = MeasureFormat::createCurrencyFormat(
1876 Locale::createFromName(CharString(mloc)), ec);
1877 if (U_FAILURE(ec)) {
1878 errln("FAIL: " + where + "Loc \"" + mloc + "\": " + u_errorName(ec));
1879 ec = U_ZERO_ERROR;
1880 if (!tokens.next(tok, ec)) goto error;
1881 if (!tokens.next(tok, ec)) goto error;
1882 if (!tokens.next(tok, ec)) goto error;
1883 continue;
1884 }
1885 }
1886 // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
1887 if (!tokens.next(currAmt, ec)) goto error;
1888 if (!tokens.next(str, ec)) goto error;
1889 parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
1890 if (assertSuccess("parseCurrencyAmount", ec)) {
1891 assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")",
1892 str, mfmt->format(n, out.remove(), ec));
1893 assertSuccess("format", ec);
1894 }
1895 if (!tokens.next(currAmt, ec)) goto error;
1896 parseCurrencyAmount(currAmt, *ref, (UChar)0x2F/*'/'*/, n, ec);
1897 if (assertSuccess("parseCurrencyAmount", ec)) {
1898 Formattable m;
1899 mfmt->parseObject(str, m, ec);
1900 if (assertSuccess("parseCurrency", ec)) {
1901 assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",
1902 n, m);
1903 }
1904 }
1905 break;
1906 case 6:
1907 // perr: <pattern or '-'> <invalid string>
1908 errln("FAIL: Under construction");
1909 goto done;
1910 case 7: {
1911 // pat: <pattern> <exp. toPattern, or '-' or 'err'>
1912 UnicodeString testpat;
1913 UnicodeString exppat;
1914 if (!tokens.next(testpat, ec)) goto error;
1915 if (!tokens.next(exppat, ec)) goto error;
1916 UBool err = exppat == "err";
1917 UBool existingPat = FALSE;
1918 if (testpat == "-") {
1919 if (err) {
1920 errln("FAIL: " + where + "Invalid command \"pat: - err\"");
1921 continue;
1922 }
1923 existingPat = TRUE;
1924 testpat = pat;
1925 }
1926 if (exppat == "-") exppat = testpat;
1927 DecimalFormat* f = 0;
1928 UErrorCode ec2 = U_ZERO_ERROR;
1929 if (existingPat) {
1930 f = fmt;
1931 } else {
1932 f = new DecimalFormat(testpat, ec2);
1933 }
1934 if (U_SUCCESS(ec2)) {
1935 if (err) {
1936 errln("FAIL: " + where + "Invalid pattern \"" + testpat +
1937 "\" was accepted");
1938 } else {
1939 UnicodeString pat2;
1940 assertEquals(where + "\"" + testpat + "\".toPattern()",
1941 exppat, f->toPattern(pat2));
1942 }
1943 } else {
1944 if (err) {
1945 logln("Ok: " + where + "Invalid pattern \"" + testpat +
1946 "\" failed: " + u_errorName(ec2));
1947 } else {
1948 errln("FAIL: " + where + "Valid pattern \"" + testpat +
1949 "\" failed: " + u_errorName(ec2));
1950 }
1951 }
1952 if (!existingPat) delete f;
1953 } break;
1954 case -1:
1955 errln("FAIL: " + where + "Unknown command \"" + tok + "\"");
1956 goto done;
1957 }
1958 }
1959 goto done;
1960
1961 error:
1962 if (U_SUCCESS(ec)) {
1963 errln("FAIL: Unexpected EOF");
1964 } else {
1965 errln("FAIL: " + where + "Unexpected " + u_errorName(ec));
1966 }
1967
1968 done:
1969 delete mfmt;
1970 delete fmt;
1971 delete ref;
1972}
1973
1974
b75a7d8f
A
1975//----------------------------------------------------------------------
1976// Support methods
1977//----------------------------------------------------------------------
1978
1979UBool NumberFormatTest::equalValue(const Formattable& a, const Formattable& b) {
374ca955
A
1980 if (a.getType() == b.getType()) {
1981 return a == b;
1982 }
1983
b75a7d8f 1984 if (a.getType() == Formattable::kLong) {
374ca955 1985 if (b.getType() == Formattable::kInt64) {
b75a7d8f
A
1986 return a.getLong() == b.getLong();
1987 } else if (b.getType() == Formattable::kDouble) {
374ca955 1988 return (double) a.getLong() == b.getDouble(); // TODO check use of double instead of long
b75a7d8f
A
1989 }
1990 } else if (a.getType() == Formattable::kDouble) {
1991 if (b.getType() == Formattable::kLong) {
1992 return a.getDouble() == (double) b.getLong();
374ca955
A
1993 } else if (b.getType() == Formattable::kInt64) {
1994 return a.getDouble() == (double)b.getInt64();
1995 }
1996 } else if (a.getType() == Formattable::kInt64) {
1997 if (b.getType() == Formattable::kLong) {
1998 return a.getInt64() == (int64_t)b.getLong();
b75a7d8f 1999 } else if (b.getType() == Formattable::kDouble) {
374ca955 2000 return a.getInt64() == (int64_t)b.getDouble();
b75a7d8f
A
2001 }
2002 }
2003 return FALSE;
2004}
2005
2006void NumberFormatTest::expect2(NumberFormat& fmt, const Formattable& n, const UnicodeString& str) {
2007 // Don't round-trip format test, since we explicitly do it
2008 expect(fmt, n, str, FALSE);
2009 expect(fmt, str, n);
2010}
2011
2012void NumberFormatTest::expect2(NumberFormat* fmt, const Formattable& n,
2013 const UnicodeString& exp,
2014 UErrorCode status) {
2015 if (U_FAILURE(status)) {
2016 errln("FAIL: NumberFormat constructor");
2017 } else {
2018 expect2(*fmt, n, exp);
2019 }
2020 delete fmt;
2021}
2022
2023void NumberFormatTest::expect(NumberFormat& fmt, const UnicodeString& str, const Formattable& n) {
2024 UErrorCode status = U_ZERO_ERROR;
2025 Formattable num;
2026 fmt.parse(str, num, status);
2027 if (U_FAILURE(status)) {
2028 errln(UnicodeString("FAIL: Parse failed for \"") + str + "\"");
2029 return;
2030 }
2031 UnicodeString pat;
2032 ((DecimalFormat*) &fmt)->toPattern(pat);
2033 if (equalValue(num, n)) {
2034 logln(UnicodeString("Ok \"") + str + "\" x " +
2035 pat + " = " +
2036 toString(num));
2037 } else {
2038 errln(UnicodeString("FAIL \"") + str + "\" x " +
2039 pat + " = " +
2040 toString(num) + ", expected " + toString(n));
2041 }
2042}
2043
2044void NumberFormatTest::expect(NumberFormat& fmt, const Formattable& n,
2045 const UnicodeString& exp, UBool rt) {
2046 UnicodeString saw;
2047 FieldPosition pos;
2048 UErrorCode status = U_ZERO_ERROR;
2049 fmt.format(n, saw, pos, status);
2050 CHECK(status, "NumberFormat::format");
2051 UnicodeString pat;
2052 ((DecimalFormat*) &fmt)->toPattern(pat);
2053 if (saw == exp) {
2054 logln(UnicodeString("Ok ") + toString(n) + " x " +
2055 escape(pat) + " = \"" +
2056 escape(saw) + "\"");
2057 // We should be able to round-trip the formatted string =>
2058 // number => string (but not the other way around: number
2059 // => string => number2, might have number2 != number):
2060 if (rt) {
2061 Formattable n2;
2062 fmt.parse(exp, n2, status);
2063 if (U_FAILURE(status)) {
2064 errln(UnicodeString("FAIL: Parse failed for \"") + exp + "\"");
2065 return;
2066 }
2067 UnicodeString saw2;
2068 fmt.format(n2, saw2, pos, status);
2069 CHECK(status, "NumberFormat::format");
2070 if (saw2 != exp) {
2071 errln((UnicodeString)"FAIL \"" + exp + "\" => " + toString(n2) +
2072 " => \"" + saw2 + "\"");
2073 }
2074 }
2075 } else {
2076 errln(UnicodeString("FAIL ") + toString(n) + " x " +
2077 escape(pat) + " = \"" +
2078 escape(saw) + "\", expected \"" + exp + "\"");
2079 }
2080}
2081
2082void NumberFormatTest::expect(NumberFormat* fmt, const Formattable& n,
2083 const UnicodeString& exp,
2084 UErrorCode status) {
2085 if (U_FAILURE(status)) {
2086 errln("FAIL: NumberFormat constructor");
2087 } else {
2088 expect(*fmt, n, exp);
2089 }
2090 delete fmt;
2091}
2092
2093void NumberFormatTest::expectCurrency(NumberFormat& nf, const Locale& locale,
2094 double value, const UnicodeString& string) {
2095 UErrorCode ec = U_ZERO_ERROR;
2096 DecimalFormat& fmt = * (DecimalFormat*) &nf;
2097 const UChar DEFAULT_CURR[] = {45/*-*/,0};
374ca955
A
2098 UChar curr[4];
2099 u_strcpy(curr, DEFAULT_CURR);
b75a7d8f 2100 if (*locale.getLanguage() != 0) {
374ca955
A
2101 ucurr_forLocale(locale.getName(), curr, 4, &ec);
2102 assertSuccess("ucurr_forLocale", ec);
2103 fmt.setCurrency(curr, ec);
2104 assertSuccess("DecimalFormat::setCurrency", ec);
73c04bcf 2105 fmt.setCurrency(curr); //Deprecated variant, for coverage only
b75a7d8f
A
2106 }
2107 UnicodeString s;
2108 fmt.format(value, s);
2109 s.findAndReplace((UChar32)0x00A0, (UChar32)0x0020);
2110
2111 // Default display of the number yields "1234.5599999999999"
2112 // instead of "1234.56". Use a formatter to fix this.
2113 NumberFormat* f =
2114 NumberFormat::createInstance(Locale::getUS(), ec);
2115 UnicodeString v;
2116 if (U_FAILURE(ec)) {
2117 // Oops; bad formatter. Use default op+= display.
2118 v = (UnicodeString)"" + value;
2119 } else {
2120 f->setMaximumFractionDigits(4);
2121 f->setGroupingUsed(FALSE);
2122 f->format(value, v);
2123 }
2124 delete f;
2125
2126 if (s == string) {
2127 logln((UnicodeString)"Ok: " + v + " x " + curr + " => " + prettify(s));
2128 } else {
2129 errln((UnicodeString)"FAIL: " + v + " x " + curr + " => " + prettify(s) +
2130 ", expected " + prettify(string));
2131 }
2132}
2133
2134void NumberFormatTest::expectPat(DecimalFormat& fmt, const UnicodeString& exp) {
2135 UnicodeString pat;
2136 fmt.toPattern(pat);
2137 if (pat == exp) {
2138 logln(UnicodeString("Ok \"") + pat + "\"");
2139 } else {
2140 errln(UnicodeString("FAIL \"") + pat + "\", expected \"" + exp + "\"");
2141 }
2142}
2143
2144void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2145 int32_t pos) {
2146 expectPad(fmt, pat, pos, 0, (UnicodeString)"");
2147}
2148void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2149 int32_t pos, int32_t width, UChar pad) {
2150 expectPad(fmt, pat, pos, width, UnicodeString(pad));
2151}
2152void NumberFormatTest::expectPad(DecimalFormat& fmt, const UnicodeString& pat,
2153 int32_t pos, int32_t width, const UnicodeString& pad) {
2154 int32_t apos = 0, awidth = 0;
2155 UnicodeString apadStr;
2156 UErrorCode status = U_ZERO_ERROR;
2157 fmt.applyPattern(pat, status);
2158 if (U_SUCCESS(status)) {
2159 apos = fmt.getPadPosition();
2160 awidth = fmt.getFormatWidth();
2161 apadStr=fmt.getPadCharacterString();
2162 } else {
2163 apos = -1;
2164 awidth = width;
2165 apadStr = pad;
2166 }
2167 if (apos == pos && awidth == width && apadStr == pad) {
374ca955
A
2168 UnicodeString infoStr;
2169 if (pos == ILLEGAL) {
2170 infoStr = UnicodeString(" width=", "") + awidth + UnicodeString(" pad=", "") + apadStr;
2171 }
2172 logln(UnicodeString("Ok \"") + pat + "\" pos=" + apos + infoStr);
b75a7d8f
A
2173 } else {
2174 errln(UnicodeString("FAIL \"") + pat + "\" pos=" + apos +
2175 " width=" + awidth + " pad=" + apadStr +
2176 ", expected " + pos + " " + width + " " + pad);
2177 }
2178}
73c04bcf
A
2179void NumberFormatTest::TestJB3832(){
2180 const char* localeID = "pt_PT@currency=PTE";
2181 Locale loc(localeID);
2182 UErrorCode status = U_ZERO_ERROR;
2183 UnicodeString expected("1,150$50 Esc.");
2184 UnicodeString s;
2185 NumberFormat* currencyFmt = NumberFormat::createCurrencyInstance(loc, status);
2186 if(U_FAILURE(status)){
2187 errln("Could not create currency formatter for locale %s", localeID);
2188 return;
2189 }
2190 currencyFmt->format(1150.50, s);
2191 if(s!=expected){
2192 errln(UnicodeString("FAIL: Expected: ")+expected
2193 + UnicodeString(" Got: ") + s
2194 + UnicodeString( " for locale: ")+ UnicodeString(localeID) );
2195 }
2196 if (U_FAILURE(status)){
2197 errln("FAIL: Status %s", u_errorName(status));
2198 }
2199 delete currencyFmt;
2200}
2201
2202void NumberFormatTest::TestHost()
2203{
2204#ifdef U_WINDOWS
2205 Win32NumberTest::testLocales(this);
2206#endif
2207}
2208
2209void NumberFormatTest::TestCurrencyFormat()
2210{
2211 // This test is here to increase code coverage.
2212 UErrorCode status = U_ZERO_ERROR;
2213 MeasureFormat *cloneObj;
2214 UnicodeString str;
2215 Formattable toFormat, result;
2216 static const UChar ISO_CODE[4] = {0x0047, 0x0042, 0x0050, 0};
2217
2218 Locale saveDefaultLocale = Locale::getDefault();
2219 Locale::setDefault( Locale::getUK(), status );
2220 if (U_FAILURE(status)) {
2221 errln("couldn't set default Locale!");
2222 return;
2223 }
2224
2225 MeasureFormat *measureObj = MeasureFormat::createCurrencyFormat(status);
2226 Locale::setDefault( saveDefaultLocale, status );
2227 if (U_FAILURE(status)){
2228 errln("FAIL: Status %s", u_errorName(status));
2229 return;
2230 }
2231 cloneObj = (MeasureFormat *)measureObj->clone();
2232 if (cloneObj == NULL) {
2233 errln("Clone doesn't work");
2234 return;
2235 }
2236 toFormat.adoptObject(new CurrencyAmount(1234.56, ISO_CODE, status));
2237 measureObj->format(toFormat, str, status);
2238 measureObj->parseObject(str, result, status);
2239 if (U_FAILURE(status)){
2240 errln("FAIL: Status %s", u_errorName(status));
2241 }
2242 if (result != toFormat) {
2243 errln("measureObj does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
2244 }
2245 status = U_ZERO_ERROR;
2246 str.truncate(0);
2247 cloneObj->format(toFormat, str, status);
2248 cloneObj->parseObject(str, result, status);
2249 if (U_FAILURE(status)){
2250 errln("FAIL: Status %s", u_errorName(status));
2251 }
2252 if (result != toFormat) {
2253 errln("Clone does not round trip. Formatted string was \"" + str + "\" Got: " + toString(result) + " Expected: " + toString(toFormat));
2254 }
2255 delete measureObj;
2256 delete cloneObj;
2257
2258}
b75a7d8f
A
2259
2260#endif /* #if !UCONFIG_NO_FORMATTING */