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