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