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