]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/dcfmapts.cpp
ICU-62135.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / dcfmapts.cpp
index b190a0805f673fa1972985c906bd4bcc22306e36..1b4578da37194feca98957c8c58aeb90d88abcea 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /********************************************************************
- * COPYRIGHT: 
- * Copyright (c) 1997-2010, International Business Machines Corporation and
+ * COPYRIGHT:
+ * Copyright (c) 1997-2015, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************/
 
 
 #include "dcfmapts.h"
 
-#include "unicode/decimfmt.h"
+#include "unicode/currpinf.h"
 #include "unicode/dcfmtsym.h"
+#include "unicode/decimfmt.h"
+#include "unicode/fmtable.h"
+#include "unicode/localpointer.h"
 #include "unicode/parseerr.h"
-#include "unicode/currpinf.h"
+#include "unicode/stringpiece.h"
+
+#include "putilimp.h"
+#include "plurrule_impl.h"
+#include "number_decimalquantity.h"
+
+#include <stdio.h>
 
 // This is an API test, not a unit test.  It doesn't test very many cases, and doesn't
 // try to test the full functionality.  It just calls each function in the class and
@@ -23,7 +34,7 @@ void IntlTestDecimalFormatAPI::runIndexedTest( int32_t index, UBool exec, const
 {
     if (exec) logln((UnicodeString)"TestSuite DecimalFormatAPI");
     switch (index) {
-        case 0: name = "DecimalFormat API test"; 
+        case 0: name = "DecimalFormat API test";
                 if (exec) {
                     logln((UnicodeString)"DecimalFormat API test---"); logln((UnicodeString)"");
                     UErrorCode status = U_ZERO_ERROR;
@@ -54,7 +65,37 @@ void IntlTestDecimalFormatAPI::runIndexedTest( int32_t index, UBool exec, const
                TestCurrencyPluralInfo();
             }
             break;
-        default: name = ""; break;
+        case 4: name = "TestScale";
+            if(exec) {
+               logln((UnicodeString)"Scale test---");
+               TestScale();
+            }
+            break;
+         case 5: name = "TestFixedDecimal";
+            if(exec) {
+               logln((UnicodeString)"TestFixedDecimal ---");
+               TestFixedDecimal();
+            }
+            break;
+         case 6: name = "TestBadFastpath";
+            if(exec) {
+               logln((UnicodeString)"TestBadFastpath ---");
+               TestBadFastpath();
+            }
+            break;
+         case 7: name = "TestRequiredDecimalPoint";
+            if(exec) {
+               logln((UnicodeString)"TestRequiredDecimalPoint ---");
+               TestRequiredDecimalPoint();
+            }
+            break;
+         case 8: name = "testErrorCode";
+            if(exec) {
+               logln((UnicodeString)"testErrorCode ---");
+               testErrorCode();
+            }
+            break;
+       default: name = ""; break;
     }
 }
 
@@ -76,6 +117,42 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
         return;
     }
 
+    // bug 10864
+    status = U_ZERO_ERROR;
+    DecimalFormat noGrouping("###0.##", status);
+    assertEquals("Grouping size should be 0 for no grouping.", 0, noGrouping.getGroupingSize());
+    noGrouping.setGroupingUsed(TRUE);
+    assertEquals("Grouping size should still be 0.", 0, noGrouping.getGroupingSize());
+    // end bug 10864
+
+    // bug 13442 comment 14
+    status = U_ZERO_ERROR;
+    {
+        DecimalFormat df("0", {"en", status}, status);
+        UnicodeString result;
+        assertEquals("pat 0: ", 0, df.getGroupingSize());
+        assertEquals("pat 0: ", (UBool) FALSE, (UBool) df.isGroupingUsed());
+        df.setGroupingUsed(false);
+        assertEquals("pat 0 then disabled: ", 0, df.getGroupingSize());
+        assertEquals("pat 0 then disabled: ", u"1111", df.format(1111, result.remove()));
+        df.setGroupingUsed(true);
+        assertEquals("pat 0 then enabled: ", 0, df.getGroupingSize());
+        assertEquals("pat 0 then enabled: ", u"1111", df.format(1111, result.remove()));
+    }
+    {
+        DecimalFormat df("#,##0", {"en", status}, status);
+        UnicodeString result;
+        assertEquals("pat #,##0: ", 3, df.getGroupingSize());
+        assertEquals("pat #,##0: ", (UBool) TRUE, (UBool) df.isGroupingUsed());
+        df.setGroupingUsed(false);
+        assertEquals("pat #,##0 then disabled: ", 3, df.getGroupingSize());
+        assertEquals("pat #,##0 then disabled: ", u"1111", df.format(1111, result.remove()));
+        df.setGroupingUsed(true);
+        assertEquals("pat #,##0 then enabled: ", 3, df.getGroupingSize());
+        assertEquals("pat #,##0 then enabled: ", u"1,111", df.format(1111, result.remove()));
+    }
+    // end bug 13442 comment 14
+
     status = U_ZERO_ERROR;
     const UnicodeString pattern("#,##0.# FF");
     DecimalFormat pat(pattern, status);
@@ -134,8 +211,8 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
     Formattable fL(l);
 
     UnicodeString res1, res2, res3, res4;
-    FieldPosition pos1(0), pos2(0), pos3(0), pos4(0);
-    
+    FieldPosition pos1(FieldPosition::DONT_CARE), pos2(FieldPosition::DONT_CARE), pos3(FieldPosition::DONT_CARE), pos4(FieldPosition::DONT_CARE);
+
     res1 = def.format(d, res1, pos1);
     logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1);
 
@@ -266,7 +343,7 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
     if(sn != TRUE) {
         errln((UnicodeString)"ERROR: setScientificNotation() failed");
     }
-    
+
     // Added by Ken Liu testing set/getMinimumExponentDigits
     int8_t MinimumExponentDigits = 0;
     pat.setMinimumExponentDigits(2);
@@ -297,6 +374,7 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
 // ======= Test applyPattern()
 
     logln((UnicodeString)"Testing applyPattern()");
+    pat = DecimalFormat(status); // reset
 
     UnicodeString p1("#,##0.0#;(#,##0.0#)");
     logln((UnicodeString)"Applying pattern " + p1);
@@ -308,9 +386,7 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
     UnicodeString s2;
     s2 = pat.toPattern(s2);
     logln((UnicodeString)"Extracted pattern is " + s2);
-    if(s2 != p1) {
-        errln((UnicodeString)"ERROR: toPattern() result did not match pattern applied");
-    }
+    assertEquals("toPattern() result did not match pattern applied", p1, s2);
 
     if(pat.getSecondaryGroupingSize() != 0) {
         errln("FAIL: Secondary Grouping Size should be 0, not %d\n", pat.getSecondaryGroupingSize());
@@ -330,9 +406,7 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
     UnicodeString s3;
     s3 = pat.toLocalizedPattern(s3);
     logln((UnicodeString)"Extracted pattern is " + s3);
-    if(s3 != p2) {
-        errln((UnicodeString)"ERROR: toLocalizedPattern() result did not match pattern applied");
-    }
+    assertEquals("toLocalizedPattern() result did not match pattern applied", p2, s3);
 
     status = U_ZERO_ERROR;
     UParseError pe;
@@ -343,9 +417,7 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
     UnicodeString s4;
     s4 = pat.toLocalizedPattern(s3);
     logln((UnicodeString)"Extracted pattern is " + s4);
-    if(s4 != p2) {
-        errln((UnicodeString)"ERROR: toLocalizedPattern(with ParseErr) result did not match pattern applied");
-    }
+    assertEquals("toLocalizedPattern(with ParseErr) result did not match pattern applied", p2, s4);
 
     if(pat.getSecondaryGroupingSize() != 2) {
         errln("FAIL: Secondary Grouping Size should be 2, not %d\n", pat.getSecondaryGroupingSize());
@@ -395,7 +467,7 @@ void IntlTestDecimalFormatAPI::TestCurrencyPluralInfo(){
     if(U_FAILURE(status)) {
         errln((UnicodeString)"ERROR: CurrencyPluralInfo::setLocale");
     }
-    
+
     cpi->setPluralRules("",status);
     if(U_FAILURE(status)) {
         errln((UnicodeString)"ERROR: CurrencyPluralInfo::setPluralRules");
@@ -404,6 +476,7 @@ void IntlTestDecimalFormatAPI::TestCurrencyPluralInfo(){
     DecimalFormat *df = new DecimalFormat(status);
     if(U_FAILURE(status)) {
         errcheckln(status, "ERROR: Could not create DecimalFormat - %s", u_errorName(status));
+        return;
     }
 
     df->adoptCurrencyPluralInfo(cpi);
@@ -427,7 +500,7 @@ void IntlTestDecimalFormatAPI::testRounding(/*char *par*/)
                         3.0,            -3.0,    //  kRoundUp       3,
                         3.0,            -3.0,    //  kRoundHalfEven 4,
                         3.0,            -3.0,    //  kRoundHalfDown 5,
-                        3.0,            -3.0     //  kRoundHalfUp   6 
+                        3.0,            -3.0     //  kRoundHalfUp   6
     };
     DecimalFormat pat(status);
     if(U_FAILURE(status)) {
@@ -467,7 +540,14 @@ void IntlTestDecimalFormatAPI::verify(const UnicodeString& message, const Unicod
     UnicodeString expectedStr("");
     expectedStr=expectedStr + expected;
     if(got != expectedStr ) {
-            errln((UnicodeString)"ERROR: Round() failed:  " + message + got + (UnicodeString)"  Expected : " + expectedStr);
+            errln((UnicodeString)"ERROR: " + message + got + (UnicodeString)"  Expected : " + expectedStr);
+        }
+}
+
+void IntlTestDecimalFormatAPI::verifyString(const UnicodeString& message, const UnicodeString& got, UnicodeString& expected){
+    logln((UnicodeString)message + got + (UnicodeString)" Expected : " + expected);
+    if(got != expected ) {
+            errln((UnicodeString)"ERROR: " + message + got + (UnicodeString)"  Expected : " + expected);
         }
 }
 
@@ -487,11 +567,11 @@ void IntlTestDecimalFormatAPI::testRoundingInc(/*char *par*/)
       return;
     }
 
-    // With rounding now being handled by decNumber, we no longer 
+    // With rounding now being handled by decNumber, we no longer
     // set a rounding increment to enable non-default mode rounding,
     // checking of which was the original point of this test.
 
-    // set rounding mode with zero increment.  Rounding 
+    // set rounding mode with zero increment.  Rounding
     // increment should not be set by this operation
     pat.setRoundingMode((DecimalFormat::ERoundingMode)0);
     roundingInc = pat.getRoundingIncrement();
@@ -501,4 +581,520 @@ void IntlTestDecimalFormatAPI::testRoundingInc(/*char *par*/)
     }
 }
 
+void IntlTestDecimalFormatAPI::TestScale()
+{
+    typedef struct TestData {
+        double inputValue;
+        int inputScale;
+        const char *expectedOutput;
+    } TestData;
+
+    static TestData testData[] = {
+        { 100.0, 3,  "100,000" },
+        { 10034.0, -2, "100.34" },
+        { 0.86, -3, "0.0009" },
+        { -0.000455, 1, "-0%" },
+        { -0.000555, 1, "-1%" },
+        { 0.000455, 1, "0%" },
+        { 0.000555, 1, "1%" },
+    };
+
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormat pat(status);
+    if(U_FAILURE(status)) {
+      errcheckln(status, "ERROR: Could not create DecimalFormat (default) - %s", u_errorName(status));
+      return;
+    }
+
+    UnicodeString message;
+    UnicodeString resultStr;
+    UnicodeString exp;
+    UnicodeString percentPattern("#,##0%");
+    pat.setMaximumFractionDigits(4);
+
+    for(int32_t i=0; i < UPRV_LENGTHOF(testData); i++) {
+        if ( i > 2 ) {
+            pat.applyPattern(percentPattern,status);
+        }
+        pat.setAttribute(UNUM_SCALE,testData[i].inputScale,status);
+        pat.format(testData[i].inputValue, resultStr);
+        message = UnicodeString("Unexpected output for ") + testData[i].inputValue + UnicodeString(" and scale ") +
+                  testData[i].inputScale + UnicodeString(". Got: ");
+        exp = testData[i].expectedOutput;
+        verifyString(message, resultStr, exp);
+        message.remove();
+        resultStr.remove();
+        exp.remove();
+    }
+}
+
+
+#define ASSERT_EQUAL(expect, actual) { char tmp[200]; sprintf(tmp, "(%g==%g)", (double)(expect), (double)(actual)); \
+    assertTrue(tmp, ((expect)==(actual)), FALSE, TRUE, __FILE__, __LINE__); }
+
+void IntlTestDecimalFormatAPI::TestFixedDecimal() {
+    UErrorCode status = U_ZERO_ERROR;
+
+    LocalPointer<DecimalFormat> df(new DecimalFormat("###", status), status);
+    TEST_ASSERT_STATUS(status);
+    if (status == U_MISSING_RESOURCE_ERROR) {
+        return;
+    }
+    FixedDecimal fd = df->getFixedDecimal(44, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(44, fd.source);
+    ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fd = df->getFixedDecimal(-44, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(44, fd.source);
+    ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(TRUE, fd.isNegative);
+
+    df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.00##", status), status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(123.456, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
+    ASSERT_EQUAL(456, fd.decimalDigits); // f
+    ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
+    ASSERT_EQUAL(123, fd.intValue); // i
+    ASSERT_EQUAL(123.456, fd.source); // n
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fd = df->getFixedDecimal(-123.456, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
+    ASSERT_EQUAL(456, fd.decimalDigits); // f
+    ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
+    ASSERT_EQUAL(123, fd.intValue); // i
+    ASSERT_EQUAL(123.456, fd.source); // n
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(TRUE, fd.isNegative);
+
+    // test max int digits
+    df->setMaximumIntegerDigits(2);
+    fd = df->getFixedDecimal(123.456, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
+    ASSERT_EQUAL(456, fd.decimalDigits); // f
+    ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
+    ASSERT_EQUAL(23, fd.intValue); // i
+    ASSERT_EQUAL(23.456, fd.source); // n
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fd = df->getFixedDecimal(-123.456, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(3, fd.visibleDecimalDigitCount); // v
+    ASSERT_EQUAL(456, fd.decimalDigits); // f
+    ASSERT_EQUAL(456, fd.decimalDigitsWithoutTrailingZeros); // t
+    ASSERT_EQUAL(23, fd.intValue); // i
+    ASSERT_EQUAL(23.456, fd.source); // n
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(TRUE, fd.isNegative);
+
+    // test max fraction digits
+    df->setMaximumIntegerDigits(2000000000);
+    df->setMaximumFractionDigits(2);
+    fd = df->getFixedDecimal(123.456, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
+    ASSERT_EQUAL(46, fd.decimalDigits); // f
+    ASSERT_EQUAL(46, fd.decimalDigitsWithoutTrailingZeros); // t
+    ASSERT_EQUAL(123, fd.intValue); // i
+    ASSERT_EQUAL(123.46, fd.source); // n
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fd = df->getFixedDecimal(-123.456, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
+    ASSERT_EQUAL(46, fd.decimalDigits); // f
+    ASSERT_EQUAL(46, fd.decimalDigitsWithoutTrailingZeros); // t
+    ASSERT_EQUAL(123, fd.intValue); // i
+    ASSERT_EQUAL(123.46, fd.source); // n
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(TRUE, fd.isNegative);
+
+    // test esoteric rounding
+    df->setMaximumFractionDigits(6);
+    df->setRoundingIncrement(7.3);
+
+    fd = df->getFixedDecimal(30.0, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
+    ASSERT_EQUAL(20, fd.decimalDigits); // f
+    ASSERT_EQUAL(2, fd.decimalDigitsWithoutTrailingZeros); // t
+    ASSERT_EQUAL(29, fd.intValue); // i
+    ASSERT_EQUAL(29.2, fd.source); // n
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fd = df->getFixedDecimal(-30.0, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount); // v
+    ASSERT_EQUAL(20, fd.decimalDigits); // f
+    ASSERT_EQUAL(2, fd.decimalDigitsWithoutTrailingZeros); // t
+    ASSERT_EQUAL(29, fd.intValue); // i
+    ASSERT_EQUAL(29.2, fd.source); // n
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(TRUE, fd.isNegative);
+
+    df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###", status), status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(123.456, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(0, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(0, fd.decimalDigits);
+    ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(123, fd.intValue);
+    ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(123.01, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(1, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(0, fd.decimalDigits);
+    ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(123, fd.intValue);
+    ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    df.adoptInsteadAndCheckErrorCode(new DecimalFormat("###.0", status), status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(123.06, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(1, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(1, fd.decimalDigits);
+    ASSERT_EQUAL(1, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(123, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status);  // Significant Digits
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(123, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(0, fd.decimalDigits);
+    ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(123, fd.intValue);
+    ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    df.adoptInsteadAndCheckErrorCode(new DecimalFormat("@@@@@", status), status);  // Significant Digits
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(1.23, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(4, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(2300, fd.decimalDigits);
+    ASSERT_EQUAL(23, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(1, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fd = df->getFixedDecimal(uprv_getInfinity(), status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(TRUE, fd.isNanOrInfinity());
+    fd = df->getFixedDecimal(0.0, status);
+    ASSERT_EQUAL(FALSE, fd.isNanOrInfinity());
+    fd = df->getFixedDecimal(uprv_getNaN(), status);
+    ASSERT_EQUAL(TRUE, fd.isNanOrInfinity());
+    TEST_ASSERT_STATUS(status);
+
+    // Test Big Decimal input.
+    // 22 digits before and after decimal, will exceed the precision of a double
+    //    and force DecimalFormat::getFixedDecimal() to work with a digit list.
+    df.adoptInsteadAndCheckErrorCode(
+        new DecimalFormat("#####################0.00####################", status), status);
+    TEST_ASSERT_STATUS(status);
+    Formattable fable("12.34", status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(34, fd.decimalDigits);
+    ASSERT_EQUAL(34, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(12, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fable.setDecimalNumber("12.345678901234567890123456789", status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(345678901234567890LL, fd.decimalDigits);
+    ASSERT_EQUAL(34567890123456789LL, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(12, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    // On field overflow, Integer part is truncated on the left, fraction part on the right.
+    fable.setDecimalNumber("123456789012345678901234567890.123456789012345678901234567890", status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(123456789012345678LL, fd.decimalDigits);
+    ASSERT_EQUAL(123456789012345678LL, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(345678901234567890LL, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    // Digits way to the right of the decimal but within the format's precision aren't truncated
+    fable.setDecimalNumber("1.0000000000000000000012", status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(12, fd.decimalDigits);
+    ASSERT_EQUAL(12, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(1, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    // Digits beyond the precision of the format are rounded away
+    fable.setDecimalNumber("1.000000000000000000000012", status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(0, fd.decimalDigits);
+    ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(1, fd.intValue);
+    ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    // Negative numbers come through
+    fable.setDecimalNumber("-1.0000000000000000000012", status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(22, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(12, fd.decimalDigits);
+    ASSERT_EQUAL(12, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(1, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(TRUE, fd.isNegative);
+
+    // MinFractionDigits from format larger than from number.
+    fable.setDecimalNumber("1000000000000000000000.3", status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(30, fd.decimalDigits);
+    ASSERT_EQUAL(3, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(100000000000000000LL, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fable.setDecimalNumber("1000000000000000050000.3", status);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(30, fd.decimalDigits);
+    ASSERT_EQUAL(3, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(50000LL, fd.intValue);
+    ASSERT_EQUAL(FALSE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    // Test some int64_t values that are out of the range of a double
+    fable.setInt64(4503599627370496LL);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(0, fd.decimalDigits);
+    ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(4503599627370496LL, fd.intValue);
+    ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fable.setInt64(4503599627370497LL);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(0, fd.decimalDigits);
+    ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
+    ASSERT_EQUAL(4503599627370497LL, fd.intValue);
+    ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+    fable.setInt64(9223372036854775807LL);
+    TEST_ASSERT_STATUS(status);
+    fd = df->getFixedDecimal(fable, status);
+    TEST_ASSERT_STATUS(status);
+    ASSERT_EQUAL(2, fd.visibleDecimalDigitCount);
+    ASSERT_EQUAL(0, fd.decimalDigits);
+    ASSERT_EQUAL(0, fd.decimalDigitsWithoutTrailingZeros);
+    // note: going through DigitList path to FixedDecimal, which is trimming
+    //       int64_t fields to 18 digits. See ticket Ticket #10374
+    // ASSERT_EQUAL(223372036854775807LL, fd.intValue);
+    if (!(fd.intValue == 223372036854775807LL || fd.intValue == 9223372036854775807LL)) {
+        dataerrln("File %s, Line %d, fd.intValue = %lld", __FILE__, __LINE__, fd.intValue);
+    }
+    ASSERT_EQUAL(TRUE, fd.hasIntegerValue());
+    ASSERT_EQUAL(FALSE, fd.isNegative);
+
+}
+
+void IntlTestDecimalFormatAPI::TestBadFastpath() {
+    UErrorCode status = U_ZERO_ERROR;
+
+    LocalPointer<DecimalFormat> df(new DecimalFormat("###", status), status);
+    if (U_FAILURE(status)) {
+        dataerrln("Error creating new DecimalFormat - %s", u_errorName(status));
+        return;
+    }
+
+    UnicodeString fmt;
+    fmt.remove();
+    assertEquals("Format 1234", "1234", df->format((int32_t)1234, fmt));
+    df->setGroupingUsed(FALSE);
+    fmt.remove();
+    assertEquals("Format 1234", "1234", df->format((int32_t)1234, fmt));
+    df->setGroupingUsed(TRUE);
+    df->setGroupingSize(3);
+    fmt.remove();
+    assertEquals("Format 1234 w/ grouping", "1,234", df->format((int32_t)1234, fmt));
+}
+
+void IntlTestDecimalFormatAPI::TestRequiredDecimalPoint() {
+    UErrorCode status = U_ZERO_ERROR;
+    UnicodeString text("99");
+    Formattable result1;
+    UnicodeString pat1("##.0000");
+    UnicodeString pat2("00.0");
+
+    LocalPointer<DecimalFormat> df(new DecimalFormat(pat1, status), status);
+    if (U_FAILURE(status)) {
+        dataerrln("Error creating new DecimalFormat - %s", u_errorName(status));
+        return;
+    }
+
+    status = U_ZERO_ERROR;
+    df->applyPattern(pat1, status);
+    if(U_FAILURE(status)) {
+        errln((UnicodeString)"ERROR: applyPattern() failed");
+    }
+    df->parse(text, result1, status);
+    if(U_FAILURE(status)) {
+        errln((UnicodeString)"ERROR: parse() failed");
+    }
+    df->setDecimalPatternMatchRequired(TRUE);
+    df->parse(text, result1, status);
+    if(U_SUCCESS(status)) {
+        errln((UnicodeString)"ERROR: unexpected parse()");
+    }
+
+
+    status = U_ZERO_ERROR;
+    df->applyPattern(pat2, status);
+    df->setDecimalPatternMatchRequired(FALSE);
+    if(U_FAILURE(status)) {
+        errln((UnicodeString)"ERROR: applyPattern(2) failed");
+    }
+    df->parse(text, result1, status);
+    if(U_FAILURE(status)) {
+        errln((UnicodeString)"ERROR: parse(2) failed - " + u_errorName(status));
+    }
+    df->setDecimalPatternMatchRequired(TRUE);
+    df->parse(text, result1, status);
+    if(U_SUCCESS(status)) {
+        errln((UnicodeString)"ERROR: unexpected parse(2)");
+    }
+}
+
+// WHERE Macro yields a literal string of the form "source_file_name:line number "
+#define WHERE __FILE__ ":" XLINE(__LINE__) " "
+#define XLINE(s) LINE(s)
+#define LINE(s) #s
+
+void IntlTestDecimalFormatAPI::testErrorCode() {
+    // Try each DecimalFormat constructor with an errorCode set on input,
+    // Verify no crashes or leaks, and that the errorCode is not altered.
+
+    UErrorCode status = U_ZERO_ERROR;
+    const UnicodeString pattern(u"0.###E0");
+    UParseError pe;
+    DecimalFormatSymbols symbols(Locale::getUS(), status);
+    assertSuccess(WHERE, status);
+
+    {
+        status = U_INTERNAL_PROGRAM_ERROR;
+        DecimalFormat df(status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+    }
+    {
+        status = U_INTERNAL_PROGRAM_ERROR;
+        DecimalFormat df(pattern, status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+    }
+    {
+        status = U_INTERNAL_PROGRAM_ERROR;
+        DecimalFormat df(pattern, new DecimalFormatSymbols(symbols), status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+    }
+    {
+        status = U_INTERNAL_PROGRAM_ERROR;
+        DecimalFormat df(pattern, new DecimalFormatSymbols(symbols), UNUM_DECIMAL_COMPACT_LONG, status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+    }
+    {
+        status = U_INTERNAL_PROGRAM_ERROR;
+        DecimalFormat df(pattern, new DecimalFormatSymbols(symbols), pe, status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+    }
+    {
+        status = U_INTERNAL_PROGRAM_ERROR;
+        DecimalFormat df(pattern, symbols ,status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+    }
+
+    // Try each DecimalFormat method with an error code parameter, verifying that
+    //  an input error is not altered.
+
+    status = U_INTERNAL_PROGRAM_ERROR;
+    DecimalFormat dfBogus(status);
+    assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+
+    status = U_ZERO_ERROR;
+    DecimalFormat dfGood(pattern, new DecimalFormatSymbols(symbols), status);
+    assertSuccess(WHERE, status);
+
+    for (DecimalFormat *df: {&dfBogus, &dfGood}) {
+        status = U_INTERNAL_PROGRAM_ERROR;
+        df->setAttribute(UNUM_PARSE_INT_ONLY, 0, status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+
+        status = U_INTERNAL_PROGRAM_ERROR;
+        df->getAttribute(UNUM_MAX_FRACTION_DIGITS, status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+
+        UnicodeString dest;
+        FieldPosition fp;
+
+        status = U_INTERNAL_PROGRAM_ERROR;
+        df->applyLocalizedPattern(pattern, status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+
+        status = U_INTERNAL_PROGRAM_ERROR;
+        df->setCurrency(u"USD", status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+
+        status = U_INTERNAL_PROGRAM_ERROR;
+        df->setCurrencyUsage(UCURR_USAGE_CASH, &status);
+        assertEquals(WHERE, U_INTERNAL_PROGRAM_ERROR, status);
+    }
+}
+
 #endif /* #if !UCONFIG_NO_FORMATTING */