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