]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/numrgts.cpp
ICU-551.41.tar.gz
[apple/icu.git] / icuSources / test / intltest / numrgts.cpp
1 /***********************************************************************
2 * Copyright (c) 1997-2014, International Business Machines Corporation
3 * and others. All Rights Reserved.
4 ***********************************************************************/
5
6 #include "unicode/utypes.h"
7
8 #if !UCONFIG_NO_FORMATTING
9
10 #include "numrgts.h"
11
12 #include <float.h> // DBL_MIN, DBL_MAX
13 #include <stdio.h>
14
15 #include "unicode/dcfmtsym.h"
16 #include "unicode/decimfmt.h"
17 #include "unicode/locid.h"
18 #include "unicode/resbund.h"
19 #include "unicode/calendar.h"
20 #include "unicode/datefmt.h"
21 #include "unicode/ucurr.h"
22 #include "putilimp.h"
23
24 class MyNumberFormatTest : public NumberFormat
25 {
26 public:
27
28 virtual UClassID getDynamicClassID(void) const;
29
30 virtual UnicodeString& format( double number,
31 UnicodeString& toAppendTo,
32 FieldPositionIterator* posIter,
33 UErrorCode& status) const
34 {
35 return NumberFormat::format(number, toAppendTo, posIter, status);
36 }
37
38 /* Just keep this here to make some of the compilers happy */
39 virtual UnicodeString& format(const Formattable& obj,
40 UnicodeString& toAppendTo,
41 FieldPosition& pos,
42 UErrorCode& status) const
43 {
44 return NumberFormat::format(obj, toAppendTo, pos, status);
45 }
46
47 /* Just use one of the format functions */
48 virtual UnicodeString& format( double /* number */,
49 UnicodeString& toAppendTo,
50 FieldPosition& /* pos */) const
51 {
52 toAppendTo = "";
53 return toAppendTo;
54 }
55
56 /*
57 public Number parse(String text, ParsePosition parsePosition)
58 { return new Integer(0); }
59 */
60
61 /* Just use one of the parse functions */
62 virtual void parse( const UnicodeString& /* text */,
63 Formattable& result,
64 ParsePosition& /* parsePosition */) const
65 {
66 result.setLong((int32_t)0);
67 }
68
69 virtual void parse( const UnicodeString& text,
70 Formattable& result,
71 UErrorCode& status) const
72 {
73 NumberFormat::parse(text, result, status);
74 }
75 virtual Format* clone() const
76 { return NULL; }
77
78 virtual UnicodeString& format(int32_t,
79 UnicodeString& foo,
80 FieldPosition&) const
81 { return foo.remove(); }
82
83 virtual UnicodeString& format(int64_t,
84 UnicodeString& foo,
85 FieldPosition&) const
86 { return foo.remove(); }
87
88 virtual void applyPattern(const UnicodeString&, UParseError&, UErrorCode&){
89 }
90 };
91
92 int32_t gMyNumberFormatTestClassID;
93 UClassID MyNumberFormatTest::getDynamicClassID() const
94 {
95 return (UClassID)&gMyNumberFormatTestClassID;
96 }
97
98
99 // *****************************************************************************
100 // class NumberFormatRegressionTest
101 // *****************************************************************************
102
103 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
104
105 void
106 NumberFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
107 {
108 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
109 switch (index) {
110 CASE(0,Test4075713);
111 CASE(1,Test4074620);
112 CASE(2,Test4088161);
113 CASE(3,Test4087245);
114 CASE(4,Test4087535);
115 CASE(5,Test4088503);
116 CASE(6,Test4066646);
117 CASE(7,Test4059870);
118 CASE(8,Test4083018);
119 CASE(9,Test4071492);
120 CASE(10,Test4086575);
121 CASE(11,Test4068693);
122 CASE(12,Test4069754);
123 CASE(13,Test4087251);
124 CASE(14,Test4090489);
125 CASE(15,Test4090504);
126 CASE(16,Test4095713);
127 CASE(17,Test4092561);
128 CASE(18,Test4092480);
129 CASE(19,Test4087244);
130 CASE(20,Test4070798);
131 CASE(21,Test4071005);
132 CASE(22,Test4071014);
133 CASE(23,Test4071859);
134 CASE(24,Test4093610);
135 CASE(25,Test4098741);
136 CASE(26,Test4074454);
137 CASE(27,Test4099404);
138 CASE(28,Test4101481);
139 CASE(29,Test4052223);
140 CASE(30,Test4061302);
141 CASE(31,Test4062486);
142 CASE(32,Test4108738);
143 CASE(33,Test4106658);
144 CASE(34,Test4106662);
145 CASE(35,Test4114639);
146 CASE(36,Test4106664);
147 CASE(37,Test4106667);
148 CASE(38,Test4110936);
149 CASE(39,Test4122840);
150 CASE(40,Test4125885);
151 CASE(41,Test4134034);
152 CASE(42,Test4134300);
153 CASE(43,Test4140009);
154 CASE(44,Test4141750);
155 CASE(45,Test4145457);
156 CASE(46,Test4147295);
157 CASE(47,Test4147706);
158 CASE(48,Test4162198);
159 CASE(49,Test4162852);
160 CASE(50,Test4167494);
161 CASE(51,Test4170798);
162 CASE(52,Test4176114);
163 CASE(53,Test4179818);
164 CASE(54,Test4212072);
165 CASE(55,Test4216742);
166 CASE(56,Test4217661);
167 CASE(57,Test4161100);
168 CASE(58,Test4243011);
169 CASE(59,Test4243108);
170 CASE(60,TestJ691);
171 CASE(61,Test8199);
172 CASE(62,Test9109);
173 CASE(63,Test9780);
174 CASE(64,Test9677);
175 CASE(65,Test10361);
176
177 default: name = ""; break;
178 }
179 }
180
181 UBool
182 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const Locale& l, UBool possibleDataError)
183 {
184 if(U_FAILURE(status)) {
185 if (possibleDataError) {
186 dataerrln(UnicodeString("FAIL: ", "") + msg
187 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),""));
188 } else {
189 errcheckln(status, UnicodeString("FAIL: ", "") + msg
190 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),""));
191 }
192 return TRUE;
193 }
194
195 return FALSE;
196 }
197
198 UBool
199 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const char *l, UBool possibleDataError)
200 {
201 if(U_FAILURE(status)) {
202 if (possibleDataError) {
203 dataerrln(UnicodeString("FAIL: ", "") + msg
204 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, ""));
205 } else {
206 errcheckln(status, UnicodeString("FAIL: ", "") + msg
207 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, ""));
208 }
209 return TRUE;
210 }
211
212 return FALSE;
213 }
214
215 UBool
216 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, UBool possibleDataError)
217 {
218 if(U_FAILURE(status)) {
219 if (possibleDataError) {
220 dataerrln(UnicodeString("FAIL: ", "") + msg
221 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), ""));
222 } else {
223 errcheckln(status, UnicodeString("FAIL: ", "") + msg
224 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), ""));
225 }
226 return TRUE;
227 }
228
229 return FALSE;
230 }
231
232 /**
233 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects
234 */
235 inline UnicodeString str(const char *input)
236 {
237 return CharsToUnicodeString(input);
238 }
239
240 /* @bug 4075713
241 * NumberFormat.equals comparing with null should always return false.
242 */
243 // {sfb} kind of silly in C++, just checking for new success
244 void NumberFormatRegressionTest::Test4075713(void)
245 {
246 //try {
247 MyNumberFormatTest *tmp = new MyNumberFormatTest();
248 if(tmp != NULL)
249 logln("NumberFormat.equals passed");
250 /*} catch (NullPointerException e) {
251 errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception");
252 }*/
253
254 delete tmp;
255 }
256
257 /* @bug 4074620
258 * NumberFormat.equals comparing two obj equal even the setGroupingUsed
259 * flag is different.
260 */
261 void NumberFormatRegressionTest::Test4074620(void)
262 {
263
264 MyNumberFormatTest *nf1 = new MyNumberFormatTest();
265 MyNumberFormatTest *nf2 = new MyNumberFormatTest();
266
267 nf1->setGroupingUsed(FALSE);
268 nf2->setGroupingUsed(TRUE);
269
270 if(nf1 == nf2)
271 errln("Test for bug 4074620 failed");
272 else
273 logln("Test for bug 4074620 passed.");
274
275 delete nf1;
276 delete nf2;
277 }
278
279
280 /* @bug 4088161
281 * DecimalFormat.format() incorrectly uses maxFractionDigits setting.
282 */
283
284 void NumberFormatRegressionTest::Test4088161 (void)
285 {
286 UErrorCode status = U_ZERO_ERROR;
287 DecimalFormat *df = new DecimalFormat(status);
288 if (!failure(status, "new DecimalFormat", "")) {
289 double d = 100;
290 df->setMinimumFractionDigits(0);
291 df->setMaximumFractionDigits(16);
292 UnicodeString sBuf1;
293 FieldPosition fp1(0);
294 logln(UnicodeString("d = ") + d);
295 logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits());
296
297 logln(" format(d) = '" + df->format(d, sBuf1, fp1) + "'");
298 df->setMaximumFractionDigits(17);
299 UnicodeString sBuf2;
300 FieldPosition fp2(0);
301 logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits());
302 sBuf2 = df->format(d, sBuf2, fp2);
303 if(sBuf2 != "100")
304 errln(" format(d) = '" + sBuf2 + "'");
305 }
306
307 delete df;
308 }
309
310 /* @bug 4087245
311 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat.
312 * DecimalFormat(String, DecimalFormatSymbols).
313 */
314 void NumberFormatRegressionTest::Test4087245 (void)
315 {
316 UErrorCode status = U_ZERO_ERROR;
317 DecimalFormatSymbols *symbols = new DecimalFormatSymbols(status);
318 failure(status, "new DecimalFormatSymbols", "");
319 // {sfb} One note about this test: if you pass in a pointer
320 // to the symbols, they are adopted and this test will fail,
321 // even though that is the correct behavior. To test the cloning
322 // of the symbols, it is necessary to pass in a reference to the symbols
323 DecimalFormat *df = new DecimalFormat("#,##0.0", *symbols, status);
324 failure(status, "new DecimalFormat with symbols", "");
325 int32_t n = 123;
326 UnicodeString buf1;
327 UnicodeString buf2;
328 FieldPosition pos(FieldPosition::DONT_CARE);
329 logln(UnicodeString("format(") + n + ") = " +
330 df->format(n, buf1, pos));
331 symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, UnicodeString((UChar)0x70)); // change value of field
332 logln(UnicodeString("format(") + n + ") = " +
333 df->format(n, buf2, pos));
334 if(buf1 != buf2)
335 errln("Test for bug 4087245 failed");
336
337 delete df;
338 delete symbols;
339 }
340
341 /* @bug 4087535
342 * DecimalFormat.format() incorrectly formats 0.0
343 */
344 void NumberFormatRegressionTest::Test4087535 (void)
345 {
346 UErrorCode status = U_ZERO_ERROR;
347 DecimalFormat *df = new DecimalFormat(status);
348 failure(status, "new DecimalFormat", "");
349 df->setMinimumIntegerDigits(0);
350
351 double n = 0;
352 UnicodeString buffer;
353 FieldPosition pos(FieldPosition::DONT_CARE);
354 buffer = df->format(n, buffer, pos);
355 if (buffer.length() == 0)
356 errln(/*n + */": '" + buffer + "'");
357 n = 0.1;
358 buffer = df->format(n, buffer, pos);
359 if (buffer.length() == 0)
360 errln(/*n + */": '" + buffer + "'");
361
362 delete df;
363 }
364
365 /* @bug 4088503
366 * DecimalFormat.format fails when groupingSize is set to 0.
367 */
368 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ??
369 void NumberFormatRegressionTest::Test4088503 (void)
370 {
371 UErrorCode status = U_ZERO_ERROR;
372 DecimalFormat *df = new DecimalFormat(status);
373 failure(status, "new DecimalFormat", "");
374 df->setGroupingSize(0);
375 UnicodeString sBuf;
376 FieldPosition fp(FieldPosition::DONT_CARE);
377 //try {
378 logln(df->format((int32_t)123, sBuf, fp));
379 //if(fp == FieldPosition(0))
380 // errln("Test for bug 4088503 failed.");
381 /*} catch (Exception foo) {
382 errln("Test for bug 4088503 failed.");
383 }*/
384 delete df;
385
386 }
387 /* @bug 4066646
388 * NumberFormat.getCurrencyInstance is wrong.
389 */
390 void NumberFormatRegressionTest::Test4066646 (void)
391 {
392 assignFloatValue(2.04f);
393 assignFloatValue(2.03f);
394 assignFloatValue(2.02f);
395 assignFloatValue(0.0f);
396 }
397
398 float
399 NumberFormatRegressionTest::assignFloatValue(float returnfloat)
400 {
401 logln(UnicodeString(" VALUE ") + returnfloat);
402 UErrorCode status = U_ZERO_ERROR;
403 NumberFormat *nfcommon = NumberFormat::createCurrencyInstance(Locale::getUS(), status);
404 if (failure(status, "NumberFormat::createCurrencyInstance", Locale::getUS(), TRUE)){
405 delete nfcommon;
406 return returnfloat;
407 }
408 nfcommon->setGroupingUsed(FALSE);
409
410 UnicodeString stringValue;
411 stringValue = nfcommon->format(returnfloat, stringValue);
412 logln(" DISPLAYVALUE " + stringValue);
413 Formattable result;
414 nfcommon->parse(stringValue, result, status);
415 failure(status, "nfcommon->parse", Locale::getUS());
416 float floatResult = (float) (result.getType() == Formattable::kDouble
417 ? result.getDouble() : result.getLong());
418 if( uprv_fabs(floatResult - returnfloat) > 0.0001)
419 //String stringValue = nfcommon.format(returnfloat).substring(1);
420 //if (Float.valueOf(stringValue).floatValue() != returnfloat)
421 errln(UnicodeString("FAIL: expected ") + returnfloat + ", got " + floatResult + " (" + stringValue+")");
422
423 delete nfcommon;
424 return returnfloat;
425 } // End Of assignFloatValue()
426
427 /* @bug 4059870
428 * DecimalFormat throws exception when parsing "0"
429 */
430 void NumberFormatRegressionTest::Test4059870(void)
431 {
432 UErrorCode status = U_ZERO_ERROR;
433 DecimalFormat *format = new DecimalFormat("00", status);
434 failure(status, "new Decimalformat", Locale::getUS());
435 //try {
436 Formattable result;
437 UnicodeString str;
438 format->parse(UnicodeString("0"), result, status);
439 failure(status, "format->parse", Locale::getUS());
440
441 /*}
442 catch (Exception e) {
443 errln("Test for bug 4059870 failed : " + e);
444 }*/
445
446 delete format;
447 }
448 /* @bug 4083018
449 * DecimalFormatSymbol.equals should always return false when
450 * comparing with null.
451 */
452 // {sfb} this is silly in C++
453 void NumberFormatRegressionTest::Test4083018 (void)
454 {
455 UErrorCode status = U_ZERO_ERROR;
456 DecimalFormatSymbols *dfs = new DecimalFormatSymbols(status);
457 failure(status, "new DecimalFormatSymbols", Locale::getUS());
458 //try {
459 if (dfs != NULL)
460 logln("Test Passed!");
461 else
462 errln("Test for bug 4083018 failed");
463 /*} catch (Exception foo) {
464 errln("Test for bug 4083018 failed => Message : " + foo.getMessage());
465 }*/
466
467 delete dfs;
468 }
469
470 /* @bug 4071492
471 * DecimalFormat does not round up correctly.
472 */
473 void NumberFormatRegressionTest::Test4071492 (void)
474 {
475 double x = 0.00159999;
476 UErrorCode status = U_ZERO_ERROR;
477 NumberFormat *nf = NumberFormat::createInstance(status);
478 if (failure(status, "NumberFormat::createInstance", Locale::getUS(), TRUE)) {
479 delete nf;
480 return;
481 }
482 nf->setMaximumFractionDigits(4);
483 UnicodeString out;
484 FieldPosition pos(FieldPosition::DONT_CARE);
485 out = nf->format(x, out, pos);
486 logln("0.00159999 formats with 4 fractional digits to " + out);
487 UnicodeString expected("0.0016");
488 if (out != expected)
489 errln("FAIL: Expected " + expected);
490
491 delete nf;
492 }
493
494 /* @bug 4086575
495 * A space as a group separator for localized pattern causes
496 * wrong format. WorkAround : use non-breaking space.
497 */
498 void NumberFormatRegressionTest::Test4086575(void)
499 {
500 UErrorCode status = U_ZERO_ERROR;
501 NumberFormat *nf1 = NumberFormat::createInstance(Locale::getFrance(), status);
502
503 // TODO: There is not a good way to find out that the creation of this number format has
504 // failed. Major rewiring of format construction proposed.
505 if(U_FAILURE(status)) {
506 dataerrln("Something is wrong with French number format - it should not fallback. Exitting - %s", u_errorName(status));
507 delete nf1;
508 return;
509 }
510 failure(status, "NumberFormat::createInstance", Locale::getFrance());
511
512 // C++ workaround to make sure cast works
513 DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nf1);
514 if(nf == NULL) {
515 errln("NumberFormat::createInstance returned incorrect type.");
516 return;
517 }
518
519 UnicodeString temp;
520 logln("nf toPattern1: " + nf->toPattern(temp));
521 logln("nf toLocPattern1: " + nf->toLocalizedPattern(temp));
522
523 // No group separator
524 logln("...applyLocalizedPattern ###,00;(###,00) ");
525 nf->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status);
526 failure(status, "nf->applyLocalizedPattern", Locale::getFrance());
527 logln("nf toPattern2: " + nf->toPattern(temp));
528 logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp));
529
530 FieldPosition pos(FieldPosition::DONT_CARE);
531 logln("nf: " + nf->format((int32_t)1234, temp, pos)); // 1234,00
532 logln("nf: " + nf->format((int32_t)-1234, temp, pos)); // (1234,00)
533
534 // Space as group separator
535
536 logln("...applyLocalizedPattern # ###,00;(# ###,00) ");
537 // nbsp = \u00a0
538 //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)");
539 UChar patChars[] = {
540 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b,
541 0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29
542 };
543 UnicodeString pat(patChars, 19, 19);
544 nf->applyLocalizedPattern(pat, status);
545 failure(status, "nf->applyLocalizedPattern", Locale::getFrance());
546 logln("nf toPattern2: " + nf->toPattern(temp));
547 logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp));
548 UnicodeString buffer;
549 buffer = nf->format((int32_t)1234, buffer, pos);
550 //if (buffer != UnicodeString("1\u00a0234,00"))
551 UChar c[] = {
552 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30
553 };
554 UnicodeString cc(c, 8, 8);
555 if (buffer != cc)
556 errln("nf : " + buffer); // Expect 1 234,00
557
558 buffer.remove();
559 buffer = nf->format((int32_t)-1234, buffer, pos);
560 UChar c1[] = {
561 0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29
562 };
563 UnicodeString cc1(c1, 10, 10);
564 if (buffer != cc1)
565 errln("nf : " + buffer); // Expect (1 234,00)
566
567 // Erroneously prints:
568 // 1234,00 ,
569 // (1234,00 ,)
570
571 delete nf1;
572 }
573 /* @bug 4068693
574 * DecimalFormat.parse returns wrong value
575 */
576 // {sfb} slightly converted into a round-trip test, since in C++
577 // there is no Double.toString()
578 void NumberFormatRegressionTest::Test4068693(void)
579 {
580 logln("----- Test Application -----");
581 ParsePosition pos(0);
582 UErrorCode status = U_ZERO_ERROR;
583 DecimalFormat *df = new DecimalFormat(status);
584 if(U_FAILURE(status)) {
585 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
586 delete df;
587 return;
588 }
589 failure(status, "new DecimalFormat");
590 Formattable d;
591 //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0));
592 df->parse(UnicodeString("123.55456"), d, pos);
593 //if (!d.toString().equals("123.55456")) {
594 UnicodeString dstr;
595 df->setMaximumFractionDigits(999);
596 df->setMaximumIntegerDigits(999);
597 FieldPosition fp(FieldPosition::DONT_CARE);
598 dstr = df->format(d.getDouble(), dstr, fp);
599 if (dstr != UnicodeString("123.55456")) {
600 errln(UnicodeString("Result -> ") + d.getDouble());
601 }
602
603 delete df;
604 }
605
606 /* @bug 4069754, 4067878
607 * null pointer thrown when accessing a deserialized DecimalFormat
608 * object.
609 */
610 // {sfb} doesn't apply in C++
611 void NumberFormatRegressionTest::Test4069754(void)
612 {
613 /* try {
614 myformat it = new myformat();
615 logln(it.Now());
616 FileOutputStream ostream = new FileOutputStream("t.tmp");
617 ObjectOutputStream p = new ObjectOutputStream(ostream);
618 p.writeObject(it);
619 ostream.close();
620 logln("Saved ok.");
621
622 FileInputStream istream = new FileInputStream("t.tmp");
623 ObjectInputStream p2 = new ObjectInputStream(istream);
624 myformat it2 = (myformat)p2.readObject();
625 logln(it2.Now());
626 istream.close();
627 logln("Loaded ok.");
628 } catch (Exception foo) {
629 errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
630 }
631 */}
632
633 /* @bug 4087251
634 * DecimalFormat.applyPattern(String) allows illegal patterns
635 */
636 void NumberFormatRegressionTest::Test4087251 (void)
637 {
638 UErrorCode status = U_ZERO_ERROR;
639 DecimalFormat *df = new DecimalFormat(status);
640 if(U_FAILURE(status)) {
641 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
642 delete df;
643 return;
644 }
645 failure(status, "new DecimalFormat");
646 //try {
647 df->applyPattern(UnicodeString("#.#.#"), status);
648 if( ! U_FAILURE(status))
649 errln("df->applyPattern with illegal pattern didn't fail");
650 UnicodeString temp;
651 logln("toPattern() returns \"" + df->toPattern(temp) + "\"");
652 //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException");
653 /*} catch (IllegalArgumentException e) {
654 logln("Caught Illegal Argument Error !");
655 }*/
656 // Second test; added 5/11/98 when reported to fail on 1.2b3
657 //try {
658 df->applyPattern("#0.0#0#0", status);
659 if( ! U_FAILURE(status))
660 errln("df->applyPattern with illegal pattern didn't fail");
661 logln("toPattern() returns \"" + df->toPattern(temp) + "\"");
662 //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException");
663 /*} catch (IllegalArgumentException e) {
664 logln("Ok - IllegalArgumentException for #0.0#0#0");
665 }*/
666
667 delete df;
668 }
669
670 /* @bug 4090489
671 * DecimalFormat.format() loses precision
672 */
673 void NumberFormatRegressionTest::Test4090489 (void)
674 {
675 // {sfb} sprintf doesn't correctly handle the double, so there is nothing
676 // that NumberFormat can do. For some reason, it does not format the last 1.
677
678 /* UErrorCode status = U_ZERO_ERROR;
679 DecimalFormat *df = new DecimalFormat(status);
680 failure(status, "new DecimalFormat");
681 df->setMinimumFractionDigits(10);
682 df->setMaximumFractionDigits(999);
683 df->setGroupingUsed(FALSE);
684 double d = 1.000000000000001E7;
685 //BigDecimal bd = new BigDecimal(d);
686 UnicodeString sb;
687 FieldPosition fp(0);
688 logln(UnicodeString("d = ") + d);
689 //logln("BigDecimal.toString(): " + bd.toString());
690 df->format(d, sb, fp);
691 if (sb != "10000000.0000000100") {
692 errln("DecimalFormat.format(): " + sb);
693 }
694 */
695 }
696
697 /* @bug 4090504
698 * DecimalFormat.format() loses precision
699 */
700 void NumberFormatRegressionTest::Test4090504 (void)
701 {
702 double d = 1;
703 logln(UnicodeString("d = ") + d);
704 UErrorCode status = U_ZERO_ERROR;
705 DecimalFormat *df = new DecimalFormat(status);
706 if(U_FAILURE(status)) {
707 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
708 delete df;
709 return;
710 }
711 failure(status, "new DecimalFormat");
712 UnicodeString sb;
713 FieldPosition fp(FieldPosition::DONT_CARE);
714 //try {
715 for (int i = 17; i <= 20; i++) {
716 df->setMaximumFractionDigits(i);
717 //sb = new StringBuffer("");
718 fp.setField(0);
719 logln(UnicodeString(" getMaximumFractionDigits() = ") + i);
720 logln(UnicodeString(" formated: ") + df->format(d, sb, fp));
721 }
722 /*} catch (Exception foo) {
723 errln("Bug 4090504 regression test failed. Message : " + foo.getMessage());
724 }*/
725
726 delete df;
727 }
728 /* @bug 4095713
729 * DecimalFormat.parse(String str, ParsePosition pp) loses precision
730 */
731 void NumberFormatRegressionTest::Test4095713 (void)
732 {
733 UErrorCode status = U_ZERO_ERROR;
734 DecimalFormat *df = new DecimalFormat(status);
735 if(U_FAILURE(status)) {
736 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
737 delete df;
738 return;
739 }
740 failure(status, "new DecimalFormat");
741 UnicodeString str("0.1234");
742 double d1 = 0.1234;
743 //Double d1 = new Double(str);
744 //Double d2 = (Double) df.parse(str, new ParsePosition(0));
745 Formattable d2;
746 ParsePosition pp(0);
747 df->parse(str, d2, pp);
748 logln(UnicodeString("") + d1);
749 if (d2.getDouble() != d1)
750 errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2.getDouble());
751 delete df;
752 }
753
754 /* @bug 4092561
755 * DecimalFormat.parse() fails when multiplier is not set to 1
756 */
757 // {sfb} not sure what to do with this one
758 void NumberFormatRegressionTest::Test4092561 (void)
759 {
760 UErrorCode status = U_ZERO_ERROR;
761 DecimalFormat *df = new DecimalFormat(status);
762 if(U_FAILURE(status)) {
763 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
764 delete df;
765 return;
766 }
767 failure(status, "new DecimalFormat");
768
769 // {sfb} going to cheat here and use sprintf ??
770
771 /*UnicodeString str = Long.toString(Long.MIN_VALUE);
772 logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString());
773 df.setMultiplier(100);
774 Number num = df.parse(str, new ParsePosition(0));
775 if (num.doubleValue() != -9.223372036854776E16)
776 errln("Bug 4092561 test failed when multiplier is set to not 1.");
777 */
778 delete df;
779 }
780
781 /* @bug 4092480
782 * DecimalFormat: Negative format ignored.
783 */
784 void NumberFormatRegressionTest::Test4092480 (void)
785 {
786 UErrorCode status = U_ZERO_ERROR;
787 DecimalFormat *dfFoo = new DecimalFormat(UnicodeString("000"), status);
788 if(U_FAILURE(status)) {
789 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
790 delete dfFoo;
791 return;
792 }
793 failure(status, "new DecimalFormat");
794
795 //try {
796 dfFoo->applyPattern("0000;-000", status);
797 failure(status, "dfFoo->applyPattern");
798 UnicodeString temp;
799 if (dfFoo->toPattern(temp) != UnicodeString("#0000"))
800 errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
801 FieldPosition pos(FieldPosition::DONT_CARE);
802 logln(dfFoo->format((int32_t)42, temp, pos));
803 logln(dfFoo->format((int32_t)-42, temp, pos));
804 dfFoo->applyPattern("000;-000", status);
805 failure(status, "dfFoo->applyPattern");
806 if (dfFoo->toPattern(temp) != UnicodeString("#000"))
807 errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
808 logln(dfFoo->format((int32_t)42,temp, pos));
809 logln(dfFoo->format((int32_t)-42, temp, pos));
810
811 dfFoo->applyPattern("000;-0000", status);
812 failure(status, "dfFoo->applyPattern");
813 if (dfFoo->toPattern(temp) != UnicodeString("#000"))
814 errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
815 logln(dfFoo->format((int32_t)42, temp, pos));
816 logln(dfFoo->format((int32_t)-42, temp, pos));
817
818 dfFoo->applyPattern("0000;-000", status);
819 failure(status, "dfFoo->applyPattern");
820 if (dfFoo->toPattern(temp) != UnicodeString("#0000"))
821 errln("dfFoo.toPattern : " + dfFoo->toPattern(temp));
822 logln(dfFoo->format((int32_t)42, temp, pos));
823 logln(dfFoo->format((int32_t)-42, temp, pos));
824 /*} catch (Exception foo) {
825 errln("Message " + foo.getMessage());
826 }*/
827
828 delete dfFoo;
829 }
830 /* @bug 4087244
831 * NumberFormat.getCurrencyInstance() produces format that uses
832 * decimal separator instead of monetary decimal separator.
833 *
834 * Rewrote this test not to depend on the actual pattern. Pattern should
835 * never contain the monetary separator! Decimal separator in pattern is
836 * interpreted as monetary separator if currency symbol is seen!
837 */
838 void NumberFormatRegressionTest::Test4087244 (void) {
839 UErrorCode status = U_ZERO_ERROR;
840 char loc[256] = {0};
841 uloc_canonicalize("pt_PT_PREEURO", loc, 256, &status);
842 Locale *de = new Locale(loc);
843 NumberFormat *nf = NumberFormat::createCurrencyInstance(*de, status);
844 if(U_FAILURE(status)) {
845 dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
846 delete nf;
847 return;
848 }
849 DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
850 if(df == NULL) {
851 errln("expected DecimalFormat!");
852 return;
853 }
854 const DecimalFormatSymbols *sym = df->getDecimalFormatSymbols();
855 UnicodeString decSep = sym->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
856 UnicodeString monSep = sym->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
857 if (decSep == monSep) {
858 errln("ERROR in test: want decimal sep != monetary sep");
859 return;
860 }
861 df->setMinimumIntegerDigits(1);
862 df->setMinimumFractionDigits(2);
863 UnicodeString str;
864 FieldPosition pos;
865 df->format(1.23, str, pos);
866 UnicodeString monStr("1x23");
867 monStr.replace((int32_t)1, 1, monSep);
868 UnicodeString decStr("1x23");
869 decStr.replace((int32_t)1, 1, decSep);
870 if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) {
871 logln(UnicodeString("OK: 1.23 -> \"") + str + "\" contains \"" +
872 monStr + "\" and not \"" + decStr + '"');
873 } else {
874 errln(UnicodeString("FAIL: 1.23 -> \"") + str + "\", should contain \"" +
875 monStr +
876 "\" and not \"" + decStr + '"');
877 }
878 delete de;
879 delete nf;
880 }
881 /* @bug 4070798
882 * Number format data rounding errors for locale FR
883 */
884 void NumberFormatRegressionTest::Test4070798 (void)
885 {
886 NumberFormat *formatter;
887 UnicodeString tempString;
888
889 /* User error :
890 String expectedDefault = "-5\u00a0789,987";
891 String expectedCurrency = "5\u00a0789,98\u00a0F";
892 String expectedPercent = "-578\u00a0998%";
893 */
894 UChar chars1 [] = {
895 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
896 };
897 UChar chars2 [] = {
898 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x46
899 };
900 UChar chars3 [] = {
901 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
902 };
903 UnicodeString expectedDefault(chars1, 10, 10);
904 UnicodeString expectedCurrency(chars2, 10, 10);
905 UnicodeString expectedPercent(chars3, 10, 10);
906
907 UErrorCode status = U_ZERO_ERROR;
908 char loc[256]={0};
909 int len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
910 (void)len; // Suppress set but not used warning.
911 formatter = NumberFormat::createInstance(Locale(loc), status);
912 if(U_FAILURE(status)) {
913 dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
914 delete formatter;
915 return;
916 }
917 failure(status, "NumberFormat::createNumberInstance", loc);
918 tempString = formatter->format (-5789.9876, tempString);
919
920 if (tempString == expectedDefault) {
921 logln ("Bug 4070798 default test passed.");
922 } else {
923 errln(UnicodeString("Failed:") +
924 " Expected " + expectedDefault +
925 " Received " + tempString );
926 }
927 delete formatter;
928 len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
929 formatter = NumberFormat::createCurrencyInstance(loc, status);
930 failure(status, "NumberFormat::createCurrencyInstance", loc);
931 tempString.remove();
932 tempString = formatter->format( 5789.9876, tempString );
933
934 if (tempString == expectedCurrency) {
935 logln ("Bug 4070798 currency test passed.");
936 } else {
937 errln(UnicodeString("Failed:") +
938 " Expected " + expectedCurrency +
939 " Received " + tempString );
940 }
941 delete formatter;
942
943 uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
944 formatter = NumberFormat::createPercentInstance(Locale(loc), status);
945 failure(status, "NumberFormat::createPercentInstance", loc);
946 tempString.remove();
947 tempString = formatter->format (-5789.9876, tempString);
948
949 if (tempString == expectedPercent) {
950 logln ("Bug 4070798 percentage test passed.");
951 } else {
952 errln(UnicodeString("Failed:") +
953 " Expected " + expectedPercent +
954 " Received " + tempString );
955 }
956
957 delete formatter;
958 }
959 /* @bug 4071005
960 * Data rounding errors for French (Canada) locale
961 */
962 void NumberFormatRegressionTest::Test4071005 (void)
963 {
964 NumberFormat *formatter;
965 UnicodeString tempString;
966 /* User error :
967 String expectedDefault = "-5\u00a0789,987";
968 String expectedCurrency = "5\u00a0789,98\u00a0$";
969 String expectedPercent = "-578\u00a0998%";
970 */
971 UChar chars1 [] = {
972 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38
973 };
974 UChar chars2 [] = {
975 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x24
976 };
977 UChar chars3 [] = {
978 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25
979 };
980 UnicodeString expectedDefault(chars1, 10, 10);
981 UnicodeString expectedCurrency(chars2, 10, 10);
982 UnicodeString expectedPercent(chars3, 10, 10);
983
984 UErrorCode status = U_ZERO_ERROR;
985 formatter = NumberFormat::createInstance(Locale::getCanadaFrench(), status);
986 if (failure(status, "NumberFormat::createNumberInstance", Locale::getCanadaFrench(), TRUE)){
987 delete formatter;
988 return;
989 };
990 tempString = formatter->format (-5789.9876, tempString);
991
992 if (tempString == expectedDefault) {
993 logln ("Bug 4071005 default test passed.");
994 } else {
995 errln(UnicodeString("Failed:") +
996 " Expected " + expectedDefault +
997 " Received " + tempString );
998 }
999 delete formatter;
1000
1001 formatter = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status);
1002 failure(status, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench());
1003 tempString.remove();
1004 tempString = formatter->format( 5789.9876, tempString );
1005
1006 if (tempString == expectedCurrency) {
1007 logln ("Bug 4071005 currency test assed.");
1008 } else {
1009 errln(UnicodeString("Failed:") +
1010 " Expected " + expectedCurrency +
1011 " Received " + tempString );
1012 }
1013 delete formatter;
1014
1015 formatter = NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status);
1016 failure(status, "NumberFormat::createPercentInstance", Locale::getCanadaFrench());
1017 tempString.remove();
1018 tempString = formatter->format (-5789.9876, tempString);
1019
1020 if (tempString == expectedPercent) {
1021 logln ("Bug 4071005 percentage test passed.");
1022 } else {
1023 errln(UnicodeString("Failed:") +
1024 " Expected " + expectedPercent +
1025 " Received " + tempString );
1026 }
1027
1028 delete formatter;
1029 }
1030
1031 /* @bug 4071014
1032 * Data rounding errors for German (Germany) locale
1033 */
1034 void NumberFormatRegressionTest::Test4071014 (void)
1035 {
1036 NumberFormat *formatter;
1037 UnicodeString tempString;
1038 /* user error :
1039 String expectedDefault = "-5.789,987";
1040 String expectedCurrency = "5.789,98 DM";
1041 String expectedPercent = "-578.998%";
1042 */
1043 UnicodeString expectedDefault("-5.789,988");
1044 UnicodeString expectedCurrency("5.789,99\\u00A0DM");
1045 UnicodeString expectedPercent("-578.999\\u00A0%");
1046
1047 expectedCurrency = expectedCurrency.unescape();
1048 expectedPercent = expectedPercent.unescape();
1049
1050 UErrorCode status = U_ZERO_ERROR;
1051 char loc[256]={0};
1052 uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
1053 formatter = NumberFormat::createInstance(Locale(loc), status);
1054 if (failure(status, "NumberFormat::createNumberInstance", loc, TRUE)){
1055 delete formatter;
1056 return;
1057 }
1058 tempString.remove();
1059 tempString = formatter->format (-5789.9876, tempString);
1060
1061 if (tempString == expectedDefault) {
1062 logln ("Bug 4071014 default test passed.");
1063 } else {
1064 errln(UnicodeString("Failed:") +
1065 " Expected " + expectedDefault +
1066 " Received " + tempString );
1067 }
1068 delete formatter;
1069 uloc_canonicalize("de_DE_PREEURO", loc, 256, &status);
1070 formatter = NumberFormat::createCurrencyInstance(Locale(loc), status);
1071 failure(status, "NumberFormat::createCurrencyInstance", loc);
1072 tempString.remove();
1073 tempString = formatter->format( 5789.9876, tempString );
1074
1075 if (tempString == expectedCurrency) {
1076 logln ("Bug 4071014 currency test assed.");
1077 } else {
1078 errln(UnicodeString("Failed:") +
1079 " Expected " + expectedCurrency +
1080 " Received " + tempString );
1081 }
1082 delete formatter;
1083
1084 formatter = NumberFormat::createPercentInstance(Locale::getGermany(), status);
1085 failure(status, "NumberFormat::createPercentInstance", Locale::getGermany());
1086 tempString.remove();
1087 tempString = formatter->format (-5789.9876, tempString);
1088
1089 if (tempString == expectedPercent) {
1090 logln ("Bug 4071014 percentage test passed.");
1091 } else {
1092 errln(UnicodeString("Failed:") +
1093 " Expected " + expectedPercent +
1094 " Received " + tempString );
1095 }
1096
1097 delete formatter;
1098 }
1099 /* @bug 4071859
1100 * Data rounding errors for Italian locale number formats
1101 */
1102 void NumberFormatRegressionTest::Test4071859 (void)
1103 {
1104 NumberFormat *formatter;
1105 UnicodeString tempString;
1106 /* user error :
1107 String expectedDefault = "-5.789,987";
1108 String expectedCurrency = "-L.\\u00A05.789,98";
1109 String expectedPercent = "-578.998%";
1110 */
1111 UnicodeString expectedDefault("-5.789,988");
1112 UnicodeString expectedCurrency("-ITL\\u00A05.790", -1, US_INV);
1113 UnicodeString expectedPercent("-578.999%");
1114 expectedCurrency = expectedCurrency.unescape();
1115
1116 UErrorCode status = U_ZERO_ERROR;
1117 char loc[256]={0};
1118 uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
1119 formatter = NumberFormat::createInstance(Locale(loc), status);
1120 if (failure(status, "NumberFormat::createNumberInstance", TRUE)){
1121 delete formatter;
1122 return;
1123 };
1124 tempString = formatter->format (-5789.9876, tempString);
1125
1126 if (tempString == expectedDefault) {
1127 logln ("Bug 4071859 default test passed.");
1128 } else {
1129 errln(UnicodeString("Failed:") +
1130 " Expected " + expectedDefault +
1131 " Received " + tempString );
1132 }
1133 delete formatter;
1134 uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
1135 formatter = NumberFormat::createCurrencyInstance(Locale(loc), status);
1136 failure(status, "NumberFormat::createCurrencyInstance");
1137 tempString.remove();
1138 tempString = formatter->format( -5789.9876, tempString );
1139
1140 if (tempString == expectedCurrency) {
1141 logln ("Bug 4071859 currency test assed.");
1142 } else {
1143 errln(UnicodeString("Failed:") +
1144 " Expected " + expectedCurrency +
1145 " Received " + tempString );
1146 }
1147 delete formatter;
1148 uloc_canonicalize("it_IT_PREEURO", loc, 256, &status);
1149 formatter = NumberFormat::createPercentInstance(Locale(loc), status);
1150 failure(status, "NumberFormat::createPercentInstance");
1151 tempString.remove();
1152 tempString = formatter->format (-5789.9876, tempString);
1153
1154 if (tempString == expectedPercent) {
1155 logln ("Bug 4071859 percentage test passed.");
1156 } else {
1157 errln(UnicodeString("Failed:") +
1158 " Expected " + expectedPercent +
1159 " Received " + tempString );
1160 }
1161
1162 delete formatter;
1163 }
1164 /* @bug 4071859
1165 * Test rounding for nearest even.
1166 */
1167 void NumberFormatRegressionTest::Test4093610(void)
1168 {
1169 UErrorCode status = U_ZERO_ERROR;
1170 DecimalFormat *df = new DecimalFormat("#0.#", status);
1171 if (!failure(status, "new DecimalFormat")) {
1172 UnicodeString s("12.4");
1173 roundingTest(df, 12.35, s);
1174 roundingTest(df, 12.45, s);
1175 s = "12.5";
1176 roundingTest(df, 12.452,s);
1177 s = "12.6";
1178 roundingTest(df, 12.55, s);
1179 roundingTest(df, 12.65, s);
1180 s = "12.7";
1181 roundingTest(df, 12.652,s);
1182 s = "12.8";
1183 roundingTest(df, 12.75, s);
1184 roundingTest(df, 12.752,s);
1185 roundingTest(df, 12.85, s);
1186 s = "12.9";
1187 roundingTest(df, 12.852,s);
1188 s = "13";
1189 roundingTest(df, 12.95, s);
1190 roundingTest(df, 12.952,s);
1191 }
1192
1193 delete df;
1194 }
1195
1196 void NumberFormatRegressionTest::roundingTest(DecimalFormat *df, double x, UnicodeString& expected)
1197 {
1198 UnicodeString out;
1199 FieldPosition pos(FieldPosition::DONT_CARE);
1200 out = df->format(x, out, pos);
1201 logln(UnicodeString("") + x + " formats with 1 fractional digits to " + out);
1202 if (out != expected)
1203 errln("FAIL: Expected " + expected);
1204 }
1205 /* @bug 4098741
1206 * Tests the setMaximumFractionDigits limit.
1207 */
1208 void NumberFormatRegressionTest::Test4098741(void)
1209 {
1210 //try {
1211 UErrorCode status = U_ZERO_ERROR;
1212 NumberFormat *fmt = NumberFormat::createPercentInstance(status);
1213 if (U_FAILURE(status)) {
1214 dataerrln("Error calling NumberFormat::createPercentInstance");
1215 delete fmt;
1216 return;
1217 }
1218
1219 fmt->setMaximumFractionDigits(20);
1220 UnicodeString temp;
1221 logln(fmt->format(.001, temp));
1222 /*} catch (Exception foo) {
1223 errln("Bug 4098471 failed with exception thrown : " + foo.getMessage());
1224 }*/
1225 delete fmt;
1226 }
1227 /* @bug 4074454
1228 * Tests illegal pattern exception.
1229 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated.
1230 * Part2 has been fixed.
1231 */
1232 void NumberFormatRegressionTest::Test4074454(void)
1233 {
1234 //try {
1235 UErrorCode status = U_ZERO_ERROR;
1236 DecimalFormat *fmt = new DecimalFormat("#,#00.00;-#.#", status);
1237 if(U_FAILURE(status)) {
1238 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1239 delete fmt;
1240 return;
1241 }
1242 failure(status, "new DecimalFormat");
1243 logln("Inconsistent negative pattern is fine.");
1244 DecimalFormat *newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status);
1245 failure(status, "new DecimalFormat");
1246 UnicodeString tempString;
1247 FieldPosition pos(FieldPosition::DONT_CARE);
1248 tempString = newFmt->format(3456.78, tempString, pos);
1249 if (tempString != UnicodeString("3,456.78 p'ieces"))
1250 dataerrln("Failed! 3456.78 p'ieces expected, but got : " + tempString);
1251 /*} catch (Exception foo) {
1252 errln("An exception was thrown for any inconsistent negative pattern.");
1253 }*/
1254
1255 delete fmt;
1256 delete newFmt;
1257 }
1258 /* @bug 4099404
1259 * Tests all different comments.
1260 * Response to some comments :
1261 * [1] DecimalFormat.parse API documentation is more than just one line.
1262 * This is not a reproducable doc error in 116 source code.
1263 * [2] See updated javadoc.
1264 * [3] Fixed.
1265 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails,
1266 * a null object will be returned. The unchanged parse position also
1267 * reflects an error.
1268 * NumberFormat.parse(String) : If parsing fails, an ParseException
1269 * will be thrown.
1270 * See updated javadoc for more details.
1271 * [5] See updated javadoc.
1272 * [6] See updated javadoc.
1273 * [7] This is a correct behavior if the DateFormat object is linient.
1274 * Otherwise, an IllegalArgumentException will be thrown when formatting
1275 * "January 35". See GregorianCalendar class javadoc for more details.
1276 */
1277 void NumberFormatRegressionTest::Test4099404(void)
1278 {
1279 //try {
1280 UErrorCode status = U_ZERO_ERROR;
1281 DecimalFormat *fmt = new DecimalFormat(UnicodeString("000.0#0"), status);
1282 if(! U_FAILURE(status))
1283 errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\""));
1284 /*} catch (Exception foo) {
1285 logln("Bug 4099404 pattern \"000.0#0\" passed");
1286 }*/
1287 delete fmt;
1288 fmt = 0;
1289 //try {
1290 fmt = new DecimalFormat(UnicodeString("0#0.000"), status);
1291 if( !U_FAILURE(status))
1292 errln("Bug 4099404 failed applying illegal pattern \"0#0.000\"");
1293 /*} catch (Exception foo) {
1294 logln("Bug 4099404 pattern \"0#0.000\" passed");
1295 }*/
1296
1297 delete fmt;
1298 }
1299 /* @bug 4101481
1300 * DecimalFormat.applyPattern doesn't set minimum integer digits
1301 */
1302 void NumberFormatRegressionTest::Test4101481(void)
1303 {
1304 UErrorCode status = U_ZERO_ERROR;
1305 DecimalFormat *sdf = new DecimalFormat(UnicodeString("#,##0"), status);
1306 if(U_FAILURE(status)) {
1307 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1308 delete sdf;
1309 return;
1310 }
1311 failure(status, "new DecimalFormat");
1312 if (sdf->getMinimumIntegerDigits() != 1)
1313 errln(UnicodeString("Minimum integer digits : ") + sdf->getMinimumIntegerDigits());
1314 delete sdf;
1315 }
1316 /* @bug 4052223 (API addition request A27)
1317 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition().
1318 */
1319 void NumberFormatRegressionTest::Test4052223(void)
1320 {
1321 //try {
1322 UErrorCode status = U_ZERO_ERROR;
1323 DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,#00.00"), status);
1324 if(U_FAILURE(status)) {
1325 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1326 delete fmt;
1327 return;
1328 }
1329 failure(status, "new DecimalFormat");
1330 Formattable num;
1331 fmt->parse(UnicodeString("abc3"), num, status);
1332 if(! U_FAILURE(status))
1333 errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\". Got ") /*+ num*/);
1334 /*} catch (ParseException foo) {
1335 logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset());
1336 }*/
1337 delete fmt;
1338 }
1339 /* @bug 4061302
1340 * API tests for API addition request A9.
1341 */
1342 void NumberFormatRegressionTest::Test4061302(void)
1343 {
1344 UErrorCode status = U_ZERO_ERROR;
1345 DecimalFormatSymbols *fmt = new DecimalFormatSymbols(status);
1346 failure(status, "new DecimalFormatSymbols");
1347 UnicodeString currency(fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol));
1348 UnicodeString intlCurrency(fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
1349 UnicodeString monDecSeparator(fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
1350 if (currency == UnicodeString("") ||
1351 intlCurrency == UnicodeString("") ||
1352 monDecSeparator == UnicodeString(""))
1353 {
1354 errln("getCurrencySymbols failed, got empty string.");
1355 }
1356 UnicodeString monDecSeparatorStr;
1357 monDecSeparatorStr.append(monDecSeparator);
1358 logln((UnicodeString)"Before set ==> Currency : " + currency +(UnicodeString)" Intl Currency : " + intlCurrency + (UnicodeString)" Monetary Decimal Separator : " + monDecSeparatorStr);
1359 fmt->setSymbol(DecimalFormatSymbols::kCurrencySymbol, UnicodeString("XYZ"));
1360 fmt->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, UnicodeString("ABC"));
1361 fmt->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, UnicodeString((UChar)0x002A/*'*'*/));
1362 currency = fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol);
1363 intlCurrency = fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
1364 monDecSeparator = fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
1365 if (currency != UnicodeString("XYZ") ||
1366 intlCurrency != UnicodeString("ABC") ||
1367 monDecSeparator != UnicodeString((UChar)0x002A/*'*'*/)) {
1368 errln("setCurrencySymbols failed.");
1369 }
1370 monDecSeparatorStr.remove();
1371 monDecSeparatorStr.append(monDecSeparator);
1372 logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparatorStr);
1373
1374 delete fmt;
1375 }
1376 /* @bug 4062486
1377 * API tests for API addition request A23. FieldPosition.getBeginIndex and
1378 * FieldPosition.getEndIndex.
1379 */
1380 void NumberFormatRegressionTest::Test4062486(void)
1381 {
1382 UErrorCode status = U_ZERO_ERROR;
1383 DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,##0.00"), status);
1384 failure(status, "new DecimalFormat");
1385 UnicodeString formatted;
1386 FieldPosition field(0);
1387 double num = 1234.5;
1388 fmt->format(num, formatted, field);
1389 if (field.getBeginIndex() != 0 && field.getEndIndex() != 5)
1390 errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1391 field.setBeginIndex(7);
1392 field.setEndIndex(4);
1393 if (field.getBeginIndex() != 7 && field.getEndIndex() != 4)
1394 errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/);
1395
1396 delete fmt;
1397 }
1398
1399 /* @bug 4108738
1400 * DecimalFormat.parse incorrectly works with a group separator.
1401 */
1402 void NumberFormatRegressionTest::Test4108738(void)
1403 {
1404 UErrorCode status = U_ZERO_ERROR;
1405 DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getUS(), status);
1406 failure(status, "new DecimalFormatSymbols");
1407 DecimalFormat *df = new DecimalFormat("#,##0.###", syms, status);
1408 if(U_FAILURE(status)) {
1409 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1410 delete df;
1411 return;
1412 }
1413 failure(status, "new DecimalFormat");
1414 UnicodeString text("1.222,111");
1415 Formattable num;
1416 ParsePosition pp(0);
1417 df->parse(text, num, pp);
1418
1419 // {sfb} how to do this (again) ?
1420 // shouldn't just be another round-trip test, should it?
1421 UnicodeString temp;
1422 FieldPosition pos(FieldPosition::DONT_CARE);
1423 temp = df->format(num.getDouble(), temp, pos);
1424 //if (!num.toString().equals("1.222"))
1425 if (temp != UnicodeString("1.222"))
1426 //errln("\"" + text + "\" is parsed as " + num);
1427 errln("\"" + text + "\" is parsed as " + temp);
1428 text = UnicodeString("1.222x111");
1429 pp = ParsePosition(0);
1430 df->parse(text, num, pp);
1431 temp.remove();
1432 temp = df->format(num.getDouble(), temp, pos);
1433 //if (!num.toString().equals("1.222"))
1434 if (temp != UnicodeString("1.222"))
1435 errln("\"" + text + "\" is parsed as " + temp);
1436
1437 delete df;
1438 }
1439
1440 /* @bug 4106658
1441 * DecimalFormat.format() incorrectly formats negative doubles.
1442 */
1443 void NumberFormatRegressionTest::Test4106658(void)
1444 {
1445 UErrorCode status = U_ZERO_ERROR;
1446 DecimalFormat *df = new DecimalFormat(status); // Corrected; see 4147706
1447 if(U_FAILURE(status)) {
1448 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1449 delete df;
1450 return;
1451 }
1452 failure(status, "new DecimalFormat");
1453 volatile double d1 = 0.0; // volatile to prevent code optimization
1454 double d2 = -0.0001;
1455 UnicodeString buffer;
1456 UnicodeString temp;
1457 FieldPosition pos(FieldPosition::DONT_CARE);
1458
1459 #if U_PLATFORM == U_PF_HPUX
1460 d1 = 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1461 #else
1462 d1 *= -1.0; // Some compilers have a problem with defining -0.0
1463 #endif
1464 logln("pattern: \"" + df->toPattern(temp) + "\"");
1465 df->format(d1, buffer, pos);
1466 if (buffer != UnicodeString("-0")) // Corrected; see 4147706
1467 errln(UnicodeString("") + d1 + " is formatted as " + buffer);
1468 buffer.remove();
1469 df->format(d2, buffer, pos);
1470 if (buffer != UnicodeString("-0")) // Corrected; see 4147706
1471 errln(UnicodeString("") + d2 + " is formatted as " + buffer);
1472
1473 delete df;
1474 }
1475
1476 /* @bug 4106662
1477 * DecimalFormat.parse returns 0 if string parameter is incorrect.
1478 */
1479 void NumberFormatRegressionTest::Test4106662(void)
1480 {
1481 UErrorCode status = U_ZERO_ERROR;
1482 DecimalFormat *df = new DecimalFormat(status);
1483 if(U_FAILURE(status)) {
1484 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1485 delete df;
1486 return;
1487 }
1488 failure(status, "new DecimalFormat");
1489 UnicodeString text("x");
1490 ParsePosition pos1(0), pos2(0);
1491
1492 UnicodeString temp;
1493 logln("pattern: \"" + df->toPattern(temp) + "\"");
1494 Formattable num;
1495 df->parse(text, num, pos1);
1496 if (pos1 == ParsePosition(0)/*num != null*/) {
1497 errln(UnicodeString("Test Failed: \"") + text + "\" is parsed as " /*+ num*/);
1498 }
1499 delete df;
1500 df = new DecimalFormat(UnicodeString("$###.00"), status);
1501 failure(status, "new DecimalFormat");
1502 df->parse(UnicodeString("$"), num, pos2);
1503 if (pos2 == ParsePosition(0) /*num != null*/){
1504 errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/);
1505 }
1506
1507 delete df;
1508 }
1509
1510 /* @bug 4114639 (duplicate of 4106662)
1511 * NumberFormat.parse doesn't return null
1512 */
1513 void NumberFormatRegressionTest::Test4114639(void)
1514 {
1515 UErrorCode status = U_ZERO_ERROR;
1516 NumberFormat *format = NumberFormat::createInstance(status);
1517 if(U_FAILURE(status)) {
1518 dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
1519 delete format;
1520 return;
1521 }
1522 failure(status, "NumberFormat::createInstance");
1523 UnicodeString text("time 10:x");
1524 ParsePosition pos(8);
1525 Formattable result;
1526 format->parse(text, result, pos);
1527 if (/*result != null*/pos.getErrorIndex() != 8)
1528 errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't
1529
1530 delete format;
1531 }
1532
1533 /* @bug 4106664
1534 * TODO: this test does not work because we need to use a 64 bit number and a
1535 * a double only MAY only have 52 bits of precision.
1536 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG.
1537 */
1538 void NumberFormatRegressionTest::Test4106664(void)
1539 {
1540 UErrorCode status = U_ZERO_ERROR;
1541 DecimalFormat *df = new DecimalFormat(status);
1542 if(U_FAILURE(status)) {
1543 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1544 delete df;
1545 return;
1546 }
1547 failure(status, "new DecimalFormat");
1548 // {sfb} long in java is 64 bits
1549 /*long*/double n = 1234567890123456.0;
1550 /*int*/int32_t m = 12345678;
1551 // {sfb} will this work?
1552 //BigInteger bigN = BigInteger.valueOf(n);
1553 //bigN = bigN.multiply(BigInteger.valueOf(m));
1554 double bigN = n * m;
1555 df->setMultiplier(m);
1556 df->setGroupingUsed(FALSE);
1557 UnicodeString temp;
1558 FieldPosition pos(FieldPosition::DONT_CARE);
1559 logln("formated: " +
1560 df->format(n, temp, pos));
1561
1562 char buf [128];
1563 sprintf(buf, "%g", bigN);
1564 //logln("expected: " + bigN.toString());
1565 logln(UnicodeString("expected: ") + buf);
1566
1567 delete df;
1568 }
1569 /* @bug 4106667 (duplicate of 4106658)
1570 * DecimalFormat.format incorrectly formats -0.0.
1571 */
1572 void NumberFormatRegressionTest::Test4106667(void)
1573 {
1574 UErrorCode status = U_ZERO_ERROR;
1575 DecimalFormat *df = new DecimalFormat(status);
1576 if(U_FAILURE(status)) {
1577 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1578 delete df;
1579 return;
1580 }
1581 failure(status, "new DecimalFormat");
1582 UChar foo [] = { 0x002B };
1583 UnicodeString bar(foo, 1, 1);
1584 volatile double d = 0.0; // volatile to prevent code optimization
1585 UnicodeString temp;
1586 UnicodeString buffer;
1587 FieldPosition pos(FieldPosition::DONT_CARE);
1588
1589 logln("pattern: \"" + df->toPattern(temp) + "\"");
1590 #if U_PLATFORM == U_PF_HPUX
1591 d = 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
1592 #else
1593 d *= -1.0; // Some compilers have a problem with defining -0.0
1594 #endif
1595 df->setPositivePrefix(/*"+"*/bar);
1596 df->format(d, buffer, pos);
1597 if (buffer != UnicodeString("-0")) // Corrected; see 4147706
1598 errln(/*d + */UnicodeString(" is formatted as ") + buffer);
1599
1600 delete df;
1601 }
1602
1603 /* @bug 4110936
1604 * DecimalFormat.setMaximumIntegerDigits() works incorrectly.
1605 */
1606 #if U_PLATFORM == U_PF_OS390
1607 # define MAX_INT_DIGITS 70
1608 #else
1609 # define MAX_INT_DIGITS 128
1610 #endif
1611
1612 void NumberFormatRegressionTest::Test4110936(void)
1613 {
1614 UErrorCode status = U_ZERO_ERROR;
1615 NumberFormat *nf = NumberFormat::createInstance(status);
1616 if(U_FAILURE(status)) {
1617 dataerrln("Error creating DecimalFormat: %s", u_errorName(status));
1618 delete nf;
1619 return;
1620 }
1621 failure(status, "NumberFormat::createInstance");
1622 nf->setMaximumIntegerDigits(MAX_INT_DIGITS);
1623 logln("setMaximumIntegerDigits(MAX_INT_DIGITS)");
1624 if (nf->getMaximumIntegerDigits() != MAX_INT_DIGITS)
1625 errln(UnicodeString("getMaximumIntegerDigits() returns ") +
1626 nf->getMaximumIntegerDigits());
1627
1628 delete nf;
1629 }
1630
1631 /* @bug 4122840
1632 * Locale data should use generic currency symbol
1633 *
1634 * 1) Make sure that all currency formats use the generic currency symbol.
1635 * 2) Make sure we get the same results using the generic symbol or a
1636 * hard-coded one.
1637 */
1638 void NumberFormatRegressionTest::Test4122840(void)
1639 {
1640 int32_t count = 0;
1641 const Locale *locales = Locale::getAvailableLocales(count);
1642
1643 for (int i = 0; i < count; i++) {
1644 UErrorCode status = U_ZERO_ERROR;
1645 ResourceBundle *rb = new ResourceBundle(
1646 NULL/*"java.text.resources.LocaleElements"*/,
1647 locales[i], status);
1648 failure(status, "new ResourceBundle");
1649 ResourceBundle numPat = rb->getWithFallback("NumberElements", status);
1650 failure(status, "rb.get(NumberElements)");
1651 numPat = numPat.getWithFallback("latn",status);
1652 failure(status, "rb.get(latn)");
1653 numPat = numPat.getWithFallback("patterns",status);
1654 failure(status, "rb.get(patterns)");
1655 numPat = numPat.getWithFallback("currencyFormat",status);
1656 failure(status, "rb.get(currencyFormat)");
1657 //
1658 // Get the currency pattern for this locale. We have to fish it
1659 // out of the ResourceBundle directly, since DecimalFormat.toPattern
1660 // will return the localized symbol, not \00a4
1661 //
1662 UnicodeString pattern = numPat.getString(status);
1663 failure(status, "rb->getString()");
1664
1665 UChar fo[] = { 0x00A4 };
1666 UnicodeString foo(fo, 1, 1);
1667
1668 //if (pattern.indexOf("\u00A4") == -1 ) {
1669 if (pattern.indexOf(foo) == -1 ) {
1670 errln(UnicodeString("Currency format for ") + UnicodeString(locales[i].getName()) +
1671 " does not contain generic currency symbol:" +
1672 pattern );
1673 }
1674
1675 // Create a DecimalFormat using the pattern we got and format a number
1676 DecimalFormatSymbols *symbols = new DecimalFormatSymbols(locales[i], status);
1677 failure(status, "new DecimalFormatSymbols");
1678 DecimalFormat *fmt1 = new DecimalFormat(pattern, *symbols, status);
1679 failure(status, "new DecimalFormat");
1680
1681 UnicodeString result1;
1682 FieldPosition pos(FieldPosition::DONT_CARE);
1683 result1 = fmt1->format(1.111, result1, pos);
1684
1685 //
1686 // Now substitute in the locale's currency symbol and create another
1687 // pattern. We have to skip locales where the currency symbol
1688 // contains decimal separators, because that confuses things
1689 //
1690 UChar ba[] = { 0x002E/*'.'*/ };
1691 UnicodeString bar(ba, 1, 1);
1692
1693 if (symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).indexOf(bar) == -1) {
1694 // {sfb} Also, switch the decimal separator to the monetary decimal
1695 // separator to mimic the behavior of a currency format
1696 symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol,
1697 symbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol));
1698
1699 UnicodeString buf(pattern);
1700 for (int j = 0; j < buf.length(); j++) {
1701 if (buf[j] == 0x00a4 ) {
1702 if(buf[j + 1] == 0x00a4) {
1703 // {sfb} added to support double currency marker (intl currency sign)
1704 buf.replace(j, /*j+*/2, symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
1705 j += symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol).length();
1706 }
1707 else {
1708 buf.replace(j, /*j+*/1, symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol));
1709 j += symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).length() - 1;
1710 }
1711 }
1712 }
1713
1714 DecimalFormat *fmt2 = new DecimalFormat(buf, *symbols, status);
1715 failure(status, "new DecimalFormat");
1716
1717 // Get the currency (if there is one) so we can set the rounding and fraction
1718 const UChar *currency = fmt1->getCurrency();
1719 if (*currency != 0) {
1720 double rounding = ucurr_getRoundingIncrement(currency, &status);
1721 int32_t frac = ucurr_getDefaultFractionDigits(currency, &status);
1722 if (U_SUCCESS(status)) {
1723 fmt2->setRoundingIncrement(rounding);
1724 fmt2->setMinimumFractionDigits(frac);
1725 fmt2->setMaximumFractionDigits(frac);
1726 }
1727 else {
1728 failure(status, "Fetching currency rounding/fractions");
1729 }
1730 }
1731
1732 UnicodeString result2;
1733 fmt2->format(1.111, result2, pos);
1734
1735 if (result1 != result2) {
1736 errln("Results for " + (UnicodeString)(locales[i].getName()) + " differ: " +
1737 result1 + " vs " + result2);
1738 }
1739
1740 delete fmt2;
1741 }
1742
1743 delete rb;
1744 delete fmt1;
1745 delete symbols;
1746 }
1747 }
1748
1749 /* @bug 4125885
1750 * DecimalFormat.format() delivers wrong string.
1751 */
1752 void NumberFormatRegressionTest::Test4125885(void)
1753 {
1754 UErrorCode status = U_ZERO_ERROR;
1755 double rate = 12.34;
1756 DecimalFormat *formatDec = new DecimalFormat ("000.00", status);
1757 if(U_FAILURE(status)) {
1758 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status));
1759 delete formatDec;
1760 return;
1761 }
1762 failure(status, "new DecimalFormat");
1763 UnicodeString temp;
1764 logln("toPattern: " + formatDec->toPattern(temp));
1765 UnicodeString rateString;
1766 FieldPosition pos(FieldPosition::DONT_CARE);
1767 rateString = formatDec->format(rate, rateString, pos);
1768 if (rateString != UnicodeString("012.34"))
1769 errln("result : " + rateString + " expected : 012.34");
1770 rate = 0.1234;
1771 delete formatDec;// = null;
1772 formatDec = new DecimalFormat ("+000.00%;-000.00%", status);
1773 failure(status, "new DecimalFormat");
1774 logln("toPattern: " + formatDec->toPattern(temp));
1775 rateString.remove();
1776 rateString = formatDec->format(rate, rateString, pos);
1777 if (rateString != UnicodeString("+012.34%"))
1778 errln("result : " + rateString + " expected : +012.34%");
1779
1780 delete formatDec;
1781 }
1782
1783 /**
1784 * @bug 4134034
1785 * DecimalFormat produces extra zeros when formatting numbers.
1786 */
1787 void NumberFormatRegressionTest::Test4134034(void)
1788 {
1789 UErrorCode status = U_ZERO_ERROR;
1790 DecimalFormat *nf = new DecimalFormat("##,###,###.00", status);
1791 if (!failure(status, "new DecimalFormat")) {
1792 UnicodeString f;
1793 FieldPosition pos(FieldPosition::DONT_CARE);
1794 f = nf->format(9.02, f, pos);
1795 if (f == UnicodeString("9.02"))
1796 logln(f + " ok");
1797 else
1798 errln("9.02 -> " + f + "; want 9.02");
1799
1800 f.remove();
1801 f = nf->format((int32_t)0, f, pos);
1802 if (f == UnicodeString(".00"))
1803 logln(f + " ok");
1804 else
1805 errln("0 -> " + f + "; want .00");
1806 }
1807
1808 delete nf;
1809 }
1810
1811 /**
1812 * @bug 4134300
1813 * CANNOT REPRODUCE - This bug could not be reproduced. It may be
1814 * a duplicate of 4134034.
1815 *
1816 * JDK 1.1.6 Bug, did NOT occur in 1.1.5
1817 * Possibly related to bug 4125885.
1818 *
1819 * This class demonstrates a regression in version 1.1.6
1820 * of DecimalFormat class.
1821 *
1822 * 1.1.6 Results
1823 * Value 1.2 Format #.00 Result '01.20' !!!wrong
1824 * Value 1.2 Format 0.00 Result '001.20' !!!wrong
1825 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong
1826 * Value 1.2 Format #0.0# Result '1.2'
1827 * Value 1.2 Format #0.00 Result '001.20' !!!wrong
1828 *
1829 * 1.1.5 Results
1830 * Value 1.2 Format #.00 Result '1.20'
1831 * Value 1.2 Format 0.00 Result '1.20'
1832 * Value 1.2 Format 00.00 Result '01.20'
1833 * Value 1.2 Format #0.0# Result '1.2'
1834 * Value 1.2 Format #0.00 Result '1.20'
1835 */
1836 void NumberFormatRegressionTest::Test4134300(void) {
1837 UnicodeString DATA [] = {
1838 // Pattern Expected string
1839 UnicodeString("#.00"), UnicodeString("1.20"),
1840 UnicodeString("0.00"), UnicodeString("1.20"),
1841 UnicodeString("00.00"), UnicodeString("01.20"),
1842 UnicodeString("#0.0#"), UnicodeString("1.2"),
1843 UnicodeString("#0.00"), UnicodeString("1.20")
1844 };
1845
1846 for (int i=0; i< 10; i+=2) {
1847 UnicodeString result;
1848 UErrorCode status = U_ZERO_ERROR;
1849 DecimalFormat *df = new DecimalFormat(DATA[i], status);
1850 if (!failure(status, "new DecimalFormat")) {
1851 FieldPosition pos(FieldPosition::DONT_CARE);
1852 result = df->format(1.2, result, pos);
1853 if (result != DATA[i+1]) {
1854 errln("Fail: 1.2 x " + DATA[i] + " = " + result +
1855 "; want " + DATA[i+1]);
1856 }
1857 else {
1858 logln("Ok: 1.2 x " + DATA[i] + " = " + result);
1859 }
1860 }
1861
1862 delete df;
1863 }
1864 }
1865
1866 /**
1867 * @bug 4140009
1868 * Empty pattern produces double negative prefix.
1869 */
1870 void NumberFormatRegressionTest::Test4140009(void)
1871 {
1872 UErrorCode status = U_ZERO_ERROR;
1873 DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status);
1874 failure(status, "new DecimalFormatSymbols");
1875 DecimalFormat *f = new DecimalFormat(UnicodeString(""), syms, status);
1876 if (!failure(status, "new DecimalFormat")) {
1877 UnicodeString s;
1878 FieldPosition pos(FieldPosition::DONT_CARE);
1879 s = f->format(123.456, s, pos);
1880 if (s != UnicodeString("123.456"))
1881 errln("Fail: Format empty pattern x 123.456 => " + s);
1882 s.remove();
1883 s = f->format(-123.456, s, pos);
1884 if (s != UnicodeString("-123.456"))
1885 errln("Fail: Format empty pattern x -123.456 => " + s);
1886 }
1887 delete f;
1888 }
1889
1890 /**
1891 * @bug 4141750
1892 * BigDecimal numbers get their fractions truncated by NumberFormat.
1893 */
1894 // {sfb} not pertinent in C++ ??
1895 void NumberFormatRegressionTest::Test4141750(void) {
1896 /*try {
1897 UnicodeString str("12345.67");
1898 BigDecimal bd = new BigDecimal(str);
1899 String sd = NumberFormat.getInstance(Locale.US).format(bd);
1900 if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd);
1901 }
1902 catch (Exception e) {
1903 errln(e.toString());
1904 e.printStackTrace();
1905 }*/
1906 }
1907
1908 /**
1909 * @bug 4145457
1910 * DecimalFormat toPattern() doesn't quote special characters or handle
1911 * single quotes.
1912 */
1913 void NumberFormatRegressionTest::Test4145457() {
1914 //try {
1915 UErrorCode status = U_ZERO_ERROR;
1916 NumberFormat *nff = NumberFormat::createInstance(status);
1917 if (failure(status, "NumberFormat::createInstance", TRUE)){
1918 delete nff;
1919 return;
1920 };
1921 DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nff);
1922 if(nf == NULL) {
1923 errln("DecimalFormat needed to continue");
1924 return;
1925 }
1926
1927 DecimalFormatSymbols *sym = (DecimalFormatSymbols*) nf->getDecimalFormatSymbols();
1928 sym->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, (UChar)/*'\''*/0x0027);
1929 nf->setDecimalFormatSymbols(*sym);
1930 double pi = 3.14159;
1931
1932 UnicodeString PATS [] = {
1933 UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''")
1934 };
1935
1936 for (int32_t i=0; i<2; ++i) {
1937 nf->applyPattern(PATS[i], status);
1938 failure(status, "nf->applyPattern");
1939 UnicodeString out;
1940 FieldPosition pos(FieldPosition::DONT_CARE);
1941 out = nf->format(pi, out, pos);
1942 UnicodeString pat;
1943 pat = nf->toPattern(pat);
1944 Formattable num;
1945 ParsePosition pp(0);
1946 nf->parse(out, num, pp);
1947 double val = num.getDouble();
1948
1949 nf->applyPattern(pat, status);
1950 failure(status, "nf->applyPattern");
1951 UnicodeString out2;
1952 out2 = nf->format(pi, out2, pos);
1953 UnicodeString pat2;
1954 pat2 = nf->toPattern(pat2);
1955 pp.setIndex(0);
1956 nf->parse(out2, num, pp);
1957 double val2 = num.getDouble();
1958
1959 if (pat != pat2)
1960 errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" +
1961 pat + "\" vs. \"" + pat2 + "\"");
1962 else
1963 logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"');
1964
1965 if (val == val2 && out == out2) {
1966 logln(UnicodeString("Ok ") + pi + " x \"" + PATS[i] + "\" -> \"" +
1967 out + "\" -> " + val + " -> \"" +
1968 out2 + "\" -> " + val2);
1969 }
1970 else {
1971 errln(UnicodeString("Fail ") + pi + " x \"" + PATS[i] + "\" -> \"" +
1972 out + "\" -> " + val + " -> \"" +
1973 out2 + "\" -> " + val2);
1974 }
1975 }
1976 /*}
1977 catch (ParseException e) {
1978 errln("Fail: " + e);
1979 e.printStackTrace();
1980 }*/
1981
1982 delete nff;
1983 }
1984
1985 /**
1986 * @bug 4147295
1987 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly.
1988 * CANNOT REPRODUCE
1989 * This bug is a duplicate of 4139344, which is a duplicate of 4134300
1990 */
1991 void NumberFormatRegressionTest::Test4147295(void)
1992 {
1993 UErrorCode status = U_ZERO_ERROR;
1994 DecimalFormat *sdf = new DecimalFormat(status);
1995 UnicodeString pattern("#,###");
1996 logln("Applying pattern \"" + pattern + "\"");
1997 sdf->applyPattern(pattern, status);
1998 if (!failure(status, "sdf->applyPattern")) {
1999 int minIntDig = sdf->getMinimumIntegerDigits();
2000 if (minIntDig != 0) {
2001 errln("Test failed");
2002 errln(UnicodeString(" Minimum integer digits : ") + minIntDig);
2003 UnicodeString temp;
2004 errln(UnicodeString(" new pattern: ") + sdf->toPattern(temp));
2005 } else {
2006 logln("Test passed");
2007 logln(UnicodeString(" Minimum integer digits : ") + minIntDig);
2008 }
2009 }
2010 delete sdf;
2011 }
2012
2013 /**
2014 * @bug 4147706
2015 * DecimalFormat formats -0.0 as +0.0
2016 * See also older related bug 4106658, 4106667
2017 */
2018 void NumberFormatRegressionTest::Test4147706(void)
2019 {
2020 UErrorCode status = U_ZERO_ERROR;
2021 DecimalFormat *df = new DecimalFormat("#,##0.0##", status);
2022 failure(status, "new DecimalFormat");
2023 DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status);
2024 if (!failure(status, "new DecimalFormatSymbols")) {
2025 UnicodeString f1;
2026 UnicodeString f2, temp;
2027 FieldPosition pos(FieldPosition::DONT_CARE);
2028 volatile double d1 = 0.0; // volatile to prevent code optimization
2029 double d2 = -0.0001;
2030
2031 #if U_PLATFORM == U_PF_HPUX
2032 d1 = 0.0 * -1.0; // old HPUX compiler ignores volatile keyword
2033 #else
2034 d1 *= -1.0; // Some compilers have a problem with defining -0.0
2035 #endif
2036 df->adoptDecimalFormatSymbols(syms);
2037 f1 = df->format(d1, f1, pos);
2038 f2 = df->format(d2, f2, pos);
2039 if (f1 != UnicodeString("-0.0")) {
2040 errln(UnicodeString("") + d1 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f1 + '"');
2041 }
2042 if (f2 != UnicodeString("-0.0")) {
2043 errln(UnicodeString("") + d2 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f2 + '"');
2044 }
2045 }
2046
2047 delete df;
2048 }
2049
2050
2051 // Not applicable, since no serialization in C++
2052 /*class myformat implements Serializable
2053 {
2054 DateFormat _dateFormat = DateFormat.getDateInstance();
2055
2056 public String Now()
2057 {
2058 GregorianCalendar calendar = new GregorianCalendar();
2059 Date t = calendar.getTime();
2060 String nowStr = _dateFormat.format(t);
2061 return nowStr;
2062 }
2063 }*/
2064
2065 /**
2066 * @bug 4162198
2067 * NumberFormat cannot format Double.MAX_VALUE
2068 */
2069 // TODO: make this test actually test something
2070 void
2071 NumberFormatRegressionTest::Test4162198(void)
2072 {
2073 // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof)
2074 double dbl = INT32_MAX * 1000.0;
2075 UErrorCode status = U_ZERO_ERROR;
2076 NumberFormat *f = NumberFormat::createInstance(status);
2077 if(U_FAILURE(status)) {
2078 dataerrln("Couldn't create number format - %s", u_errorName(status));
2079 return;
2080 }
2081 f->setMaximumFractionDigits(INT32_MAX);
2082 f->setMaximumIntegerDigits(INT32_MAX);
2083 UnicodeString s;
2084 f->format(dbl,s);
2085 logln(UnicodeString("The number ") + dbl + " formatted to " + s);
2086 Formattable n;
2087 //try {
2088 f->parse(s, n, status);
2089 if(U_FAILURE(status))
2090 errln("Couldn't parse!");
2091 //} catch (java.text.ParseException e) {
2092 // errln("Caught a ParseException:");
2093 // e.printStackTrace();
2094 //}
2095
2096 //logln("The string " + s + " parsed as " + n);
2097
2098 // {dlf} The old code assumes n is a double, but it isn't any more...
2099 // Formattable apparently does not and never did interconvert... too bad.
2100 //if(n.getDouble() != dbl) {
2101 // errln("Round trip failure");
2102 //}
2103 if (n.getInt64() != dbl) {
2104 errln("Round trip failure");
2105 }
2106
2107 delete f;
2108 }
2109
2110 /**
2111 * @bug 4162852
2112 * NumberFormat does not parse negative zero.
2113 */
2114 void
2115 NumberFormatRegressionTest::Test4162852(void)
2116 {
2117 UErrorCode status = U_ZERO_ERROR;
2118 for(int32_t i=0; i < 2; ++i) {
2119 NumberFormat *f = (i == 0) ? NumberFormat::createInstance(status)
2120 : NumberFormat::createPercentInstance(status);
2121 if(U_FAILURE(status)) {
2122 dataerrln("Couldn't create number format - %s", u_errorName(status));
2123 return;
2124 }
2125 double d = 0.0;
2126 d *= -1.0;
2127 UnicodeString s;
2128 f->format(d, s);
2129 Formattable n;
2130 f->parse(s, n, status);
2131 if(U_FAILURE(status))
2132 errln("Couldn't parse!");
2133 double e = n.getDouble();
2134 logln(UnicodeString("") +
2135 d + " -> " +
2136 '"' + s + '"' + " -> " + e);
2137 #if (U_PLATFORM == U_PF_OS390 && !defined(IEEE_754)) || U_PLATFORM == U_PF_OS400
2138 if (e != 0.0) {
2139 #else
2140 if (e != 0.0 || 1.0/e > 0.0) {
2141 #endif
2142 logln("Failed to parse negative zero");
2143 }
2144 delete f;
2145 }
2146 }
2147
2148 static double _u_abs(double a) { return a<0?-a:a; }
2149
2150 /**
2151 * May 17 1999 sync up - liu
2152 * @bug 4167494
2153 * NumberFormat truncates data
2154 */
2155 void NumberFormatRegressionTest::Test4167494(void) {
2156 UErrorCode status = U_ZERO_ERROR;
2157 NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status);
2158 if (failure(status, "NumberFormat::createInstance", TRUE)){
2159 delete fmt;
2160 return;
2161 };
2162
2163 double a = DBL_MAX * 0.99; // DBL_MAX itself overflows to +Inf
2164 UnicodeString s;
2165 fmt->format(a, s);
2166 Formattable num;
2167 fmt->parse(s, num, status);
2168 failure(status, "Parse");
2169 if (num.getType() == Formattable::kDouble &&
2170 _u_abs(num.getDouble() - a) / a < 0.01) { // RT within 1%
2171 logln(UnicodeString("") + a + " -> \"" + s + "\" -> " +
2172 toString(num) + " ok");
2173 } else {
2174 errln(UnicodeString("") + a + " -> \"" + s + "\" -> " +
2175 toString(num) + " FAIL");
2176 }
2177
2178 // We don't test Double.MIN_VALUE because the locale data for the US
2179 // currently doesn't specify enough digits to display Double.MIN_VALUE.
2180 // This is correct for now; however, we leave this here as a reminder
2181 // in case we want to address this later.
2182
2183 delete fmt;
2184 }
2185
2186 /**
2187 * May 17 1999 sync up - liu
2188 * @bug 4170798
2189 * DecimalFormat.parse() fails when ParseIntegerOnly set to true
2190 */
2191 void NumberFormatRegressionTest::Test4170798(void) {
2192 UErrorCode status = U_ZERO_ERROR;
2193 NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
2194 if (failure(status, "NumberFormat::createInstance", TRUE)){
2195 delete nf;
2196 return;
2197 };
2198 DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
2199 if(df == NULL) {
2200 errln("DecimalFormat needed to continue");
2201 return;
2202 }
2203 df->setParseIntegerOnly(TRUE);
2204 Formattable n;
2205 ParsePosition pos(0);
2206 df->parse("-0.0", n, pos);
2207 if (n.getType() != Formattable::kLong
2208 || n.getLong() != 0) {
2209 errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n));
2210 }
2211 delete nf;
2212 }
2213
2214 /**
2215 * May 17 1999 sync up - liu
2216 * toPattern only puts the first grouping separator in.
2217 */
2218 void NumberFormatRegressionTest::Test4176114(void) {
2219 const char* DATA[] = {
2220 "00", "#00",
2221 "000", "#000", // No grouping
2222 "#000", "#000", // No grouping
2223 "#,##0", "#,##0",
2224 "#,000", "#,000",
2225 "0,000", "#0,000",
2226 "00,000", "#00,000",
2227 "000,000", "#,000,000",
2228 "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported
2229 };
2230 int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
2231 UErrorCode status = U_ZERO_ERROR;
2232 UnicodeString s;
2233 for (int i=0; i<DATA_length; i+=2) {
2234 DecimalFormat df(DATA[i], status);
2235 if (!failure(status, "DecimalFormat constructor")) {
2236 df.toPattern(s);
2237 UnicodeString exp(DATA[i+1]);
2238 if (s != exp) {
2239 errln(UnicodeString("FAIL: ") + DATA[i] + " -> " +
2240 s + ", want " + exp);
2241 }
2242 }
2243 }
2244 }
2245
2246 /**
2247 * May 17 1999 sync up - liu
2248 * @bug 4179818
2249 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2
2250 */
2251 void NumberFormatRegressionTest::Test4179818(void) {
2252 const char* DATA[] = {
2253 // Input Pattern Expected output
2254 "1.2511", "#.#", "1.3",
2255 "1.2501", "#.#", "1.3",
2256 "0.9999", "#", "1",
2257 };
2258 int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
2259 double DOUBLE[] = {
2260 1.2511,
2261 1.2501,
2262 0.9999,
2263 };
2264 UErrorCode status = U_ZERO_ERROR;
2265 DecimalFormatSymbols sym(Locale::getUS(), status);
2266 failure(status, "Construct DecimalFormatSymbols");
2267 DecimalFormat fmt("#", sym, status);
2268 if (!failure(status, "Construct DecimalFormat")) {
2269 for (int i=0; i<DATA_length; i+=3) {
2270 double in = DOUBLE[i/3];
2271 UnicodeString pat(DATA[i+1]);
2272 UnicodeString exp(DATA[i+2]);
2273 fmt.applyPattern(pat, status);
2274 failure(status, "applyPattern");
2275 UnicodeString out;
2276 FieldPosition pos;
2277 fmt.format(in, out, pos);
2278 if (out == exp) {
2279 logln(UnicodeString("Ok: ") + in + " x " + pat + " = " + out);
2280 } else {
2281 errln(UnicodeString("FAIL: ") + in + " x " + pat + " = " + out +
2282 ", expected " + exp);
2283 }
2284 }
2285 }
2286 }
2287
2288 /**
2289 * May 17 1999 sync up - liu
2290 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
2291 * This includes the minus sign, currency symbol, international currency
2292 * symbol, percent, and permille. This is filed as bugs 4212072 and
2293 * 4212073.
2294 */
2295 void NumberFormatRegressionTest::Test4212072(void) {
2296 UErrorCode status = U_ZERO_ERROR;
2297 DecimalFormatSymbols sym(Locale::getUS(), status);
2298
2299 failure(status, "DecimalFormatSymbols ct", Locale::getUS());
2300 DecimalFormat fmt(UnicodeString("#"), sym, status);
2301 if(failure(status, "DecimalFormat ct", Locale::getUS())) {
2302 return;
2303 }
2304
2305 UnicodeString s;
2306 FieldPosition pos;
2307
2308 sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x5e);
2309 fmt.setDecimalFormatSymbols(sym);
2310 s.remove();
2311 if (fmt.format((int32_t)-1, s, pos) != UNICODE_STRING("^1", 2)) {
2312 errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s +
2313 ", exp ^1");
2314 }
2315 s.remove();
2316 if (fmt.getNegativePrefix(s) != UnicodeString((UChar)0x5e)) {
2317 errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") +
2318 s + ", exp ^");
2319 }
2320 sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x2d);
2321
2322 fmt.applyPattern(UnicodeString("#%"), status);
2323 failure(status, "applyPattern percent");
2324 sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x5e);
2325 fmt.setDecimalFormatSymbols(sym);
2326 s.remove();
2327 if (fmt.format(0.25, s, pos) != UNICODE_STRING("25^", 3)) {
2328 errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s +
2329 ", exp 25^");
2330 }
2331 s.remove();
2332 if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) {
2333 errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") +
2334 s + ", exp ^");
2335 }
2336 sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x25);
2337
2338 fmt.applyPattern(str("#\\u2030"), status);
2339 failure(status, "applyPattern permill");
2340 sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x5e);
2341 fmt.setDecimalFormatSymbols(sym);
2342 s.remove();
2343 if (fmt.format(0.25, s, pos) != UNICODE_STRING("250^", 4)) {
2344 errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s +
2345 ", exp 250^");
2346 }
2347 s.remove();
2348 if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) {
2349 errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") +
2350 s + ", exp ^");
2351 }
2352 sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x2030);
2353
2354 fmt.applyPattern(str("\\u00A4#.00"), status);
2355 failure(status, "applyPattern currency");
2356 sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "usd");
2357 fmt.setDecimalFormatSymbols(sym);
2358 s.remove();
2359 if (fmt.format(12.5, s, pos) != UnicodeString("usd12.50")) {
2360 errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s +
2361 ", exp usd12.50");
2362 }
2363 s.remove();
2364 if (fmt.getPositivePrefix(s) != UnicodeString("usd")) {
2365 errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") +
2366 s + ", exp usd");
2367 }
2368 sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "$");
2369
2370 fmt.applyPattern(str("\\u00A4\\u00A4#.00"), status);
2371 failure(status, "applyPattern intl currency");
2372 sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "DOL");
2373 fmt.setDecimalFormatSymbols(sym);
2374 s.remove();
2375 if (fmt.format(12.5, s, pos) != UnicodeString("DOL12.50")) {
2376 errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s +
2377 ", exp DOL12.50");
2378 }
2379 s.remove();
2380 if (fmt.getPositivePrefix(s) != UnicodeString("DOL")) {
2381 errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") +
2382 s + ", exp DOL");
2383 }
2384 sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "USD");
2385
2386 // Since the pattern logic has changed, make sure that patterns round
2387 // trip properly. Test stream in/out integrity too.
2388 int32_t n;
2389 const Locale* avail = NumberFormat::getAvailableLocales(n);
2390 static const char* type[] = {
2391 "",
2392 "$ ",
2393 "% ",
2394 };
2395 for (int i=0; i<n; ++i) {
2396 for (int j=0; j<3; ++j) {
2397 status = U_ZERO_ERROR;
2398 NumberFormat *nf;
2399 switch (j) {
2400 case 0:
2401 nf = NumberFormat::createInstance(avail[i], status);
2402 failure(status, "createInstance", avail[i]);
2403 break;
2404 case 1:
2405 nf = NumberFormat::createCurrencyInstance(avail[i], status);
2406 failure(status, "createCurrencyInstance", avail[i]);
2407 break;
2408 default:
2409 nf = NumberFormat::createPercentInstance(avail[i], status);
2410 failure(status, "createPercentInstance", avail[i]);
2411 break;
2412 }
2413 if (U_FAILURE(status)) {
2414 continue;
2415 }
2416 DecimalFormat *df = (DecimalFormat*) nf;
2417
2418 // Test toPattern/applyPattern round trip
2419 UnicodeString pat;
2420 df->toPattern(pat);
2421 DecimalFormatSymbols symb(avail[i], status);
2422 failure(status, "Construct DecimalFormatSymbols", avail[i]);
2423 DecimalFormat f2(pat, symb, status);
2424 if (failure(status,
2425 UnicodeString("Construct DecimalFormat(") + pat + ")")) {
2426 continue;
2427 }
2428 if (*df != f2) {
2429 UnicodeString l, p;
2430 errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) +
2431 " -> \"" + pat +
2432 "\" -> \"" + f2.toPattern(p) + "\"");
2433 } else {
2434 UnicodeString l, p;
2435 logln(UnicodeString("PASS: ") + type[j] + avail[i].getDisplayName(l) +
2436 " -> \"" + pat +
2437 "\"");
2438 }
2439
2440 // Test toLocalizedPattern/applyLocalizedPattern round trip
2441 df->toLocalizedPattern(pat);
2442 f2.applyLocalizedPattern(pat, status);
2443 failure(status,
2444 UnicodeString("applyLocalizedPattern(") + pat + ")", avail[i]);
2445 if (U_FAILURE(status)) {
2446 continue;
2447 }
2448
2449 // Make sure we set the currency attributes appropriately
2450 if (j == 1) { // Currency format
2451 f2.setCurrency(f2.getCurrency(), status);
2452 }
2453 failure(status,
2454 UnicodeString("setCurrency() for (") + pat + ")", avail[i]);
2455 if (U_FAILURE(status)) {
2456 continue;
2457 }
2458
2459 if (*df != f2) {
2460 UnicodeString l, p;
2461 errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) +
2462 " -> localized \"" + pat +
2463 "\" -> \"" + f2.toPattern(p) + "\"");
2464 }
2465
2466 delete nf;
2467
2468 // Test writeObject/readObject round trip
2469 // NOT ON ICU -- Java only
2470 }
2471 }
2472 }
2473
2474 /**
2475 * May 17 1999 sync up - liu
2476 * DecimalFormat.parse() fails for mulipliers 2^n.
2477 */
2478 void NumberFormatRegressionTest::Test4216742(void) {
2479 UErrorCode status = U_ZERO_ERROR;
2480 DecimalFormat *fmt = (DecimalFormat*) NumberFormat::createInstance(Locale::getUS(), status);
2481 if (failure(status, "createInstance", Locale::getUS(), TRUE)){
2482 delete fmt;
2483 return;
2484 };
2485 int32_t DATA[] = { INT32_MIN, INT32_MAX, -100000000, 100000000 };
2486 int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0]));
2487 for (int i=0; i<DATA_length; ++i) {
2488 UnicodeString str((UnicodeString)"" + DATA[i]);
2489 for (int m = 1; m <= 100; m++) {
2490 fmt->setMultiplier(m);
2491 Formattable num;
2492 fmt->parse(str, num, status);
2493 failure(status, "parse", Locale::getUS());
2494 if (num.getType() != Formattable::kLong &&
2495 num.getType() != Formattable::kDouble) {
2496 errln(UnicodeString("FAIL: Wanted number, got ") +
2497 toString(num));
2498 } else {
2499 double d = num.getType() == Formattable::kDouble ?
2500 num.getDouble() : (double) num.getLong();
2501 if ((d > 0) != (DATA[i] > 0)) {
2502 errln(UnicodeString("\"") + str + "\" parse(x " +
2503 fmt->getMultiplier() +
2504 ") => " + toString(num));
2505 }
2506 }
2507 }
2508 }
2509 delete fmt;
2510 }
2511
2512 /**
2513 * May 17 1999 sync up - liu
2514 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction
2515 * digits.
2516 */
2517 void NumberFormatRegressionTest::Test4217661(void) {
2518 const double D[] = { 0.001, 1.001, 0.006, 1.006 };
2519 const char* S[] = { "0", "1", "0.01", "1.01" };
2520 int D_length = (int)(sizeof(D) / sizeof(D[0]));
2521 UErrorCode status = U_ZERO_ERROR;
2522 NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status);
2523 if (failure(status, "createInstance", Locale::getUS(), TRUE)){
2524 delete fmt;
2525 return;
2526 };
2527 fmt->setMaximumFractionDigits(2);
2528 for (int i=0; i<D_length; i++) {
2529 UnicodeString s;
2530 fmt->format(D[i], s);
2531 if (s != UnicodeString(S[i])) {
2532 errln(UnicodeString("FAIL: Got ") + s + ", exp " + S[i]);
2533 }
2534 }
2535 delete fmt;
2536 }
2537
2538 /**
2539 * alphaWorks upgrade
2540 */
2541 void NumberFormatRegressionTest::Test4161100(void) {
2542 UErrorCode status = U_ZERO_ERROR;
2543 NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
2544 if (failure(status, "createInstance", Locale::getUS(), TRUE)){
2545 delete nf;
2546 return;
2547 };
2548 nf->setMinimumFractionDigits(1);
2549 nf->setMaximumFractionDigits(1);
2550 double a = -0.09;
2551 UnicodeString s;
2552 nf->format(a, s);
2553 UnicodeString pat;
2554 logln(UnicodeString() + a + " x " +
2555 ((DecimalFormat*) nf)->toPattern(pat) + " = " + s);
2556 if (s != UnicodeString("-0.1")) {
2557 errln("FAIL");
2558 }
2559 delete nf;
2560 }
2561
2562 /**
2563 * June 16 1999 sync up - liu
2564 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1)
2565 */
2566 void NumberFormatRegressionTest::Test4243011(void) {
2567 UErrorCode status = U_ZERO_ERROR;
2568 DecimalFormatSymbols sym(Locale::getUS(), status);
2569 failure(status, "DecimalFormatSymbols ct", Locale::getUS());
2570 DecimalFormat fmt(UnicodeString("0."), sym, status);
2571
2572 if (!failure(status, "DecimalFormat ct", Locale::getUS())) {
2573 const double NUM[] = { -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5 };
2574 const char* STR[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." };
2575 int32_t N = (int32_t)(sizeof(NUM) / sizeof(NUM[0]));
2576
2577 for (int32_t i=0; i<N; ++i) {
2578 UnicodeString str;
2579 UnicodeString exp(STR[i]);
2580 FieldPosition pos;
2581 fmt.format(NUM[i], str, pos);
2582 if (str == exp) {
2583 logln(UnicodeString("Ok ") + NUM[i] + " x 0. = " + str);
2584 } else {
2585 errln(UnicodeString("FAIL ") + NUM[i] + " x 0. = " + str +
2586 ", want " + exp);
2587 }
2588 }
2589 }
2590 }
2591
2592 /**
2593 * June 16 1999 sync up - liu
2594 * format(0.0) gives "0.1" if preceded by parse("99.99").
2595 * (Regression in 1.2.2 RC1)
2596 */
2597 void NumberFormatRegressionTest::Test4243108(void) {
2598 UErrorCode status = U_ZERO_ERROR;
2599 DecimalFormatSymbols sym(Locale::getUS(), status);
2600 failure(status, "DecimalFormatSymbols ct", Locale::getUS());
2601 DecimalFormat fmt(UnicodeString("#.#"), sym, status);
2602 if (failure(status, "DecimalFormat ct", Locale::getUS())) {
2603 return;
2604 }
2605
2606 UnicodeString str;
2607 FieldPosition pos;
2608
2609 fmt.format(0.0, str, pos);
2610 UnicodeString exp("0");
2611 if (str == exp) {
2612 logln(UnicodeString("Ok 0.0 x #.# = ") + str);
2613 } else {
2614 errln(UnicodeString("FAIL 0.0 x #.# = ") + str +
2615 ", want " + exp);
2616 }
2617
2618 str = "99.99";
2619 Formattable val;
2620 fmt.parse(str, val, status);
2621 failure(status, "DecimalFormat.parse(99.99)", Locale::getUS());
2622 if (val.getType() == Formattable::kDouble &&
2623 val.getDouble() == 99.99) {
2624 logln(UnicodeString("Ok 99.99 / #.# = ") + toString(val));
2625 } else {
2626 errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val) +
2627 ", want " + 99.99);
2628 }
2629
2630 str.remove();
2631 fmt.format(0.0, str, pos);
2632 if (str == exp) {
2633 logln(UnicodeString("Ok 0.0 x #.# = ") + str);
2634 } else {
2635 errln(UnicodeString("FAIL 0.0 x #.# = ") + str +
2636 ", want " + exp);
2637 }
2638 }
2639
2640
2641 /**
2642 * DateFormat should call setIntegerParseOnly(TRUE) on adopted
2643 * NumberFormat objects.
2644 */
2645 void NumberFormatRegressionTest::TestJ691(void) {
2646 UErrorCode status = U_ZERO_ERROR;
2647 Locale loc("fr", "CH");
2648
2649 // set up the input date string & expected output
2650 UnicodeString udt("11.10.2000", "");
2651 UnicodeString exp("11.10.00", "");
2652
2653 // create a Calendar for this locale
2654 Calendar *cal = Calendar::createInstance(loc, status);
2655 if (U_FAILURE(status)) {
2656 dataerrln("FAIL: Calendar::createInstance() returned " + (UnicodeString)u_errorName(status));
2657 return;
2658 }
2659
2660 // create a NumberFormat for this locale
2661 NumberFormat *nf = NumberFormat::createInstance(loc, status);
2662 if (U_FAILURE(status)) {
2663 dataerrln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString)u_errorName(status));
2664 return;
2665 }
2666
2667 // *** Here's the key: We don't want to have to do THIS:
2668 // nf->setParseIntegerOnly(TRUE);
2669
2670 // create the DateFormat
2671 DateFormat *df = DateFormat::createDateInstance(DateFormat::kShort, loc);
2672 if (U_FAILURE(status)) {
2673 errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString)u_errorName(status));
2674 return;
2675 }
2676
2677 df->adoptCalendar(cal);
2678 df->adoptNumberFormat(nf);
2679
2680 // set parsing to lenient & parse
2681 df->setLenient(TRUE);
2682 UDate ulocdat = df->parse(udt, status);
2683
2684 // format back to a string
2685 UnicodeString outString;
2686 df->format(ulocdat, outString);
2687
2688 if (outString != exp) {
2689 errln("FAIL: " + udt + " => " + outString);
2690 }
2691
2692 delete df;
2693 }
2694
2695 //---------------------------------------------------------------------------
2696 //
2697 // Error Checking / Reporting macros
2698 //
2699 //---------------------------------------------------------------------------
2700 #define TEST_CHECK_STATUS(status) { \
2701 if (U_FAILURE(status)) { \
2702 if (status == U_MISSING_RESOURCE_ERROR) { \
2703 dataerrln("File %s, Line %d: status=%s", __FILE__, __LINE__, u_errorName(status)); \
2704 } else { \
2705 errln("File %s, Line %d: status=%s", __FILE__, __LINE__, u_errorName(status)); \
2706 } return; \
2707 }}
2708
2709 #define TEST_ASSERT(expr) \
2710 if ((expr)==FALSE) {\
2711 errln("File %s, line %d: Assertion Failed: " #expr "\n", __FILE__, __LINE__);\
2712 }
2713
2714
2715 // Ticket 8199: Parse failure for numbers in the range of 1E10 - 1E18
2716
2717 void NumberFormatRegressionTest::Test8199(void) {
2718 UErrorCode status = U_ZERO_ERROR;
2719 NumberFormat *nf = NumberFormat::createInstance(Locale::getEnglish(), status);
2720 if (nf == NULL) {
2721 dataerrln("Fail: NumberFormat::createInstance(Locale::getEnglish(), status)");
2722 return;
2723 }
2724 TEST_CHECK_STATUS(status);
2725
2726 // Note: Retrieving parsed values from a Formattable as a reduced-precision type
2727 // should always truncate, no other rounding scheme.
2728
2729 UnicodeString numStr = "1000000000.6"; // 9 zeroes
2730 Formattable val;
2731 nf->parse(numStr, val, status);
2732 TEST_CHECK_STATUS(status);
2733 TEST_ASSERT(Formattable::kDouble == val.getType());
2734 TEST_ASSERT(1000000000 == val.getInt64(status));
2735 TEST_CHECK_STATUS(status);
2736 TEST_ASSERT(1000000000.6 == val.getDouble(status));
2737 TEST_CHECK_STATUS(status);
2738
2739 numStr = "100000000000000001.1"; // approx 1E17, parses as a double rather
2740 // than int64 because of the fraction
2741 // even though int64 is more precise.
2742 nf->parse(numStr, val, status);
2743 TEST_CHECK_STATUS(status);
2744 TEST_ASSERT(Formattable::kDouble == val.getType());
2745 TEST_ASSERT(100000000000000001LL == val.getInt64(status));
2746 TEST_CHECK_STATUS(status);
2747 TEST_ASSERT(100000000000000000.0 == val.getDouble(status));
2748 TEST_CHECK_STATUS(status);
2749
2750 numStr = "1E17"; // Parses with the internal decimal number having non-zero exponent
2751 nf->parse(numStr, val, status);
2752 TEST_CHECK_STATUS(status);
2753 TEST_ASSERT(Formattable::kInt64 == val.getType());
2754 TEST_ASSERT(100000000000000000LL == val.getInt64());
2755 TEST_ASSERT(1.0E17 == val.getDouble(status));
2756 TEST_CHECK_STATUS(status);
2757
2758 numStr = "9223372036854775807"; // largest int64_t
2759 nf->parse(numStr, val, status);
2760 TEST_CHECK_STATUS(status);
2761 TEST_ASSERT(Formattable::kInt64 == val.getType());
2762 TEST_ASSERT(9223372036854775807LL == val.getInt64());
2763 // In the following check, note that a substantial range of integers will
2764 // convert to the same double value. There are also platform variations
2765 // in the rounding at compile time of double constants.
2766 TEST_ASSERT(9223372036854775808.0 >= val.getDouble(status));
2767 TEST_ASSERT(9223372036854774700.0 <= val.getDouble(status));
2768 TEST_CHECK_STATUS(status);
2769
2770 numStr = "-9223372036854775808"; // smallest int64_t
2771 nf->parse(numStr, val, status);
2772 TEST_CHECK_STATUS(status);
2773 TEST_ASSERT(Formattable::kInt64 == val.getType());
2774 // TEST_ASSERT(-9223372036854775808LL == val.getInt64()); // Compiler chokes on constant.
2775 TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64());
2776 TEST_ASSERT(-9223372036854775808.0 == val.getDouble(status));
2777 TEST_CHECK_STATUS(status);
2778
2779 numStr = "9223372036854775808"; // largest int64_t + 1
2780 nf->parse(numStr, val, status);
2781 TEST_CHECK_STATUS(status);
2782 TEST_ASSERT(Formattable::kDouble == val.getType());
2783 TEST_ASSERT(9223372036854775807LL == val.getInt64(status));
2784 TEST_ASSERT(status == U_INVALID_FORMAT_ERROR);
2785 status = U_ZERO_ERROR;
2786 TEST_ASSERT(9223372036854775810.0 == val.getDouble(status));
2787 TEST_CHECK_STATUS(status);
2788
2789 numStr = "-9223372036854775809"; // smallest int64_t - 1
2790 nf->parse(numStr, val, status);
2791 TEST_CHECK_STATUS(status);
2792 TEST_ASSERT(Formattable::kDouble == val.getType());
2793 // TEST_ASSERT(-9223372036854775808LL == val.getInt64(status)); // spurious compiler warnings
2794 TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64(status));
2795 TEST_ASSERT(status == U_INVALID_FORMAT_ERROR);
2796 status = U_ZERO_ERROR;
2797 TEST_ASSERT(-9223372036854775810.0 == val.getDouble(status));
2798 TEST_CHECK_STATUS(status);
2799
2800 // Test values near the limit of where doubles can represent all integers.
2801 // The implementation strategy of getInt64() changes at this boundary.
2802 // Strings to be parsed include a decimal fraction to force them to be
2803 // parsed as doubles rather than ints. The fraction is discarded
2804 // from the parsed double value because it is beyond what can be represented.
2805
2806 status = U_ZERO_ERROR;
2807 numStr = "9007199254740991.1"; // largest 53 bit int
2808 nf->parse(numStr, val, status);
2809 TEST_CHECK_STATUS(status);
2810 // printf("getInt64() returns %lld\n", val.getInt64(status));
2811 TEST_ASSERT(Formattable::kDouble == val.getType());
2812 TEST_ASSERT(9007199254740991LL == val.getInt64(status));
2813 TEST_ASSERT(9007199254740991.0 == val.getDouble(status));
2814 TEST_CHECK_STATUS(status);
2815
2816 status = U_ZERO_ERROR;
2817 numStr = "9007199254740992.1"; // 54 bits for the int part.
2818 nf->parse(numStr, val, status);
2819 TEST_CHECK_STATUS(status);
2820 TEST_ASSERT(Formattable::kDouble == val.getType());
2821 TEST_ASSERT(9007199254740992LL == val.getInt64(status));
2822 TEST_ASSERT(9007199254740992.0 == val.getDouble(status));
2823 TEST_CHECK_STATUS(status);
2824
2825 status = U_ZERO_ERROR;
2826 numStr = "9007199254740993.1"; // 54 bits for the int part. Double will round
2827 nf->parse(numStr, val, status); // the ones digit, putting it up to ...994
2828 TEST_CHECK_STATUS(status);
2829 TEST_ASSERT(Formattable::kDouble == val.getType());
2830 TEST_ASSERT(9007199254740993LL == val.getInt64(status));
2831 TEST_ASSERT(9007199254740994.0 == val.getDouble(status));
2832 TEST_CHECK_STATUS(status);
2833
2834 delete nf;
2835 }
2836
2837 void NumberFormatRegressionTest::Test9109(void) {
2838 UErrorCode status = U_ZERO_ERROR;
2839 Formattable val;
2840 ParsePosition pos;
2841 DecimalFormat fmt("+##", status);
2842 fmt.setLenient(TRUE);
2843
2844 if (U_FAILURE(status)) {
2845 dataerrln("Failed to create DecimalFormat with pattern '+##' - %s", u_errorName(status));
2846 }
2847
2848 UnicodeString text("123");
2849 int32_t expected = 123;
2850 int32_t expos = 3;
2851
2852 fmt.parse(text, val, pos);
2853 if (pos.getErrorIndex() >= 0) {
2854 errln(UnicodeString("Parse failure at ") + pos.getErrorIndex());
2855 } else if (val.getLong() != 123) {
2856 errln(UnicodeString("Incorrect parse result: ") + val.getLong() + " expected: " + expected);
2857 } else if (pos.getIndex() != 3) {
2858 errln(UnicodeString("Incorrect parse position: ") + pos.getIndex() + " expected: " + expos);
2859 }
2860 }
2861
2862
2863 void NumberFormatRegressionTest::Test9780(void) {
2864 UErrorCode status = U_ZERO_ERROR;
2865 NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status);
2866 if (failure(status, "NumberFormat::createInstance", TRUE)){
2867 delete nf;
2868 return;
2869 };
2870 DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf);
2871 if(df == NULL) {
2872 errln("DecimalFormat needed to continue");
2873 return;
2874 }
2875 df->setParseIntegerOnly(TRUE);
2876
2877 {
2878 Formattable n;
2879 ParsePosition pos(0);
2880 UnicodeString toParse("1,234","");
2881 df->parse(toParse, n, pos);
2882 if (n.getType() != Formattable::kLong
2883 || n.getLong() != 1234) {
2884 errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n));
2885 }
2886 }
2887 // should still work in lenient mode, just won't get fastpath
2888 df->setLenient(TRUE);
2889 {
2890 Formattable n;
2891 ParsePosition pos(0);
2892 UnicodeString toParse("1,234","");
2893 df->parse(toParse, n, pos);
2894 if (n.getType() != Formattable::kLong
2895 || n.getLong() != 1234) {
2896 errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n));
2897 }
2898 }
2899 delete nf;
2900 }
2901
2902
2903 void NumberFormatRegressionTest::Test9677(void) {
2904 static const UChar pattern[] = { 0x23,0x23,0x23,0x23,0x2E,0x23,0x23,0x23,0x23,0 }; // "####.####"
2905 static const UChar positivePrefix[] = { 0x40,0 }; // "@"
2906 static const UChar negativePrefix[] = { 0x6E,0 }; // "n"
2907 static const UChar text[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // 123456789
2908 static const UChar text2[] = { 0x6E, 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // n123456789
2909
2910 UErrorCode status = U_ZERO_ERROR;
2911 LocalUNumberFormatPointer f(unum_open(UNUM_DEFAULT, NULL, 0, "en_US", NULL, &status));
2912 if (U_FAILURE(status)) {
2913 dataerrln("Failure opening unum_open");
2914 return;
2915 }
2916
2917 if (U_SUCCESS(status)) {
2918 unum_applyPattern(f.getAlias(), FALSE, pattern, -1, NULL, &status);
2919 unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, positivePrefix, -1, &status);
2920 assertSuccess("setting attributes", status);
2921 }
2922
2923 if(U_SUCCESS(status)) {
2924 int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status);
2925 logln("unum_parse status %s, result %d\n", u_errorName(status), n);
2926
2927 if(U_FAILURE(status)) {
2928 logln("Got expected parse error %s\n", u_errorName(status));
2929 status = U_ZERO_ERROR;
2930 } else {
2931 errln("FAIL: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n);
2932 }
2933 }
2934
2935 if (U_SUCCESS(status)) {
2936 unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, NULL, 0, &status);
2937 assertSuccess("setting attributes", status);
2938 logln("removed positive prefix");
2939 }
2940
2941 if(U_SUCCESS(status)) {
2942 int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status);
2943 logln("unum_parse status %s, result %d\n", u_errorName(status), n);
2944
2945 if(U_FAILURE(status)) {
2946 errln("FAIL: with pos prefix removed, parse error %s\n", u_errorName(status));
2947 status = U_ZERO_ERROR;
2948 } else {
2949 if(n!=123456789) {
2950 errln("FAIL: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status), n);
2951 } else {
2952 logln("PASS: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status),n);
2953 }
2954 }
2955 }
2956
2957 if(U_SUCCESS(status)) {
2958 int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status);
2959 logln("unum_parse status %s, result %d\n", u_errorName(status), n);
2960
2961 if(U_FAILURE(status)) {
2962 logln("text2: Got expected parse error %s\n", u_errorName(status));
2963 status = U_ZERO_ERROR;
2964 } else {
2965 errln("FAIL: text2: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n);
2966 }
2967 }
2968
2969 if (U_SUCCESS(status)) {
2970 unum_setTextAttribute(f.getAlias(), UNUM_NEGATIVE_PREFIX, negativePrefix, -1, &status);
2971 assertSuccess("setting attributes", status);
2972 logln("Set a different neg prefix prefix");
2973 }
2974
2975 if(U_SUCCESS(status)) {
2976 int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status);
2977 logln("unum_parse status %s, result %d\n", u_errorName(status), n);
2978
2979 if(U_FAILURE(status)) {
2980 errln("FAIL: with different neg prefix , parse error %s\n", u_errorName(status));
2981 status = U_ZERO_ERROR;
2982 } else {
2983 ;
2984 if(n!=-123456789) {
2985 errln("FAIL: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n);
2986 } else {
2987 logln("PASS: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n);
2988 }
2989 }
2990 }
2991 }
2992
2993 void NumberFormatRegressionTest::Test10361(void) {
2994 // DecimalFormat/NumberFormat were artificially limiting the number of digits,
2995 // preventing formatting of big decimals.
2996 UErrorCode status = U_ZERO_ERROR;
2997 DecimalFormatSymbols symbols(Locale::getEnglish(), status);
2998 LocalPointer<DecimalFormat> df(new DecimalFormat("###.##", symbols, status), status);
2999 TEST_CHECK_STATUS(status);
3000
3001 // Create a decimal number with a million digits.
3002 const int32_t NUMSIZE=1000000;
3003 char *num = new char[NUMSIZE];
3004 for (int32_t i=0; i<NUMSIZE; i++) {
3005 num[i] = '0' + (i+1) % 10;
3006 }
3007 num[NUMSIZE-3] = '.';
3008 num[NUMSIZE-1] = 0;
3009
3010 UnicodeString s;
3011 Formattable fmtable;
3012 fmtable.setDecimalNumber(num, status);
3013 TEST_CHECK_STATUS(status);
3014
3015 FieldPosition pos(UNUM_DECIMAL_SEPARATOR_FIELD);
3016 df->format(fmtable, s, pos, status);
3017 TEST_CHECK_STATUS(status);
3018 TEST_ASSERT(999999 == s.length());
3019 TEST_ASSERT(999997 == pos.getBeginIndex());
3020 TEST_ASSERT(999998 == pos.getEndIndex());
3021
3022 UnicodeString expected(num, -1, US_INV);
3023 TEST_ASSERT(expected == s);
3024 delete [] num;
3025 }
3026
3027 #endif /* #if !UCONFIG_NO_FORMATTING */