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