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