]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/numfmtst.cpp
ICU-62141.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / numfmtst.cpp
index 492b16b057b0d62e56827105a60cb86abe5cb14b..86c25e6bcb90a2ce08c741205f00811b6572699c 100644 (file)
@@ -15,6 +15,7 @@
 #if !UCONFIG_NO_FORMATTING
 
 #include "numfmtst.h"
+#include "unicode/currpinf.h"
 #include "unicode/dcfmtsym.h"
 #include "unicode/decimfmt.h"
 #include "unicode/localpointer.h"
 #include "unicode/measfmt.h"
 #include "unicode/curramt.h"
 #include "unicode/strenum.h"
-#include "digitlst.h"
 #include "textfile.h"
 #include "tokiter.h"
 #include "charstr.h"
+#include "cstr.h"
 #include "putilimp.h"
 #include "winnmtst.h"
+#include <cmath>
 #include <float.h>
 #include <string.h>
 #include <stdlib.h>
 #include "unicode/numsys.h"
 #include "fmtableimp.h"
 #include "numberformattesttuple.h"
-#include "datadrivennumberformattestsuite.h"
 #include "unicode/msgfmt.h"
-
-class NumberFormatTestDataDriven : public DataDrivenNumberFormatTestSuite {
-protected:
-UBool isFormatPass(
-        const NumberFormatTestTuple &tuple,
-        UnicodeString &appendErrorMessage,
-        UErrorCode &status);
-UBool isToPatternPass(
-        const NumberFormatTestTuple &tuple,
-        UnicodeString &appendErrorMessage,
-        UErrorCode &status);
-UBool isParsePass(
-        const NumberFormatTestTuple &tuple,
-        UnicodeString &appendErrorMessage,
-        UErrorCode &status);
-UBool isParseCurrencyPass(
-        const NumberFormatTestTuple &tuple,
-        UnicodeString &appendErrorMessage,
-        UErrorCode &status);
-};
-
-static DigitList &strToDigitList(
-        const UnicodeString &str,
-        DigitList &digitList,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return digitList;
-    }
-    if (str == "NaN") {
-        digitList.set(uprv_getNaN());
-        return digitList;
-    }
-    if (str == "-Inf") {
-        digitList.set(-1*uprv_getInfinity());
-        return digitList;
-    }
-    if (str == "Inf") {
-        digitList.set(uprv_getInfinity());
-        return digitList;
-    }
-    CharString formatValue;
-    formatValue.appendInvariantChars(str, status);
-    digitList.set(StringPiece(formatValue.data()), status, 0);
-    return digitList;
-}
-
-static UnicodeString &format(
-        const DecimalFormat &fmt,
-        const DigitList &digitList,
-        UnicodeString &appendTo,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return appendTo;
-    }
-    FieldPosition fpos(FieldPosition::DONT_CARE);
-    return fmt.format(digitList, appendTo, fpos, status);
-}
-
-template<class T>
-static UnicodeString &format(
-        const DecimalFormat &fmt,
-        T value,
-        UnicodeString &appendTo,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return appendTo;
-    }
-    FieldPosition fpos(FieldPosition::DONT_CARE);
-    return fmt.format(value, appendTo, fpos, status);
-}
-
-static void adjustDecimalFormat(
-        const NumberFormatTestTuple &tuple,
-        DecimalFormat &fmt,
-        UnicodeString &appendErrorMessage) {
-    if (tuple.minIntegerDigitsFlag) {
-        fmt.setMinimumIntegerDigits(tuple.minIntegerDigits);
-    }
-    if (tuple.maxIntegerDigitsFlag) {
-        fmt.setMaximumIntegerDigits(tuple.maxIntegerDigits);
-    }
-    if (tuple.minFractionDigitsFlag) {
-        fmt.setMinimumFractionDigits(tuple.minFractionDigits);
-    }
-    if (tuple.maxFractionDigitsFlag) {
-        fmt.setMaximumFractionDigits(tuple.maxFractionDigits);
-    }
-    if (tuple.currencyFlag) {
-        UErrorCode status = U_ZERO_ERROR;
-        UnicodeString currency(tuple.currency);
-        const UChar *terminatedCurrency = currency.getTerminatedBuffer();
-        fmt.setCurrency(terminatedCurrency, status);
-        if (U_FAILURE(status)) {
-            appendErrorMessage.append("Error setting currency.");
-        }
-    }
-    if (tuple.minGroupingDigitsFlag) {
-        fmt.setMinimumGroupingDigits(tuple.minGroupingDigits);
-    }
-    if (tuple.useSigDigitsFlag) {
-        fmt.setSignificantDigitsUsed(tuple.useSigDigits != 0);
-    }
-    if (tuple.minSigDigitsFlag) {
-        fmt.setMinimumSignificantDigits(tuple.minSigDigits);
-    }
-    if (tuple.maxSigDigitsFlag) {
-        fmt.setMaximumSignificantDigits(tuple.maxSigDigits);
-    }
-    if (tuple.useGroupingFlag) {
-        fmt.setGroupingUsed(tuple.useGrouping != 0);
-    }
-    if (tuple.multiplierFlag) {
-        fmt.setMultiplier(tuple.multiplier);
-    }
-    if (tuple.roundingIncrementFlag) {
-        fmt.setRoundingIncrement(tuple.roundingIncrement);
-    }
-    if (tuple.formatWidthFlag) {
-        fmt.setFormatWidth(tuple.formatWidth);
-    }
-    if (tuple.padCharacterFlag) {
-        fmt.setPadCharacter(tuple.padCharacter);
-    }
-    if (tuple.useScientificFlag) {
-        fmt.setScientificNotation(tuple.useScientific != 0);
-    }
-    if (tuple.groupingFlag) {
-        fmt.setGroupingSize(tuple.grouping);
-    }
-    if (tuple.grouping2Flag) {
-        fmt.setSecondaryGroupingSize(tuple.grouping2);
-    }
-    if (tuple.roundingModeFlag) {
-        fmt.setRoundingMode(tuple.roundingMode);
-    }
-    if (tuple.currencyUsageFlag) {
-        UErrorCode status = U_ZERO_ERROR;
-        fmt.setCurrencyUsage(tuple.currencyUsage, &status);
-        if (U_FAILURE(status)) {
-            appendErrorMessage.append("CurrencyUsage: error setting.");
-        }
-    }
-    if (tuple.minimumExponentDigitsFlag) {
-        fmt.setMinimumExponentDigits(tuple.minimumExponentDigits);
-    }
-    if (tuple.exponentSignAlwaysShownFlag) {
-        fmt.setExponentSignAlwaysShown(tuple.exponentSignAlwaysShown != 0);
-    }
-    if (tuple.decimalSeparatorAlwaysShownFlag) {
-        fmt.setDecimalSeparatorAlwaysShown(
-                tuple.decimalSeparatorAlwaysShown != 0);
-    }
-    if (tuple.padPositionFlag) {
-        fmt.setPadPosition(tuple.padPosition);
-    }
-    if (tuple.positivePrefixFlag) {
-        fmt.setPositivePrefix(tuple.positivePrefix);
-    }
-    if (tuple.positiveSuffixFlag) {
-        fmt.setPositiveSuffix(tuple.positiveSuffix);
-    }
-    if (tuple.negativePrefixFlag) {
-        fmt.setNegativePrefix(tuple.negativePrefix);
-    }
-    if (tuple.negativeSuffixFlag) {
-        fmt.setNegativeSuffix(tuple.negativeSuffix);
-    }
-    if (tuple.localizedPatternFlag) {
-        UErrorCode status = U_ZERO_ERROR;
-        fmt.applyLocalizedPattern(tuple.localizedPattern, status);
-        if (U_FAILURE(status)) {
-            appendErrorMessage.append("Error setting localized pattern.");
-        }
-    }
-    fmt.setLenient(NFTT_GET_FIELD(tuple, lenient, 1) != 0);
-    if (tuple.parseIntegerOnlyFlag) {
-        fmt.setParseIntegerOnly(tuple.parseIntegerOnly != 0);
-    }
-    if (tuple.decimalPatternMatchRequiredFlag) {
-        fmt.setDecimalPatternMatchRequired(
-                tuple.decimalPatternMatchRequired != 0);
-    }
-    if (tuple.parseNoExponentFlag) {
-        UErrorCode status = U_ZERO_ERROR;
-        fmt.setAttribute(
-                UNUM_PARSE_NO_EXPONENT,
-                tuple.parseNoExponent,
-                status);
-        if (U_FAILURE(status)) {
-            appendErrorMessage.append("Error setting parse no exponent flag.");
-        }
-    }
-}
-
-static DecimalFormat *newDecimalFormat(
-        const Locale &locale,
-        const UnicodeString &pattern,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-    LocalPointer<DecimalFormatSymbols> symbols(
-            new DecimalFormatSymbols(locale, status), status);
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-    UParseError perror;
-    LocalPointer<DecimalFormat> result(new DecimalFormat(
-            pattern, symbols.getAlias(), perror, status), status);
-    if (!result.isNull()) {
-        symbols.orphan();
-    }
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-    return result.orphan();
-}
-
-static DecimalFormat *newDecimalFormat(
-        const NumberFormatTestTuple &tuple,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-    Locale en("en");
-    return newDecimalFormat(
-            NFTT_GET_FIELD(tuple, locale, en),
-            NFTT_GET_FIELD(tuple, pattern, "0"),
-            status);
+#include "number_decimalquantity.h"
+#include "unicode/numberformatter.h"
+
+#if (U_PLATFORM == U_PF_AIX) || (U_PLATFORM == U_PF_OS390)
+// These should not be macros. If they are,
+// replace them with std::isnan and std::isinf
+#if defined(isnan)
+#undef isnan
+namespace std {
+ bool isnan(double x) {
+   return _isnan(x);
+ }
 }
-
-UBool NumberFormatTestDataDriven::isFormatPass(
-        const NumberFormatTestTuple &tuple,
-        UnicodeString &appendErrorMessage,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return FALSE;
-    }
-    LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status));
-    if (U_FAILURE(status)) {
-        appendErrorMessage.append("Error creating DecimalFormat.");
-        return FALSE;
-    }
-    adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage);
-    if (appendErrorMessage.length() > 0) {
-        return FALSE;
-    }
-    DigitList digitList;
-    strToDigitList(tuple.format, digitList, status);
-    {
-        UnicodeString appendTo;
-        format(*fmtPtr, digitList, appendTo, status);
-        if (U_FAILURE(status)) {
-            appendErrorMessage.append("Error formatting.");
-            return FALSE;
-        }
-        if (appendTo != tuple.output) {
-            appendErrorMessage.append(
-                    UnicodeString("Expected: ") + tuple.output + ", got: " + appendTo);
-            return FALSE;
-        }
-    }
-    double doubleVal = digitList.getDouble();
-    {
-        UnicodeString appendTo;
-        format(*fmtPtr, doubleVal, appendTo, status);
-        if (U_FAILURE(status)) {
-            appendErrorMessage.append("Error formatting.");
-            return FALSE;
-        }
-        if (appendTo != tuple.output) {
-            appendErrorMessage.append(
-                    UnicodeString("double Expected: ") + tuple.output + ", got: " + appendTo);
-            return FALSE;
-        }
-    }
-    if (!uprv_isNaN(doubleVal) && !uprv_isInfinite(doubleVal) && doubleVal == uprv_floor(doubleVal)) {
-        int64_t intVal = digitList.getInt64();
-        {
-            UnicodeString appendTo;
-            format(*fmtPtr, intVal, appendTo, status);
-            if (U_FAILURE(status)) {
-                appendErrorMessage.append("Error formatting.");
-                return FALSE;
-            }
-            if (appendTo != tuple.output) {
-                appendErrorMessage.append(
-                        UnicodeString("int64 Expected: ") + tuple.output + ", got: " + appendTo);
-                return FALSE;
-            }
-        }
-    }
-    return TRUE;
-}
-
-UBool NumberFormatTestDataDriven::isToPatternPass(
-        const NumberFormatTestTuple &tuple,
-        UnicodeString &appendErrorMessage,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return FALSE;
-    }
-    LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status));
-    if (U_FAILURE(status)) {
-        appendErrorMessage.append("Error creating DecimalFormat.");
-        return FALSE;
-    }
-    adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage);
-    if (appendErrorMessage.length() > 0) {
-        return FALSE;
-    }
-    if (tuple.toPatternFlag) {
-        UnicodeString actual;
-        fmtPtr->toPattern(actual);
-        if (actual != tuple.toPattern) {
-            appendErrorMessage.append(
-                    UnicodeString("Expected: ") + tuple.toPattern + ", got: " + actual + ". ");
-        }
-    }
-    if (tuple.toLocalizedPatternFlag) {
-        UnicodeString actual;
-        fmtPtr->toLocalizedPattern(actual);
-        if (actual != tuple.toLocalizedPattern) {
-            appendErrorMessage.append(
-                    UnicodeString("Expected: ") + tuple.toLocalizedPattern + ", got: " + actual + ". ");
-        }
-    }
-    return appendErrorMessage.length() == 0;
-}
-
-UBool NumberFormatTestDataDriven::isParsePass(
-        const NumberFormatTestTuple &tuple,
-        UnicodeString &appendErrorMessage,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return FALSE;
-    }
-    LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status));
-    if (U_FAILURE(status)) {
-        appendErrorMessage.append("Error creating DecimalFormat.");
-        return FALSE;
-    }
-    adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage);
-    if (appendErrorMessage.length() > 0) {
-        return FALSE;
-    }
-    Formattable result;
-    ParsePosition ppos;
-    fmtPtr->parse(tuple.parse, result, ppos);
-    if (ppos.getIndex() == 0) {
-        if (tuple.output != "fail") {
-            appendErrorMessage.append("Parse failed but was expected to succeed.");
-            return FALSE;
-        }
-        return TRUE;
-    }
-    UnicodeString resultStr(UnicodeString::fromUTF8(result.getDecimalNumber(status)));
-    if (tuple.output == "fail") {
-        appendErrorMessage.append(UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail.");
-        return FALSE;
-    }
-    DigitList expected;
-    strToDigitList(tuple.output, expected, status);
-    if (U_FAILURE(status)) {
-        appendErrorMessage.append("Error parsing.");
-        return FALSE;
-    }
-    if (expected != *result.getDigitList()) {
-        appendErrorMessage.append(
-                    UnicodeString("Expected: ") + tuple.output + ", got: " + resultStr + ". ");
-        return FALSE;
-    }
-    return TRUE;
+#endif
+#if defined(isinf)
+#undef isinf
+namespace std {
+ bool isinf(double x) {
+   return _isinf(x);
+ }
 }
+#endif
+#endif
 
-UBool NumberFormatTestDataDriven::isParseCurrencyPass(
-        const NumberFormatTestTuple &tuple,
-        UnicodeString &appendErrorMessage,
-        UErrorCode &status) {
-    if (U_FAILURE(status)) {
-        return FALSE;
-    }
-    LocalPointer<DecimalFormat> fmtPtr(newDecimalFormat(tuple, status));
-    if (U_FAILURE(status)) {
-        appendErrorMessage.append("Error creating DecimalFormat.");
-        return FALSE;
-    }
-    adjustDecimalFormat(tuple, *fmtPtr, appendErrorMessage);
-    if (appendErrorMessage.length() > 0) {
-        return FALSE;
-    }
-    ParsePosition ppos;
-    LocalPointer<CurrencyAmount> currAmt(
-            fmtPtr->parseCurrency(tuple.parse, ppos));
-    if (ppos.getIndex() == 0) {
-        if (tuple.output != "fail") {
-            appendErrorMessage.append("Parse failed but was expected to succeed.");
-            return FALSE;
-        }
-        return TRUE;
-    }
-    UnicodeString currStr(currAmt->getISOCurrency());
-    Formattable resultFormattable(currAmt->getNumber());
-    UnicodeString resultStr(UnicodeString::fromUTF8(resultFormattable.getDecimalNumber(status)));
-    if (tuple.output == "fail") {
-        appendErrorMessage.append(UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail.");
-        return FALSE;
-    }
-    DigitList expected;
-    strToDigitList(tuple.output, expected, status);
-    if (U_FAILURE(status)) {
-        appendErrorMessage.append("Error parsing.");
-        return FALSE;
-    }
-    if (expected != *currAmt->getNumber().getDigitList()) {
-        appendErrorMessage.append(
-                    UnicodeString("Expected: ") + tuple.output + ", got: " + resultStr + ". ");
-        return FALSE;
-    }
-    if (currStr != tuple.outputCurrency) {
-        appendErrorMessage.append(UnicodeString(
-                "Expected currency: ") + tuple.outputCurrency + ", got: " + currStr + ". ");
-        return FALSE;
-    }
-    return TRUE;
-}
+using icu::number::impl::DecimalQuantity;
+using namespace icu::number;
 
 //#define NUMFMTST_CACHE_DEBUG 1
 #include "stdio.h" /* for sprintf */
@@ -524,6 +125,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
   TESTCASE_AUTO(TestCurrencyAmount);
   TESTCASE_AUTO(TestCurrencyUnit);
   TESTCASE_AUTO(TestCoverage);
+  //TESTCASE_AUTO(TestLocalizedPatternSymbolCoverage);
   TESTCASE_AUTO(TestJB3832);
   TESTCASE_AUTO(TestHost);
   TESTCASE_AUTO(TestHostClone);
@@ -534,6 +136,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
   TESTCASE_AUTO(TestSpaceParsing);
   TESTCASE_AUTO(TestMultiCurrencySign);
   TESTCASE_AUTO(TestCurrencyFormatForMixParsing);
+  //TESTCASE_AUTO(TestMismatchedCurrencyFormatFail);
   TESTCASE_AUTO(TestDecimalFormatCurrencyParse);
   TESTCASE_AUTO(TestCurrencyIsoPluralFormat);
   TESTCASE_AUTO(TestCurrencyParsing);
@@ -542,8 +145,8 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
   TESTCASE_AUTO(TestFieldPositionIterator);
   TESTCASE_AUTO(TestDecimal);
   TESTCASE_AUTO(TestCurrencyFractionDigits);
-  TESTCASE_AUTO(TestExponentParse); 
-  TESTCASE_AUTO(TestExplicitParents); 
+  TESTCASE_AUTO(TestExponentParse);
+  TESTCASE_AUTO(TestExplicitParents);
   TESTCASE_AUTO(TestLenientParse);
   TESTCASE_AUTO(TestAvailableNumberingSystems);
   TESTCASE_AUTO(TestRoundingPattern);
@@ -566,10 +169,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
   TESTCASE_AUTO(TestAccountingCurrency);
   TESTCASE_AUTO(TestEquality);
   TESTCASE_AUTO(TestCurrencyUsage);
-  TESTCASE_AUTO(TestNumberFormatTestTuple);
-  TESTCASE_AUTO(TestDataDriven);
   TESTCASE_AUTO(TestDoubleLimit11439);
-  TESTCASE_AUTO(TestFastPathConsistent11524);
   TESTCASE_AUTO(TestGetAffixes);
   TESTCASE_AUTO(TestToPatternScientific11648);
   TESTCASE_AUTO(TestBenchmark);
@@ -577,11 +177,44 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
   TESTCASE_AUTO(TestFractionalDigitsForCurrency);
   TESTCASE_AUTO(TestFormatCurrencyPlural);
   TESTCASE_AUTO(Test11868);
+  TESTCASE_AUTO(Test11739_ParseLongCurrency);
+  //TESTCASE_AUTO(Test13035_MultiCodePointPaddingInPattern);
+  TESTCASE_AUTO(Test13737_ParseScientificStrict);
   TESTCASE_AUTO(Test10727_RoundingZero);
   TESTCASE_AUTO(Test11376_getAndSetPositivePrefix);
   TESTCASE_AUTO(Test11475_signRecognition);
   TESTCASE_AUTO(Test11640_getAffixes);
   TESTCASE_AUTO(Test11649_toPatternWithMultiCurrency);
+  TESTCASE_AUTO(Test13327_numberingSystemBufferOverflow);
+  TESTCASE_AUTO(Test13391_chakmaParsing);
+  TESTCASE_AUTO(Test11735_ExceptionIssue);
+  TESTCASE_AUTO(Test11035_FormatCurrencyAmount);
+  TESTCASE_AUTO(Test11318_DoubleConversion);
+  TESTCASE_AUTO(TestParsePercentRegression);
+  TESTCASE_AUTO(TestMultiplierWithScale);
+  TESTCASE_AUTO(TestFastFormatInt32);
+  TESTCASE_AUTO(Test11646_Equality);
+  TESTCASE_AUTO(TestParseNaN);
+  TESTCASE_AUTO(Test11897_LocalizedPatternSeparator);
+  TESTCASE_AUTO(Test13055_PercentageRounding);
+  TESTCASE_AUTO(Test11839);
+  TESTCASE_AUTO(Test10354);
+  TESTCASE_AUTO(Test11645_ApplyPatternEquality);
+  TESTCASE_AUTO(Test12567);
+  TESTCASE_AUTO(Test11626_CustomizeCurrencyPluralInfo);
+  TESTCASE_AUTO(Test13056_GroupingSize);
+  TESTCASE_AUTO(Test11025_CurrencyPadding);
+  TESTCASE_AUTO(Test11648_ExpDecFormatMalPattern);
+  //TESTCASE_AUTO(Test11649_DecFmtCurrencies);
+  TESTCASE_AUTO(Test13148_ParseGroupingSeparators);
+  TESTCASE_AUTO(Test12753_PatternDecimalPoint);
+  TESTCASE_AUTO(Test11647_PatternCurrencySymbols);
+  TESTCASE_AUTO(Test11913_BigDecimal);
+  TESTCASE_AUTO(Test11020_RoundingInScientificNotation);
+  TESTCASE_AUTO(Test11640_TripleCurrencySymbol);
+  TESTCASE_AUTO(Test13763_FieldPositionIteratorOffset);
+  TESTCASE_AUTO(Test13777_ParseLongNameNonCurrencyMode);
+  TESTCASE_AUTO(Test13804_EmptyStringsWhenParsing);
   TESTCASE_AUTO_END;
 }
 
@@ -599,10 +232,10 @@ NumberFormatTest::TestAPI(void)
   }
   if(test != NULL) {
     test->setMinimumIntegerDigits(10);
-    test->setMaximumIntegerDigits(2);
+    test->setMaximumIntegerDigits(1);
 
     test->setMinimumFractionDigits(10);
-    test->setMaximumFractionDigits(2);
+    test->setMaximumFractionDigits(1);
 
     UnicodeString result;
     FieldPosition pos;
@@ -617,9 +250,14 @@ NumberFormatTest::TestAPI(void)
     result.remove();
     int64_t ll = 12;
     test->format(ll, result);
-    if (result != "12.00"){
-        errln("format int64_t error");
-    }
+    assertEquals("format int64_t error", u"2.0", result);
+
+    test->setMinimumIntegerDigits(4);
+    test->setMinimumFractionDigits(4);
+
+    result.remove();
+    test->format(ll, result);
+    assertEquals("format int64_t error", u"0,012.0000", result);
 
     ParsePosition ppos;
     LocalPointer<CurrencyAmount> currAmt(test->parseCurrency("",ppos));
@@ -671,6 +309,58 @@ NumberFormatTest::TestCoverage(void){
     };
 }
 
+void NumberFormatTest::TestLocalizedPatternSymbolCoverage() {
+    IcuTestErrorCode errorCode(*this, "TestLocalizedPatternSymbolCoverage");
+    // Ticket #12961: DecimalFormat::toLocalizedPattern() is not working as designed.
+    DecimalFormatSymbols dfs(errorCode);
+    dfs.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, u'⁖');
+    dfs.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u'⁘');
+    dfs.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, u'⁙');
+    dfs.setSymbol(DecimalFormatSymbols::kDigitSymbol, u'▰');
+    dfs.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, u'໐');
+    dfs.setSymbol(DecimalFormatSymbols::kSignificantDigitSymbol, u'⁕');
+    dfs.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, u'†');
+    dfs.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, u'‡');
+    dfs.setSymbol(DecimalFormatSymbols::kPercentSymbol, u'⁜');
+    dfs.setSymbol(DecimalFormatSymbols::kPerMillSymbol, u'‱');
+    dfs.setSymbol(DecimalFormatSymbols::kExponentialSymbol, u"⁑⁑"); // tests multi-char sequence
+    dfs.setSymbol(DecimalFormatSymbols::kPadEscapeSymbol, u'⁂');
+
+    {
+        UnicodeString standardPattern(u"#,##0.05+%;#,##0.05-%");
+        UnicodeString localizedPattern(u"▰⁖▰▰໐⁘໐໕†⁜⁙▰⁖▰▰໐⁘໐໕‡⁜");
+
+        DecimalFormat df1("#", new DecimalFormatSymbols(dfs), errorCode);
+        df1.applyPattern(standardPattern, errorCode);
+        DecimalFormat df2("#", new DecimalFormatSymbols(dfs), errorCode);
+        df2.applyLocalizedPattern(localizedPattern, errorCode);
+        assertTrue("DecimalFormat instances should be equal", df1 == df2);
+        UnicodeString p2;
+        assertEquals("toPattern should match on localizedPattern instance",
+                standardPattern, df2.toPattern(p2));
+        UnicodeString lp1;
+        assertEquals("toLocalizedPattern should match on standardPattern instance",
+                localizedPattern, df1.toLocalizedPattern(lp1));
+    }
+
+    {
+        UnicodeString standardPattern(u"* @@@E0‰");
+        UnicodeString localizedPattern(u"⁂ ⁕⁕⁕⁑⁑໐‱");
+
+        DecimalFormat df1("#", new DecimalFormatSymbols(dfs), errorCode);
+        df1.applyPattern(standardPattern, errorCode);
+        DecimalFormat df2("#", new DecimalFormatSymbols(dfs), errorCode);
+        df2.applyLocalizedPattern(localizedPattern, errorCode);
+        assertTrue("DecimalFormat instances should be equal", df1 == df2);
+        UnicodeString p2;
+        assertEquals("toPattern should match on localizedPattern instance",
+                standardPattern, df2.toPattern(p2));
+        UnicodeString lp1;
+        assertEquals("toLocalizedPattern should match on standardPattern instance",
+                localizedPattern, df1.toLocalizedPattern(lp1));
+    }
+}
+
 // Test various patterns
 void
 NumberFormatTest::TestPatterns(void)
@@ -681,7 +371,7 @@ NumberFormatTest::TestPatterns(void)
 
     const char* pat[]    = { "#.#", "#.", ".#", "#" };
     int32_t pat_length = UPRV_LENGTHOF(pat);
-    const char* newpat[] = { "#0.#", "#0.", "#.0", "#" };
+    const char* newpat[] = { "#0.#", "#0.", "#.0", "#" }; // use ICU 61 behavior
     const char* num[]    = { "0",   "0.", ".0", "0" };
     for (int32_t i=0; i<pat_length; ++i)
     {
@@ -855,7 +545,7 @@ NumberFormatTest::TestExponential(void)
 #endif
             }
             else {
-                errln((UnicodeString)"FAIL: Non-numeric Formattable returned");
+                errln(UnicodeString("FAIL: Non-numeric Formattable returned: ") + pattern + " " + s);
                 continue;
             }
             if (pos.getIndex() == s.length())
@@ -866,7 +556,8 @@ NumberFormatTest::TestExponential(void)
                     (uprv_fabs(a - valParse[v+ival]) / a > (2*DBL_EPSILON))) ||
                     (!useEpsilon && a != valParse[v+ival]))
                 {
-                    errln((UnicodeString)"FAIL: Expected " + valParse[v+ival]);
+                    errln((UnicodeString)"FAIL: Expected " + valParse[v+ival] + " but got " + a
+                        + " on input " + s);
                 }
             }
             else {
@@ -893,7 +584,7 @@ NumberFormatTest::TestExponential(void)
                 {
                     logln((UnicodeString)"  -parse-> " + a);
                     if (a != lvalParse[v+ilval])
-                        errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval]);
+                        errln((UnicodeString)"FAIL: Expected " + lvalParse[v+ilval] + " but got " + a);
                 }
                 else
                     errln((UnicodeString)"FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
@@ -929,7 +620,7 @@ NumberFormatTest::TestScientificGrouping() {
     // jb 2552
     UErrorCode status = U_ZERO_ERROR;
     DecimalFormat fmt("##0.00E0",status);
-    if (U_SUCCESS(status)) {
+    if (assertSuccess("", status, true, __FILE__, __LINE__)) {
         expect(fmt, .01234, "12.3E-3");
         expect(fmt, .1234, "123E-3");
         expect(fmt, 1.234, "1.23E0");
@@ -1189,7 +880,7 @@ NumberFormatTest::TestCurrency(void)
     UnicodeString s; currencyFmt->format(1.50, s);
     logln((UnicodeString)"Un pauvre ici a..........." + s);
     if (!(s==CharsToUnicodeString("1,50\\u00A0$")))
-        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>$");
+        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>$ but got " + s);
     delete currencyFmt;
     s.truncate(0);
     char loc[256]={0};
@@ -1199,7 +890,7 @@ NumberFormatTest::TestCurrency(void)
     currencyFmt->format(1.50, s);
     logln((UnicodeString)"Un pauvre en Allemagne a.." + s);
     if (!(s==CharsToUnicodeString("1,50\\u00A0DM")))
-        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>DM");
+        errln((UnicodeString)"FAIL: Expected 1,50<nbsp>DM but got " + s);
     delete currencyFmt;
     s.truncate(0);
     len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status);
@@ -1265,7 +956,7 @@ void NumberFormatTest::TestCurrencyObject() {
                    1234.56, CharsToUnicodeString("\\u00A51,235")); // Yen
 
     expectCurrency(*fmt, Locale("fr", "CH", ""),
-                   1234.56, "CHF1,234.56"); // no more 0.05 rounding here, see cldrbug 5548
+                   1234.56, "CHF1,234.56"); // no more 0.05 rounding here, see cldrbug 5548 // use ICU 61 behavior
 
     expectCurrency(*fmt, Locale::getUS(),
                    1234.56, "$1,234.56");
@@ -1332,7 +1023,7 @@ static const char *lenientAffixTestCases[] = {
 static const char *lenientMinusTestCases[] = {
     "-5",
     "\\u22125",
-    "\\u20105"
+    "\\u27965"
 };
 
 static const char *lenientCurrencyTestCases[] = {
@@ -1408,7 +1099,8 @@ NumberFormatTest::TestLenientParse(void)
 
             if (U_FAILURE(status) || n.getType() != Formattable::kLong ||
                n.getLong() != 1) {
-               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientAffixTestCases[t] + (UnicodeString) "\"");
+               dataerrln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientAffixTestCases[t]
+                      + (UnicodeString) "\"; error code = " + u_errorName(status));
                status = U_ZERO_ERROR;
             }
        }
@@ -1417,47 +1109,49 @@ NumberFormatTest::TestLenientParse(void)
 
     Locale en_US("en_US");
     Locale sv_SE("sv_SE");
-    
+
     NumberFormat *mFormat = NumberFormat::createInstance(sv_SE, UNUM_DECIMAL, status);
-    
+
     if (mFormat == NULL || U_FAILURE(status)) {
         dataerrln("Unable to create NumberFormat (sv_SE, UNUM_DECIMAL) - %s", u_errorName(status));
     } else {
         mFormat->setLenient(TRUE);
         for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) {
             UnicodeString testCase = ctou(lenientMinusTestCases[t]);
-            
+
             mFormat->parse(testCase, n, status);
             logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
-            
+
             if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
-                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\"");
+                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t]
+                      + (UnicodeString) "\"; error code = " + u_errorName(status));
                 status = U_ZERO_ERROR;
             }
         }
         delete mFormat;
     }
-    
+
     mFormat = NumberFormat::createInstance(en_US, UNUM_DECIMAL, status);
-    
+
     if (mFormat == NULL || U_FAILURE(status)) {
         dataerrln("Unable to create NumberFormat (en_US, UNUM_DECIMAL) - %s", u_errorName(status));
     } else {
         mFormat->setLenient(TRUE);
         for (int32_t t = 0; t < UPRV_LENGTHOF(lenientMinusTestCases); t += 1) {
             UnicodeString testCase = ctou(lenientMinusTestCases[t]);
-            
+
             mFormat->parse(testCase, n, status);
             logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
-            
+
             if (U_FAILURE(status) || n.getType() != Formattable::kLong || n.getLong() != -5) {
-                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t] + (UnicodeString) "\"");
+                errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientMinusTestCases[t]
+                      + (UnicodeString) "\"; error code = " + u_errorName(status));
                 status = U_ZERO_ERROR;
             }
         }
         delete mFormat;
     }
-    
+
     NumberFormat *cFormat = NumberFormat::createInstance(en_US, UNUM_CURRENCY, status);
 
     if (cFormat == NULL || U_FAILURE(status)) {
@@ -1472,7 +1166,8 @@ NumberFormatTest::TestLenientParse(void)
 
             if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
                n.getLong() != 1000) {
-               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientCurrencyTestCases[t] + (UnicodeString) "\"");
+               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientCurrencyTestCases[t]
+                      + (UnicodeString) "\"; error code = " + u_errorName(status));
                status = U_ZERO_ERROR;
             }
         }
@@ -1485,7 +1180,8 @@ NumberFormatTest::TestLenientParse(void)
 
             if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
                n.getLong() != -1000) {
-               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativeCurrencyTestCases[t] + (UnicodeString) "\"");
+               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativeCurrencyTestCases[t]
+                      + (UnicodeString) "\"; error code = " + u_errorName(status));
                status = U_ZERO_ERROR;
             }
         }
@@ -1507,7 +1203,9 @@ NumberFormatTest::TestLenientParse(void)
 
             if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
                n.getDouble() != 0.25) {
-               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientPercentTestCases[t] + (UnicodeString) "\"");
+               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientPercentTestCases[t]
+                      + (UnicodeString) "\"; error code = " + u_errorName(status)
+                      + "; got: " + n.getDouble(status));
                status = U_ZERO_ERROR;
             }
         }
@@ -1520,7 +1218,9 @@ NumberFormatTest::TestLenientParse(void)
 
             if (U_FAILURE(status) ||n.getType() != Formattable::kDouble ||
                n.getDouble() != -0.25) {
-               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativePercentTestCases[t] + (UnicodeString) "\"");
+               errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) lenientNegativePercentTestCases[t]
+                      + (UnicodeString) "\"; error code = " + u_errorName(status)
+                      + "; got: " + n.getDouble(status));
                status = U_ZERO_ERROR;
             }
         }
@@ -1531,10 +1231,10 @@ NumberFormatTest::TestLenientParse(void)
    // Test cases that should fail with a strict parse and pass with a
    // lenient parse.
    NumberFormat *nFormat = NumberFormat::createInstance(en_US, status);
-    
+
    if (nFormat == NULL || U_FAILURE(status)) {
        dataerrln("Unable to create NumberFormat (en_US) - %s", u_errorName(status));
-   } else { 
+   } else {
        // first, make sure that they fail with a strict parse
        for (int32_t t = 0; t < UPRV_LENGTHOF(strictFailureTestCases); t += 1) {
               UnicodeString testCase = ctou(strictFailureTestCases[t]);
@@ -1543,7 +1243,8 @@ NumberFormatTest::TestLenientParse(void)
               logln((UnicodeString)"parse(" + testCase + ") = " + n.getLong());
 
               if (! U_FAILURE(status)) {
-                      errln((UnicodeString)"Strict Parse succeeded for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\"");
+                      errln((UnicodeString)"Strict Parse succeeded for \"" + (UnicodeString) strictFailureTestCases[t]
+                     + (UnicodeString) "\"; error code = " + u_errorName(status));
               }
 
               status = U_ZERO_ERROR;
@@ -1559,7 +1260,8 @@ NumberFormatTest::TestLenientParse(void)
 
               if (U_FAILURE(status) ||n.getType() != Formattable::kLong ||
                        n.getLong() != 1000) {
-                      errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) strictFailureTestCases[t] + (UnicodeString) "\"");
+                      errln((UnicodeString)"Lenient parse failed for \"" + (UnicodeString) strictFailureTestCases[t]
+                     + (UnicodeString) "\"; error code = " + u_errorName(status));
                       status = U_ZERO_ERROR;
               }
        }
@@ -1606,13 +1308,13 @@ void NumberFormatTest::TestSecondaryGrouping(void) {
     CHECK(status, "DecimalFormat ct");
 
     expect2(f, (int32_t)123456789L, "12,34,56,789");
-    expectPat(f, "#,##,###");
+    expectPat(f, "#,##,###"); // use ICU 61 behavior
     f.applyPattern("#,###", status);
     CHECK(status, "applyPattern");
 
     f.setSecondaryGroupingSize(4);
     expect2(f, (int32_t)123456789L, "12,3456,789");
-    expectPat(f, "#,####,###");
+    expectPat(f, "#,####,###"); // use ICU 61 behavior
     NumberFormat *g = NumberFormat::createInstance(Locale("hi", "IN"), status);
     CHECK_DATA(status, "createInstance(hi_IN)");
 
@@ -1664,6 +1366,8 @@ void NumberFormatTest::TestWhiteSpaceParsing(void) {
         errcheckln(ec, "FAIL: Constructor - %s", u_errorName(ec));
         return;
     }
+    // From ICU 62, flexible whitespace needs lenient mode
+    fmt.setLenient(TRUE);
     int32_t n = 1234;
     expect(fmt, "a b1234c ", n);
     expect(fmt, "a   b1234c   ", n);
@@ -1734,7 +1438,7 @@ void NumberFormatTest::TestScientific(void) {
     int32_t PAT_length = UPRV_LENGTHOF(PAT);
     int32_t DIGITS[] = {
         // min int, max int, min frac, max frac
-        0, 1, 0, 0, // "#E0"
+        0, 1, 0, 0, // "#E0" // expect ICU 61 behavior
         1, 1, 0, 4, // "0.####E0"
         2, 2, 3, 3, // "00.000E00"
         1, 3, 0, 4, // "##0.####E000"
@@ -2077,7 +1781,7 @@ void NumberFormatTest::TestPatterns2(void) {
 
     fmt.setFormatWidth(16);
     //              12  34567890123456
-    expectPat(fmt, "AA*^#,###,##0.00ZZ");
+    expectPat(fmt, "AA*^#,###,##0.00ZZ"); // use ICU 61 behavior
 }
 
 void NumberFormatTest::TestSurrogateSupport(void) {
@@ -2270,30 +1974,54 @@ void NumberFormatTest::TestCurrencyNames(void) {
     const UBool possibleDataError = TRUE;
     // Warning: HARD-CODED LOCALE DATA in this test.  If it fails, CHECK
     // THE LOCALE DATA before diving into the code.
-    assertEquals("USD.getName(SYMBOL_NAME)",
+    assertEquals("USD.getName(SYMBOL_NAME, en)",
                  UnicodeString("$"),
                  UnicodeString(ucurr_getName(USD, "en",
                                              UCURR_SYMBOL_NAME,
                                              &isChoiceFormat, &len, &ec)),
                                              possibleDataError);
-    assertEquals("USD.getName(LONG_NAME)",
+    assertEquals("USD.getName(NARROW_SYMBOL_NAME, en)",
+                 UnicodeString("$"),
+                 UnicodeString(ucurr_getName(USD, "en",
+                                             UCURR_NARROW_SYMBOL_NAME,
+                                             &isChoiceFormat, &len, &ec)),
+                                             possibleDataError);
+    assertEquals("USD.getName(LONG_NAME, en)",
                  UnicodeString("US Dollar"),
                  UnicodeString(ucurr_getName(USD, "en",
                                              UCURR_LONG_NAME,
                                              &isChoiceFormat, &len, &ec)),
                                              possibleDataError);
-    assertEquals("CAD.getName(SYMBOL_NAME)",
+    assertEquals("CAD.getName(SYMBOL_NAME, en)",
                  UnicodeString("CA$"),
                  UnicodeString(ucurr_getName(CAD, "en",
                                              UCURR_SYMBOL_NAME,
                                              &isChoiceFormat, &len, &ec)),
                                              possibleDataError);
-    assertEquals("CAD.getName(SYMBOL_NAME)",
+    assertEquals("CAD.getName(NARROW_SYMBOL_NAME, en)",
+                 UnicodeString("$"),
+                 UnicodeString(ucurr_getName(CAD, "en",
+                                             UCURR_NARROW_SYMBOL_NAME,
+                                             &isChoiceFormat, &len, &ec)),
+                                             possibleDataError);
+    assertEquals("CAD.getName(SYMBOL_NAME, en_CA)",
                  UnicodeString("$"),
                  UnicodeString(ucurr_getName(CAD, "en_CA",
                                              UCURR_SYMBOL_NAME,
                                              &isChoiceFormat, &len, &ec)),
                                              possibleDataError);
+    assertEquals("USD.getName(SYMBOL_NAME, en_CA)",
+                 UnicodeString("US$"),
+                 UnicodeString(ucurr_getName(USD, "en_CA",
+                                             UCURR_SYMBOL_NAME,
+                                             &isChoiceFormat, &len, &ec)),
+                                             possibleDataError);
+    assertEquals("USD.getName(NARROW_SYMBOL_NAME, en_CA)",
+                 UnicodeString("$"),
+                 UnicodeString(ucurr_getName(USD, "en_CA",
+                                             UCURR_NARROW_SYMBOL_NAME,
+                                             &isChoiceFormat, &len, &ec)),
+                                             possibleDataError);
     assertEquals("USD.getName(SYMBOL_NAME) in en_NZ",
                  UnicodeString("US$"),
                  UnicodeString(ucurr_getName(USD, "en_NZ",
@@ -2306,6 +2034,18 @@ void NumberFormatTest::TestCurrencyNames(void) {
                                              UCURR_SYMBOL_NAME,
                                              &isChoiceFormat, &len, &ec)),
                                              possibleDataError);
+    assertEquals("USX.getName(SYMBOL_NAME)",
+                 UnicodeString("USX"),
+                 UnicodeString(ucurr_getName(USX, "en_US",
+                                             UCURR_SYMBOL_NAME,
+                                             &isChoiceFormat, &len, &ec)),
+                                             possibleDataError);
+    assertEquals("USX.getName(NARROW_SYMBOL_NAME)",
+                 UnicodeString("USX"),
+                 UnicodeString(ucurr_getName(USX, "en_US",
+                                             UCURR_NARROW_SYMBOL_NAME,
+                                             &isChoiceFormat, &len, &ec)),
+                                             possibleDataError);
     assertEquals("USX.getName(LONG_NAME)",
                  UnicodeString("USX"),
                  UnicodeString(ucurr_getName(USX, "en_US",
@@ -2348,14 +2088,17 @@ void NumberFormatTest::TestCurrencyNames(void) {
 
 void NumberFormatTest::TestCurrencyUnit(void){
     UErrorCode ec = U_ZERO_ERROR;
-    static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
-    static const UChar BAD[] = {63, 63, 63, 0}; /*???*/
-    static const UChar BAD2[] = {63, 63, 65, 0}; /*???*/
+    static const UChar USD[]  = u"USD";
+    static const char USD8[]  =  "USD";
+    static const UChar BAD[]  = u"???";
+    static const UChar BAD2[] = u"??A";
+    static const UChar XXX[]  = u"XXX";
+    static const char XXX8[]  =  "XXX";
     CurrencyUnit cu(USD, ec);
     assertSuccess("CurrencyUnit", ec);
 
-    const UChar * r = cu.getISOCurrency(); // who is the buffer owner ?
-    assertEquals("getISOCurrency()", USD, r);
+    assertEquals("getISOCurrency()", USD, cu.getISOCurrency());
+    assertEquals("getSubtype()", USD8, cu.getSubtype());
 
     CurrencyUnit cu2(cu);
     if (!(cu2 == cu)){
@@ -2384,6 +2127,31 @@ void NumberFormatTest::TestCurrencyUnit(void){
         errln("Currency unit assignment should be the same.");
     }
     delete cu3;
+
+    // Test default constructor
+    CurrencyUnit def;
+    assertEquals("Default currency", XXX, def.getISOCurrency());
+    assertEquals("Default currency as subtype", XXX8, def.getSubtype());
+
+    // Test slicing
+    MeasureUnit sliced1 = cu;
+    MeasureUnit sliced2 = cu;
+    assertEquals("Subtype after slicing 1", USD8, sliced1.getSubtype());
+    assertEquals("Subtype after slicing 2", USD8, sliced2.getSubtype());
+    CurrencyUnit restored1(sliced1, ec);
+    CurrencyUnit restored2(sliced2, ec);
+    assertSuccess("Restoring from MeasureUnit", ec);
+    assertEquals("Subtype after restoring 1", USD8, restored1.getSubtype());
+    assertEquals("Subtype after restoring 2", USD8, restored2.getSubtype());
+    assertEquals("ISO Code after restoring 1", USD, restored1.getISOCurrency());
+    assertEquals("ISO Code after restoring 2", USD, restored2.getISOCurrency());
+
+    // Test copy constructor failure
+    LocalPointer<MeasureUnit> meter(MeasureUnit::createMeter(ec));
+    assertSuccess("Creating meter", ec);
+    CurrencyUnit failure(*meter, ec);
+    assertEquals("Copying from meter should fail", ec, U_ILLEGAL_ARGUMENT_ERROR);
+    assertEquals("Copying should not give uninitialized ISO code", u"", failure.getISOCurrency());
 }
 
 void NumberFormatTest::TestCurrencyAmount(void){
@@ -2428,7 +2196,7 @@ void NumberFormatTest::TestSymbolsWithBadLocale(void) {
         UnicodeString intlCurrencySymbol((UChar)0xa4);
 
         intlCurrencySymbol.append((UChar)0xa4);
-        
+
         logln("Current locale is %s", Locale::getDefault().getName());
         Locale::setDefault(locBad, status);
         logln("Current locale is %s", Locale::getDefault().getName());
@@ -2538,11 +2306,17 @@ void NumberFormatTest::TestPerMill() {
     DecimalFormat fmt(ctou("###.###\\u2030"), ec);
     if (!assertSuccess("DecimalFormat ct", ec)) return;
     assertEquals("0.4857 x ###.###\\u2030",
-                 ctou("485.7\\u2030"), fmt.format(0.4857, str));
+                 ctou("485.7\\u2030"), fmt.format(0.4857, str), true);
 
     DecimalFormatSymbols sym(Locale::getUS(), ec);
+    if (!assertSuccess("", ec, true, __FILE__, __LINE__)) {
+        return;
+    }
     sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, ctou("m"));
     DecimalFormat fmt2("", sym, ec);
+    if (!assertSuccess("", ec, true, __FILE__, __LINE__)) {
+        return;
+    }
     fmt2.applyLocalizedPattern("###.###m", ec);
     if (!assertSuccess("setup", ec)) return;
     str.truncate(0);
@@ -3139,7 +2913,7 @@ void NumberFormatTest::TestCompatibleCurrencies() {
     expectParseCurrency(*fmtJP, JPY, 1235,  "\\u00A51,235");
     logln("%s:%d - testing parse of fullwidth yen sign in JP\n", __FILE__, __LINE__);
     expectParseCurrency(*fmtJP, JPY, 1235,  "\\uFFE51,235");
-    
+
     // more..
 */
 }
@@ -3159,7 +2933,7 @@ void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar*
             fmt.getLocale(ULOC_ACTUAL_LOCALE, status).getBaseName(),
             text);
     u_austrcpy(theInfo+uprv_strlen(theInfo), currency);
-    
+
     char theOperation[100];
 
     uprv_strcpy(theOperation, theInfo);
@@ -3170,7 +2944,7 @@ void NumberFormatTest::expectParseCurrency(const NumberFormat &fmt, const UChar*
     uprv_strcat(theOperation, ", check currency:");
     assertEquals(theOperation, currency, currencyAmount->getISOCurrency());
 }
-  
+
 
 void NumberFormatTest::TestJB3832(){
     const char* localeID = "pt_PT@currency=PTE";
@@ -3549,6 +3323,7 @@ NumberFormatTest::TestSpaceParsing() {
         foo->setLenient(DATA[i].lenient);
         Formattable result;
         foo->parse(stringToBeParsed, result, parsePosition);
+        logln("Parsing: " + stringToBeParsed);
         if (parsePosition.getIndex() != parsedPosition ||
             parsePosition.getErrorIndex() != errorIndex) {
             errln("FAILED parse " + stringToBeParsed + "; lenient: " + DATA[i].lenient + "; wrong position, expected: (" + parsedPosition + ", " + errorIndex + "); got (" + parsePosition.getIndex() + ", " + parsePosition.getErrorIndex() + ")");
@@ -3607,7 +3382,7 @@ void NumberFormatTest::TestNumberingSystems() {
         NumberFormat *fmt = (NumberFormat *) origFmt->clone();
         delete origFmt;
 
-        
+
         if (item->isRBNF) {
             expect3(*fmt,item->value,CharsToUnicodeString(item->expectedResult));
         } else {
@@ -3753,7 +3528,7 @@ NumberFormatTest::TestCurrencyFormatForMixParsing() {
         "$1,234.56",  // string to be parsed
         "USD1,234.56",
         "US dollars1,234.56",
-        "1,234.56 US dollars"
+        // "1,234.56 US dollars" // Fails in 62 because currency format is not compatible with pattern.
     };
     const CurrencyAmount* curramt = NULL;
     for (uint32_t i = 0; i < UPRV_LENGTHOF(formats); ++i) {
@@ -3782,6 +3557,40 @@ NumberFormatTest::TestCurrencyFormatForMixParsing() {
 }
 
 
+/** Starting in ICU 62, strict mode is actually strict with currency formats. */
+void NumberFormatTest::TestMismatchedCurrencyFormatFail() {
+    IcuTestErrorCode status(*this, "TestMismatchedCurrencyFormatFail");
+    LocalPointer<DecimalFormat> df(
+            dynamic_cast<DecimalFormat*>(DecimalFormat::createCurrencyInstance("en", status)), status);
+    if (!assertSuccess("createCurrencyInstance() failed.", status, true, __FILE__, __LINE__)) {return;}
+    UnicodeString pattern;
+    assertEquals("Test assumes that currency sign is at the beginning",
+            u"\u00A4#,##0.00",
+            df->toPattern(pattern));
+    // Should round-trip on the correct currency format:
+    expect2(*df, 1.23, u"XXX\u00A01.23");
+    df->setCurrency(u"EUR", status);
+    expect2(*df, 1.23, u"\u20AC1.23");
+    // Should parse with currency in the wrong place in lenient mode
+    df->setLenient(TRUE);
+    expect(*df, u"1.23\u20AC", 1.23);
+    expectParseCurrency(*df, u"EUR", 1.23, "1.23\\u20AC");
+    // Should NOT parse with currency in the wrong place in STRICT mode
+    df->setLenient(FALSE);
+    {
+        Formattable result;
+        ErrorCode failStatus;
+        df->parse(u"1.23\u20AC", result, failStatus);
+        assertEquals("Should fail to parse", U_INVALID_FORMAT_ERROR, failStatus);
+    }
+    {
+        ParsePosition ppos;
+        df->parseCurrency(u"1.23\u20AC", ppos);
+        assertEquals("Should fail to parse currency", 0, ppos.getIndex());
+    }
+}
+
+
 void
 NumberFormatTest::TestDecimalFormatCurrencyParse() {
     // Locale.US
@@ -3811,12 +3620,15 @@ NumberFormatTest::TestDecimalFormatCurrencyParse() {
         {"USD1,234.56", "1234.56"},
         {"1,234.56 US dollar", "1234.56"},
     };
+    // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
+    fmt->setLenient(TRUE);
     for (uint32_t i = 0; i < UPRV_LENGTHOF(DATA); ++i) {
         UnicodeString stringToBeParsed = ctou(DATA[i][0]);
         double parsedResult = atof(DATA[i][1]);
         UErrorCode status = U_ZERO_ERROR;
         Formattable result;
         fmt->parse(stringToBeParsed, result, status);
+        logln((UnicodeString)"Input: " + stringToBeParsed + "; output: " + result.getDouble(status));
         if (U_FAILURE(status) ||
             (result.getType() == Formattable::kDouble &&
             result.getDouble() != parsedResult) ||
@@ -3862,12 +3674,14 @@ NumberFormatTest::TestCurrencyIsoPluralFormat() {
     };
 
     for (int32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
+      const char* localeString = DATA[i][0];
+      double numberToBeFormat = atof(DATA[i][1]);
+      const char* currencyISOCode = DATA[i][2];
+      logln(UnicodeString(u"Locale: ") + localeString + "; amount: " + numberToBeFormat);
+      Locale locale(localeString);
       for (int32_t kIndex = 0; kIndex < UPRV_LENGTHOF(currencyStyles); ++kIndex) {
         UNumberFormatStyle k = currencyStyles[kIndex];
-        const char* localeString = DATA[i][0];
-        double numberToBeFormat = atof(DATA[i][1]);
-        const char* currencyISOCode = DATA[i][2];
-        Locale locale(localeString);
+        logln(UnicodeString(u"UNumberFormatStyle: ") + k);
         UErrorCode status = U_ZERO_ERROR;
         NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
         if (U_FAILURE(status)) {
@@ -3894,6 +3708,8 @@ NumberFormatTest::TestCurrencyIsoPluralFormat() {
             errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
         }
         // test parsing, and test parsing for all currency formats.
+        // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
+        numFmt->setLenient(TRUE);
         for (int j = 3; j < 6; ++j) {
             // DATA[i][3] is the currency format result using
             // CURRENCYSTYLE formatter.
@@ -3934,24 +3750,25 @@ NumberFormatTest::TestCurrencyParsing() {
         // format result using CURRENCYSTYLE,
         // format result using ISOCURRENCYSTYLE,
         // format result using PLURALCURRENCYSTYLE,
-        {"en_US", "1", "USD", "$1.00", "USD1.00", "1.00 US dollar"},
+        {"en_US", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00 US dollars"},
         {"pa_IN", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\u0a2f\\u0a42.\\u0a10\\u0a38. \\u0a21\\u0a3e\\u0a32\\u0a30"},
         {"es_AR", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 d\\u00f3lar estadounidense"},
         {"ar_EG", "1", "USD", "\\u0661\\u066b\\u0660\\u0660\\u00a0US$", "\\u0661\\u066b\\u0660\\u0660\\u00a0USD", "\\u0661\\u066b\\u0660\\u0660 \\u062f\\u0648\\u0644\\u0627\\u0631 \\u0623\\u0645\\u0631\\u064a\\u0643\\u064a"},
-        {"fa_CA", "1", "USD", "\\u06f1\\u066b\\u06f0\\u06f0\\u00a0\\u061c$", "\\u06f1\\u066b\\u06f0\\u06f0\\u00a0\\u061cUSD", "\\u06f1\\u066b\\u06f0\\u06f0 \\u062f\\u0644\\u0627\\u0631 \\u0627\\u0645\\u0631\\u06cc\\u06a9\\u0627"},
+        {"fa_CA", "1", "USD", "\\u200e$\\u06f1\\u066b\\u06f0\\u06f0", "\\u200eUSD\\u06f1\\u066b\\u06f0\\u06f0", "\\u06f1\\u066b\\u06f0\\u06f0 \\u062f\\u0644\\u0627\\u0631 \\u0627\\u0645\\u0631\\u06cc\\u06a9\\u0627"},
         {"he_IL", "1", "USD", "\\u200f1.00\\u00a0$", "\\u200f1.00\\u00a0USD", "1.00 \\u05d3\\u05d5\\u05dc\\u05e8 \\u05d0\\u05de\\u05e8\\u05d9\\u05e7\\u05d0\\u05d9"},
-        {"hr_HR", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 Ameri\\u010dki dolar"},
-        {"id_ID", "1", "USD", "US$1,00", "USD1,00", "1,00 Dolar Amerika Serikat"},
-        {"it_IT", "1", "USD", "1,00\\u00a0US$", "1,00\\u00a0USD", "1,00 Dollaro Statunitense"},
-        {"ko_KR", "1", "USD", "US$1.00", "USD1.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"},
-        {"ja_JP", "1", "USD", "$1.00", "USD1.00", "1.00\\u7c73\\u30c9\\u30eb"},
-        {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY01.00", "1.00\\u4EBA\\u6C11\\u5E01"},
-        {"zh_TW", "1", "CNY", "CN\\u00A51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"},
-        {"zh_Hant", "1", "CNY", "CN\\u00A51.00", "CNY1.00", "1.00 \\u4eba\\u6c11\\u5e63"},
-        {"zh_Hant", "1", "JPY", "\\u00A51.00", "JPY1.00", "1.00 \\u65e5\\u5713"},
-        {"ja_JP", "1", "JPY", "\\uFFE51.00", "JPY1.00", "1.00\\u65e5\\u672c\\u5186"},
-        {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY1.00", "1.00\\u65e5\\u672c\\u5186"},
-        {"ru_RU", "1", "RUB", "1,00\\u00A0\\u20BD", "1,00\\u00A0RUB", "1,00 \\u0420\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u0438\\u0439 \\u0440\\u0443\\u0431\\u043B\\u044C"}
+        {"hr_HR", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 ameri\\u010Dkih dolara"},
+        {"id_ID", "1", "USD", "US$\\u00A01,00", "USD\\u00A01,00", "1,00 Dolar Amerika Serikat"},
+        {"it_IT", "1", "USD", "1,00\\u00a0USD", "1,00\\u00a0USD", "1,00 dollari statunitensi"},
+        {"ko_KR", "1", "USD", "US$\\u00A01.00", "USD\\u00A01.00", "1.00 \\ubbf8\\uad6d \\ub2ec\\ub7ec"},
+        {"ja_JP", "1", "USD", "$1.00", "USD\\u00A01.00", "1.00\\u7c73\\u30c9\\u30eb"},
+        {"zh_CN", "1", "CNY", "\\uFFE51.00", "CNY\\u00A001.00", "1.00\\u4EBA\\u6C11\\u5E01"},
+        {"zh_TW", "1", "CNY", "CN\\u00A51.00", "CNY\\u00A01.00", "1.00 \\u4eba\\u6c11\\u5e63"},
+        {"zh_Hant", "1", "CNY", "CN\\u00A51.00", "CNY\\u00A01.00", "1.00 \\u4eba\\u6c11\\u5e63"},
+        {"zh_Hant", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1 \\u65E5\\u5713"},
+        {"ja_JP", "1", "JPY", "\\uFFE51.00", "JPY\\u00A01.00", "1\\u5186"},
+        // ICU 62 requires #parseCurrency() to recognize variants when parsing
+        // {"ja_JP", "1", "JPY", "\\u00A51.00", "JPY\\u00A01.00", "1\\u00A0\\u5186"},
+        {"ru_RU", "1", "RUB", "1,00\\u00A0\\u00A0\\u20BD", "1,00\\u00A0\\u00A0RUB", "1,00 \\u0440\\u043E\\u0441\\u0441\\u0438\\u0439\\u0441\\u043A\\u043E\\u0433\\u043E \\u0440\\u0443\\u0431\\u043B\\u044F"}
     };
     static const UNumberFormatStyle currencyStyles[] = {
         UNUM_CURRENCY,
@@ -3979,7 +3796,7 @@ for (;;) {
         UErrorCode status = U_ZERO_ERROR;
         NumberFormat* numFmt = NumberFormat::createInstance(locale, k, status);
         logln("#%d NumberFormat(%s, %s) Currency=%s\n",
-              i, localeString, currencyStyleNames[kIndex], 
+              i, localeString, currencyStyleNames[kIndex],
               currencyISOCode);
 
         if (U_FAILURE(status)) {
@@ -3998,7 +3815,6 @@ for (;;) {
 
         UnicodeString strBuf;
         numFmt->format(numberToBeFormat, strBuf);
-        /*
         int resultDataIndex = 3 + kIndex;
         // DATA[i][resultDataIndex] is the currency format result
         // using 'k' currency style.
@@ -4006,8 +3822,9 @@ for (;;) {
         if (strBuf.compare(formatResult)) {
             errln("FAIL: Expected " + formatResult + " actual: " + strBuf);
         }
-        */
         // test parsing, and test parsing for all currency formats.
+        // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
+        numFmt->setLenient(TRUE);
         for (int j = 3; j < 6; ++j) {
             // DATA[i][3] is the currency format result using
             // CURRENCYSTYLE formatter.
@@ -4886,9 +4703,9 @@ NumberFormatTest::TestParseCurrencyInUCurr() {
         "Peruvian soles1.00",
         "Peruvian sol (1863\\u20131965)1.00",
         "Peruvian soles (1863\\u20131965)1.00",
-        "Philippine Peso1.00",
-        "Philippine peso1.00",
-        "Philippine pesos1.00",
+        "Philippine Piso1.00",
+        "Philippine piso1.00",
+        "Philippine pisos1.00",
         "Platinum1.00",
         "Platinum1.00",
         "Polish Zloty (1950\\u20131995)1.00",
@@ -5823,9 +5640,9 @@ NumberFormatTest::TestParseCurrencyInUCurr() {
         "1.00 Peruvian soles random",
         "1.00 Peruvian sol (1863\\u20131965) random",
         "1.00 Peruvian soles (1863\\u20131965) random",
-        "1.00 Philippine Peso random",
-        "1.00 Philippine peso random",
-        "1.00 Philippine pesos random",
+        "1.00 Philippine Piso random",
+        "1.00 Philippine piso random",
+        "1.00 Philippine pisos random",
         "1.00 Platinum random",
         "1.00 Platinum random",
         "1.00 Polish Zloty (1950\\u20131995) random",
@@ -6591,26 +6408,24 @@ NumberFormatTest::TestParseCurrencyInUCurr() {
 
     Locale locale("en_US");
     for (uint32_t i=0; i<UPRV_LENGTHOF(DATA); ++i) {
-      UnicodeString formatted = ctou(DATA[i]);
-      UErrorCode status = U_ZERO_ERROR;
-      NumberFormat* numFmt = NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
-      if (numFmt != NULL && U_SUCCESS(status)) {
-          ParsePosition parsePos;
-          LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos));
-          if (parsePos.getIndex() > 0) {
-              double doubleVal = currAmt->getNumber().getDouble(status);
-              if ( doubleVal != 1.0 ) {
-                  errln("Parsed as currency value other than 1.0: " + formatted + " -> " + doubleVal);
-              }
-          } else {
-              errln("Failed to parse as currency: " + formatted);
-          }
-      } else {
-          dataerrln("Unable to create NumberFormat. - %s", u_errorName(status));
-          delete numFmt;
-          break;
-      }
-      delete numFmt;
+        UnicodeString formatted = ctou(DATA[i]);
+        UErrorCode status = U_ZERO_ERROR;
+        LocalPointer<NumberFormat> numFmt(NumberFormat::createInstance(locale, UNUM_CURRENCY, status), status);
+        if (!assertSuccess("", status, true, __FILE__, __LINE__)) {
+            return;
+        }
+        // NOTE: ICU 62 requires that the currency format match the pattern in strict mode.
+        numFmt->setLenient(TRUE);
+        ParsePosition parsePos;
+        LocalPointer<CurrencyAmount> currAmt(numFmt->parseCurrency(formatted, parsePos));
+        if (parsePos.getIndex() > 0) {
+            double doubleVal = currAmt->getNumber().getDouble(status);
+            if ( doubleVal != 1.0 ) {
+                errln("Parsed as currency value other than 1.0: " + formatted + " -> " + doubleVal);
+            }
+        } else {
+            errln("Failed to parse as currency: " + formatted);
+        }
     }
 
     for (uint32_t i=0; i<UPRV_LENGTHOF(WRONG_DATA); ++i) {
@@ -6737,7 +6552,7 @@ void NumberFormatTest::TestFormatAttributes() {
   DecimalFormat *decFmt = (DecimalFormat *) NumberFormat::createInstance(locale, UNUM_CURRENCY, status);
     if (failure(status, "NumberFormat::createInstance", TRUE)) return;
   double val = 12345.67;
-  
+
   {
     int32_t expected[] = {
       UNUM_CURRENCY_FIELD, 0, 1,
@@ -6822,18 +6637,14 @@ const char* attrString(int32_t attrId) {
 
 //
 //   Test formatting & parsing of big decimals.
-//      API test, not a comprehensive test. 
+//      API test, not a comprehensive test.
 //      See DecimalFormatTest/DataDrivenTests
 //
-#define ASSERT_SUCCESS(status) {if (U_FAILURE(status)) errln("file %s, line %d: status: %s", \
-                                                __FILE__, __LINE__, u_errorName(status));}
-#define ASSERT_EQUALS(expected, actual) {if ((expected) != (actual)) \
-                  errln("file %s, line %d: %s != %s", __FILE__, __LINE__, #expected, #actual);}
-
-static UBool operator != (const char *s1, UnicodeString &s2) {
-    // This function lets ASSERT_EQUALS("literal", UnicodeString) work.
-    UnicodeString us1(s1);
-    return us1 != s2;
+#define ASSERT_SUCCESS(status) { \
+    assertSuccess(UnicodeString("file ") + __FILE__ + ", line " + __LINE__, (status)); \
+}
+#define ASSERT_EQUALS(expected, actual) { \
+    assertEquals(UnicodeString("file ") + __FILE__ + ", line " + __LINE__, (expected), (actual)); \
 }
 
 void NumberFormatTest::TestDecimal() {
@@ -6843,7 +6654,7 @@ void NumberFormatTest::TestDecimal() {
         ASSERT_SUCCESS(status);
         StringPiece s = f.getDecimalNumber(status);
         ASSERT_SUCCESS(status);
-        ASSERT_EQUALS("1.2345678999987654321E+667", s);
+        ASSERT_EQUALS("1.2345678999987654321E+667", s.data());
         //printf("%s\n", s.data());
     }
 
@@ -6862,7 +6673,7 @@ void NumberFormatTest::TestDecimal() {
         ASSERT_EQUALS(123.45, f.getDouble());
         ASSERT_EQUALS(123.45, f.getDouble(status));
         ASSERT_SUCCESS(status);
-        ASSERT_EQUALS("123.45", f.getDecimalNumber(status));
+        ASSERT_EQUALS("123.45", f.getDecimalNumber(status).data());
         ASSERT_SUCCESS(status);
 
         f.setDecimalNumber("4.5678E7", status);
@@ -6877,7 +6688,7 @@ void NumberFormatTest::TestDecimal() {
         ASSERT_EQUALS(-123, f.getLong());
         ASSERT_EQUALS(-123, f.getLong(status));
         ASSERT_SUCCESS(status);
-        ASSERT_EQUALS("-123", f.getDecimalNumber(status));
+        ASSERT_EQUALS("-123", f.getDecimalNumber(status).data());
         ASSERT_SUCCESS(status);
 
         status = U_ZERO_ERROR;
@@ -6887,7 +6698,7 @@ void NumberFormatTest::TestDecimal() {
         ASSERT_EQUALS(1234567890123LL, f.getInt64());
         ASSERT_EQUALS(1234567890123LL, f.getInt64(status));
         ASSERT_SUCCESS(status);
-        ASSERT_EQUALS("1234567890123", f.getDecimalNumber(status));
+        ASSERT_EQUALS("1234567890123", f.getDecimalNumber(status).data());
         ASSERT_SUCCESS(status);
     }
 
@@ -6950,12 +6761,12 @@ void NumberFormatTest::TestDecimal() {
             Formattable result;
             fmtr->parse(input, result, status);
             ASSERT_SUCCESS(status);
-            ASSERT_EQUALS(0, strcmp("0.0184", result.getDecimalNumber(status).data()));
+            ASSERT_EQUALS("0.0184", result.getDecimalNumber(status).data());
             //std::cout << result.getDecimalNumber(status).data();
             delete fmtr;
         }
     }
-    
+
 #if U_PLATFORM != U_PF_CYGWIN || defined(CYGWINMSVC)
     /*
      * This test fails on Cygwin (1.7.16) using GCC because of a rounding issue with strtod().
@@ -7003,42 +6814,42 @@ void NumberFormatTest::TestCurrencyFractionDigits() {
             errln((UnicodeString)"NumberFormat::format() should return the same result - text1="
                 + text1 + " text2=" + text2);
         }
-        delete fmt;
     }
+    delete fmt;
 }
 
-void NumberFormatTest::TestExponentParse() { 
-    UErrorCode status = U_ZERO_ERROR; 
-    Formattable result; 
-    ParsePosition parsePos(0); 
-    // set the exponent symbol 
-    status = U_ZERO_ERROR; 
-    DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getDefault(), status); 
-    if(U_FAILURE(status)) { 
-        dataerrln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)"); 
-        return; 
-    } 
-    
-    // create format instance 
-    status = U_ZERO_ERROR; 
-    DecimalFormat fmt("#####", symbols, status); 
-    if(U_FAILURE(status)) { 
-        errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)"); 
-    } 
-    
-    // parse the text 
-    fmt.parse("5.06e-27", result, parsePos); 
-    if(result.getType() != Formattable::kDouble &&  
-       result.getDouble() != 5.06E-27 && 
-       parsePos.getIndex() != 8 
-       ) 
-    { 
-        errln("ERROR: parse failed - expected 5.06E-27, 8  - returned %d, %i", 
-              result.getDouble(), parsePos.getIndex()); 
-    } 
-} 
+void NumberFormatTest::TestExponentParse() {
+
+    UErrorCode status = U_ZERO_ERROR;
+    Formattable result;
+    ParsePosition parsePos(0);
+
+    // set the exponent symbol
+    status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols(Locale::getDefault(), status);
+    if(U_FAILURE(status)) {
+        dataerrln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)");
+        return;
+    }
+
+    // create format instance
+    status = U_ZERO_ERROR;
+    DecimalFormat fmt(u"#####", symbols, status);
+    if(U_FAILURE(status)) {
+        errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
+    }
+
+    // parse the text
+    fmt.parse("5.06e-27", result, parsePos);
+    if(result.getType() != Formattable::kDouble &&
+       result.getDouble() != 5.06E-27 &&
+       parsePos.getIndex() != 8
+       )
+    {
+        errln("ERROR: parse failed - expected 5.06E-27, 8  - returned %d, %i",
+              result.getDouble(), parsePos.getIndex());
+    }
+}
 
 void NumberFormatTest::TestExplicitParents() {
 
@@ -7121,13 +6932,13 @@ NumberFormatTest::Test9087(void)
 {
     U_STRING_DECL(pattern,"#",1);
     U_STRING_INIT(pattern,"#",1);
-    
+
     U_STRING_DECL(infstr,"INF",3);
     U_STRING_INIT(infstr,"INF",3);
 
     U_STRING_DECL(nanstr,"NAN",3);
     U_STRING_INIT(nanstr,"NAN",3);
-    
+
     UChar outputbuf[50] = {0};
     UErrorCode status = U_ZERO_ERROR;
     UNumberFormat* fmt = unum_open(UNUM_PATTERN_DECIMAL,pattern,1,NULL,NULL,&status);
@@ -7149,7 +6960,7 @@ NumberFormatTest::Test9087(void)
 
     UFieldPosition position = { 0, 0, 0};
     unum_formatDouble(fmt,inf,outputbuf,50,&position,&status);
-    
+
     if ( u_strcmp(infstr, outputbuf)) {
         errln((UnicodeString)"FAIL: unexpected result for infinity - expected " + infstr + " got " + outputbuf);
     }
@@ -7157,25 +6968,11 @@ NumberFormatTest::Test9087(void)
     unum_close(fmt);
 }
 
-#include "dcfmtimp.h"
-
 void NumberFormatTest::TestFormatFastpaths() {
-#if UCONFIG_FORMAT_FASTPATHS_49
-    logln("Sizeof DecimalFormat = %d, Sizeof DecimalFormatInternal=%d, UNUM_DECIMALFORMAT_INTERNAL_SIZE=%d\n",
-        sizeof(DecimalFormat), sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
-    if(UNUM_DECIMALFORMAT_INTERNAL_SIZE < sizeof(DecimalFormatInternal)) {
-        errln("Error: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is only %d. Increase the #define?\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
-    } else if(UNUM_DECIMALFORMAT_INTERNAL_SIZE > (sizeof(DecimalFormatInternal)+16)) {
-        infoln("Note: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is %d. Decrease the #define? sizeof(DecimalFormat)=%d\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE, sizeof(DecimalFormat));
-    }
-#else
-    infoln("NOTE: UCONFIG_FORMAT_FASTPATHS not set, test skipped.");
-#endif  
-
     // get some additional case
     {
         UErrorCode status=U_ZERO_ERROR;
-        DecimalFormat df(UnicodeString("0000",""),status);
+        DecimalFormat df(UnicodeString(u"0000"),status);
         if (U_FAILURE(status)) {
             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
         } else {
@@ -7185,15 +6982,16 @@ void NumberFormatTest::TestFormatFastpaths() {
             FieldPosition pos;
             df.format(long_number, result, pos);
             if(U_FAILURE(status)||expect!=result) {
-                errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),""));
-            } else {
+                dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s",
+                          __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
+             } else {
                 logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),""));
             }
         }
     }
     {
         UErrorCode status=U_ZERO_ERROR;
-        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
+        DecimalFormat df(UnicodeString(u"0000000000000000000"),status);
         if (U_FAILURE(status)) {
             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
         } else {
@@ -7208,7 +7006,8 @@ void NumberFormatTest::TestFormatFastpaths() {
             FieldPosition pos;
             df.format(long_number, result, pos);
             if(U_FAILURE(status)||expect!=result) {
-                errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
+                dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on -9223372036854775808",
+                          __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
             } else {
                 logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
             }
@@ -7216,7 +7015,7 @@ void NumberFormatTest::TestFormatFastpaths() {
     }
     {
         UErrorCode status=U_ZERO_ERROR;
-        DecimalFormat df(UnicodeString("0000000000000000000",""),status);
+        DecimalFormat df(UnicodeString(u"0000000000000000000"),status);
         if (U_FAILURE(status)) {
             dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
         } else {
@@ -7231,7 +7030,8 @@ void NumberFormatTest::TestFormatFastpaths() {
             FieldPosition pos;
             df.format(long_number, result, pos);
             if(U_FAILURE(status)||expect!=result) {
-                errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
+                dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on U_INT64_MAX",
+                          __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
             } else {
                 logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
             }
@@ -7254,7 +7054,8 @@ void NumberFormatTest::TestFormatFastpaths() {
             FieldPosition pos;
             df.format(long_number, result, pos);
             if(U_FAILURE(status)||expect!=result) {
-                errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
+                dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on 0",
+                          __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
             } else {
                 logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
             }
@@ -7272,7 +7073,8 @@ void NumberFormatTest::TestFormatFastpaths() {
             FieldPosition pos;
             df.format(long_number, result, pos);
             if(U_FAILURE(status)||expect!=result) {
-                errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
+                dataerrln("%s:%d FAIL: expected '%s' got '%s' status %s on -9223372036854775807",
+                          __FILE__, __LINE__, CStr(expect)(), CStr(result)(), u_errorName(status));
             } else {
                 logln("OK:  got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
             }
@@ -7281,7 +7083,7 @@ void NumberFormatTest::TestFormatFastpaths() {
 }
 
 
-void NumberFormatTest::TestFormattableSize(void) {
+void NumberFormatTest::TestFormattableSize(void) { // test ICU 61 behavior
   if(sizeof(FmtStackData) > UNUM_INTERNAL_STACKARRAY_SIZE) {
     errln("Error: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
           sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
@@ -7289,8 +7091,8 @@ void NumberFormatTest::TestFormattableSize(void) {
     logln("Warning: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
         sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
   } else {
-    logln("sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n",
-        sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE);
+    logln("sizeof(Formattable)=%d, 112=%d\n",
+        sizeof(Formattable), 112);
   }
 }
 
@@ -7433,9 +7235,9 @@ UBool NumberFormatTest::testFormattableAsUFormattable(const char *file, int line
       UErrorCode int64ConversionU = U_ZERO_ERROR;
       int64_t r = ufmt_getInt64(u, &int64ConversionU);
 
-      if( (l==r) 
+      if( (l==r)
           && ( uType != UFMT_INT64 ) // int64 better not overflow
-          && (U_INVALID_FORMAT_ERROR==int64ConversionU) 
+          && (U_INVALID_FORMAT_ERROR==int64ConversionU)
           && (U_INVALID_FORMAT_ERROR==int64ConversionF) ) {
         logln("%s:%d: OK: 64 bit overflow", file, line);
       } else {
@@ -7560,7 +7362,7 @@ void NumberFormatTest::TestSignificantDigits(void) {
     numberFormat->setMinimumSignificantDigits(3);
     numberFormat->setMaximumSignificantDigits(5);
     numberFormat->setGroupingUsed(false);
-    
+
     UnicodeString result;
     UnicodeString expectedResult;
     for (unsigned int i = 0; i < UPRV_LENGTHOF(input); ++i) {
@@ -7582,7 +7384,7 @@ void NumberFormatTest::TestShowZero() {
 
     numberFormat->setSignificantDigitsUsed(TRUE);
     numberFormat->setMaximumSignificantDigits(3);
-    
+
     UnicodeString result;
     numberFormat->format(0.0, result);
     if (result != "0") {
@@ -7599,7 +7401,7 @@ void NumberFormatTest::TestBug9936() {
         dataerrln("File %s, Line %d: status = %s.\n", __FILE__, __LINE__, u_errorName(status));
         return;
     }
-        
+
     if (numberFormat->areSignificantDigitsUsed() == TRUE) {
         errln("File %s, Line %d: areSignificantDigitsUsed() was TRUE, expected FALSE.\n", __FILE__, __LINE__);
     }
@@ -7623,7 +7425,7 @@ void NumberFormatTest::TestBug9936() {
     if (numberFormat->areSignificantDigitsUsed() == FALSE) {
         errln("File %s, Line %d: areSignificantDigitsUsed() was FALSE, expected TRUE.\n", __FILE__, __LINE__);
     }
+
 }
 
 void NumberFormatTest::TestParseNegativeWithFaLocale() {
@@ -7714,7 +7516,7 @@ void NumberFormatTest::TestParseSignsAndMarks() {
         { "en@numbers=arabext", FALSE,  CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"),          -67 },
         { "en@numbers=arabext", TRUE,   CharsToUnicodeString("\\u200E-\\u200E\\u06F6\\u06F7"),          -67 },
         { "en@numbers=arabext", TRUE,   CharsToUnicodeString("\\u200E-\\u200E \\u06F6\\u06F7"),         -67 },
+
         { "he",                 FALSE,  CharsToUnicodeString("12"),                                      12 },
         { "he",                 TRUE,   CharsToUnicodeString("12"),                                      12 },
         { "he",                 FALSE,  CharsToUnicodeString("-23"),                                    -23 },
@@ -7834,19 +7636,14 @@ void NumberFormatTest::Test10468ApplyPattern() {
         return;
     }
 
-    if (fmt.getPadCharacterString() != UnicodeString("a")) {
-        errln("Padding character should be 'a'.");
-        return;
-    }
+    assertEquals("Padding character should be 'a'.", u"a", fmt.getPadCharacterString());
 
     // Padding char of fmt ought to be '*' since that is the default and no
     // explicit padding char is specified in the new pattern.
     fmt.applyPattern("AA#,##0.00ZZ", status);
 
-    // Oops this still prints 'a' even though we changed the pattern. 
-    if (fmt.getPadCharacterString() != UnicodeString(" ")) {
-        errln("applyPattern did not clear padding character.");
-    }
+    // Oops this still prints 'a' even though we changed the pattern.
+    assertEquals("applyPattern did not clear padding character.", u" ", fmt.getPadCharacterString());
 }
 
 void NumberFormatTest::TestRoundingScientific10542() {
@@ -7856,7 +7653,7 @@ void NumberFormatTest::TestRoundingScientific10542() {
         errcheckln(status, "DecimalFormat constructor failed - %s", u_errorName(status));
         return;
     }
-        
+
     DecimalFormat::ERoundingMode roundingModes[] = {
             DecimalFormat::kRoundCeiling,
             DecimalFormat::kRoundDown,
@@ -7873,7 +7670,7 @@ void NumberFormatTest::TestRoundingScientific10542() {
             "Round half even",
             "Round half up",
             "Round up"};
-        
+
     {
         double values[] = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016};
         // The order of these expected values correspond to the order of roundingModes and the order of values.
@@ -8022,12 +7819,12 @@ void NumberFormatTest::TestRoundingScientific10542() {
 void NumberFormatTest::TestZeroScientific10547() {
     UErrorCode status = U_ZERO_ERROR;
     DecimalFormat fmt("0.00E0", status);
-    if (!assertSuccess("Formt creation", status)) {
+    if (!assertSuccess("Format creation", status)) {
         return;
     }
     UnicodeString out;
     fmt.format(-0.0, out);
-    assertEquals("format", "-0.00E0", out);
+    assertEquals("format", "-0.00E0", out, true);
 }
 
 void NumberFormatTest::verifyRounding(
@@ -8046,13 +7843,8 @@ void NumberFormatTest::verifyRounding(
             UnicodeString actual;
             format.format(values[j], actual);
             if (currentExpected != actual) {
-                char buffer[256];
-                sprintf(
-                        buffer,
-                        "For %s value %f, expected ",
-                        descriptions[i],
-                        values[j]);
-                errln(UnicodeString(buffer) + currentExpected + ", got " + actual);
+                dataerrln("For %s value %f, expected '%s', got '%s'",
+                          descriptions[i], values[j], CStr(currentExpected)(), CStr(actual)());
             }
         }
     }
@@ -8081,26 +7873,24 @@ void NumberFormatTest::TestAccountingCurrency() {
 // for #5186
 void NumberFormatTest::TestEquality() {
     UErrorCode status = U_ZERO_ERROR;
-    DecimalFormatSymbols* symbols = new DecimalFormatSymbols(Locale("root"), status);
+    DecimalFormatSymbols symbols(Locale("root"), status);
     if (U_FAILURE(status)) {
        dataerrln("Fail: can't create DecimalFormatSymbols for root");
        return;
     }
     UnicodeString pattern("#,##0.###");
-    DecimalFormat* fmtBase = new DecimalFormat(pattern, symbols, status);
+    DecimalFormat fmtBase(pattern, symbols, status);
     if (U_FAILURE(status)) {
        dataerrln("Fail: can't create DecimalFormat using root symbols");
        return;
     }
 
-    DecimalFormat* fmtClone = (DecimalFormat*)fmtBase->clone();
-    fmtClone->setFormatWidth(fmtBase->getFormatWidth() + 32);
-    if (*fmtClone == *fmtBase) {
+    DecimalFormat* fmtClone = (DecimalFormat*)fmtBase.clone();
+    fmtClone->setFormatWidth(fmtBase.getFormatWidth() + 32);
+    if (*fmtClone == fmtBase) {
         errln("Error: DecimalFormat == does not distinguish objects that differ only in FormatWidth");
     }
     delete fmtClone;
-
-    delete fmtBase;
 }
 
 void NumberFormatTest::TestCurrencyUsage() {
@@ -8126,7 +7916,7 @@ void NumberFormatTest::TestCurrencyUsage() {
 
             UnicodeString original;
             fmt->format(agent,original);
-            assertEquals("Test Currency Usage 1", UnicodeString("PKR124"), original);
+            assertEquals("Test Currency Usage 1", u"PKR124", original); // use ICU 61 behavior
 
             // test the getter here
             UCurrencyUsage curUsage = fmt->getCurrencyUsage();
@@ -8146,7 +7936,7 @@ void NumberFormatTest::TestCurrencyUsage() {
 
         UnicodeString cash_currency;
         fmt->format(agent,cash_currency);
-        assertEquals("Test Currency Usage 2", UnicodeString("PKR124"), cash_currency);
+        assertEquals("Test Currency Usage 2", u"PKR124", cash_currency); // use ICU 61 behavior
         delete fmt;
     }
 
@@ -8163,10 +7953,10 @@ void NumberFormatTest::TestCurrencyUsage() {
 
             UnicodeString original_rounding;
             fmt->format(agent, original_rounding);
-            assertEquals("Test Currency Usage 3", UnicodeString("CA$123.57"), original_rounding);
+            assertEquals("Test Currency Usage 3", u"CA$123.57", original_rounding);
             fmt->setCurrencyUsage(UCURR_USAGE_CASH, &status);
         }else{
-            fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status); 
+            fmt = (DecimalFormat *) NumberFormat::createInstance(enUS_CAD, UNUM_CASH_CURRENCY, status);
             if (assertSuccess("en_US@currency=CAD/CASH", status, TRUE) == FALSE) {
                 continue;
             }
@@ -8174,7 +7964,7 @@ void NumberFormatTest::TestCurrencyUsage() {
 
         UnicodeString cash_rounding_currency;
         fmt->format(agent, cash_rounding_currency);
-        assertEquals("Test Currency Usage 4", UnicodeString("CA$123.55"), cash_rounding_currency);
+        assertEquals("Test Currency Usage 4", u"CA$123.55", cash_rounding_currency);
         delete fmt;
     }
 
@@ -8199,83 +7989,18 @@ void NumberFormatTest::TestCurrencyUsage() {
         UnicodeString cur_original;
         fmt->setCurrencyUsage(UCURR_USAGE_STANDARD, &status);
         fmt->format(agent, cur_original);
-        assertEquals("Test Currency Usage 5", UnicodeString("CA$123.57"), cur_original);
+        assertEquals("Test Currency Usage 5", u"CA$123.57", cur_original);
 
         fmt->setCurrency(CUR_PKR, status);
         assertSuccess("Set currency to PKR", status);
 
         UnicodeString PKR_changed;
         fmt->format(agent, PKR_changed);
-        assertEquals("Test Currency Usage 6", UnicodeString("PKR124"), PKR_changed);
+        assertEquals("Test Currency Usage 6", u"PKR124", PKR_changed); // use ICU 61 behavior
         delete fmt;
     }
 }
 
-void NumberFormatTest::TestNumberFormatTestTuple() {
-    NumberFormatTestTuple tuple;
-    UErrorCode status = U_ZERO_ERROR;
-
-    tuple.setField(
-            NumberFormatTestTuple::getFieldByName("locale"),
-            "en",
-            status);
-    tuple.setField(
-            NumberFormatTestTuple::getFieldByName("pattern"),
-            "#,##0.00",
-            status);
-    tuple.setField(
-            NumberFormatTestTuple::getFieldByName("minIntegerDigits"),
-            "-10",
-            status);
-    if (!assertSuccess("", status)) {
-        return;
-    }
-
-    // only what we set should be set.
-    assertEquals("", "en", tuple.locale.getName());
-    assertEquals("", "#,##0.00", tuple.pattern);
-    assertEquals("", -10, tuple.minIntegerDigits);
-    assertTrue("", tuple.localeFlag);
-    assertTrue("", tuple.patternFlag);
-    assertTrue("", tuple.minIntegerDigitsFlag);
-    assertFalse("", tuple.formatFlag);
-
-    UnicodeString appendTo;
-    assertEquals(
-            "",
-            "{locale: en, pattern: #,##0.00, minIntegerDigits: -10}",
-            tuple.toString(appendTo));
-
-    tuple.clear();
-    appendTo.remove();
-    assertEquals(
-            "",
-            "{}",
-            tuple.toString(appendTo));
-    tuple.setField(
-            NumberFormatTestTuple::getFieldByName("aBadFieldName"),
-            "someValue",
-            status);
-    if (status != U_ILLEGAL_ARGUMENT_ERROR) {
-        errln("Expected U_ILLEGAL_ARGUMENT_ERROR");
-    }
-    status = U_ZERO_ERROR;
-    tuple.setField(
-            NumberFormatTestTuple::getFieldByName("minIntegerDigits"),
-            "someBadValue",
-            status);
-    if (status != U_ILLEGAL_ARGUMENT_ERROR) {
-        errln("Expected U_ILLEGAL_ARGUMENT_ERROR");
-    }
-}
-
-void
-NumberFormatTest::TestDataDriven() {
-    NumberFormatTestDataDriven dd;
-    dd.setCaller(this);
-    dd.run("numberformattestspecification.txt", FALSE);
-}
-
 
 // Check the constant MAX_INT64_IN_DOUBLE.
 // The value should convert to a double with no loss of precision.
@@ -8293,7 +8018,7 @@ void NumberFormatTest::TestDoubleLimit11439() {
         sprintf(buf, "%lld", (long long)num);
         double fNum = 0.0;
         sscanf(buf, "%lf", &fNum);
-        int64_t rtNum = fNum;
+        int64_t rtNum = static_cast<int64_t>(fNum);
         if (num != rtNum) {
             errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__, __LINE__, (long long)num, (long long)rtNum);
             return;
@@ -8303,7 +8028,7 @@ void NumberFormatTest::TestDoubleLimit11439() {
         sprintf(buf, "%lld", (long long)num);
         double fNum = 0.0;
         sscanf(buf, "%lf", &fNum);
-        int64_t rtNum = fNum;
+        int64_t rtNum = static_cast<int64_t>(fNum);
         if (num != rtNum) {
             errln("%s:%d MAX_INT64_IN_DOUBLE test, %lld did not round trip. Got %lld", __FILE__, __LINE__, (long long)num, (long long)rtNum);
             return;
@@ -8311,21 +8036,6 @@ void NumberFormatTest::TestDoubleLimit11439() {
     }
 }
 
-void NumberFormatTest::TestFastPathConsistent11524() {
-    UErrorCode status = U_ZERO_ERROR;
-    NumberFormat *fmt = NumberFormat::createInstance("en", status);
-    if (U_FAILURE(status) || fmt == NULL) {
-        dataerrln("Failed call to NumberFormat::createInstance() - %s", u_errorName(status));
-        return;
-    }
-    fmt->setMaximumIntegerDigits(INT32_MIN);
-    UnicodeString appendTo;
-    assertEquals("", "0", fmt->format((int32_t)123, appendTo));
-    appendTo.remove();
-    assertEquals("", "0", fmt->format((int32_t)12345, appendTo));
-    delete fmt;
-}
-
 void NumberFormatTest::TestGetAffixes() {
     UErrorCode status = U_ZERO_ERROR;
     DecimalFormatSymbols sym("en_US", status);
@@ -8564,11 +8274,51 @@ void NumberFormatTest::Test11868() {
 }
 
 void NumberFormatTest::Test10727_RoundingZero() {
-   DigitList d;
-   d.set(-0.0);
-   assertFalse("", d.isPositive());
-   d.round(3); 
-   assertFalse("", d.isPositive());
+    IcuTestErrorCode status(*this, "Test10727_RoundingZero");
+    DecimalQuantity dq;
+    dq.setToDouble(-0.0);
+    assertTrue("", dq.isNegative());
+    dq.roundToMagnitude(0, UNUM_ROUND_HALFEVEN, status);
+    assertTrue("", dq.isNegative());
+}
+
+void NumberFormatTest::Test11739_ParseLongCurrency() {
+    IcuTestErrorCode status(*this, "Test11739_ParseLongCurrency");
+    LocalPointer<NumberFormat> nf(NumberFormat::createCurrencyInstance("sr_BA", status));
+    if (status.errDataIfFailureAndReset()) { return; }
+    ((DecimalFormat*) nf.getAlias())->applyPattern(u"#,##0.0 ¤¤¤", status);
+    ParsePosition ppos(0);
+    LocalPointer<CurrencyAmount> result(nf->parseCurrency(u"1.500 амерички долар", ppos));
+    assertEquals("Should parse to 1500 USD", -1, ppos.getErrorIndex());
+    assertEquals("Should parse to 1500 USD", 1500LL, result->getNumber().getInt64(status));
+    assertEquals("Should parse to 1500 USD", u"USD", result->getISOCurrency());
+}
+
+void NumberFormatTest::Test13035_MultiCodePointPaddingInPattern() {
+    IcuTestErrorCode status(*this, "Test13035_MultiCodePointPaddingInPattern");
+    DecimalFormat df(u"a*'நி'###0b", status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    UnicodeString result;
+    df.format(12, result.remove());
+    // TODO(13034): Re-enable this test when support is added in ICU4C.
+    //assertEquals("Multi-codepoint padding should not be split", u"aநிநி12b", result);
+    df = DecimalFormat(u"a*\U0001F601###0b", status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    result = df.format(12, result.remove());
+    assertEquals("Single-codepoint padding should not be split", u"a\U0001F601\U0001F60112b", result, true);
+    df = DecimalFormat(u"a*''###0b", status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    result = df.format(12, result.remove());
+    assertEquals("Quote should be escapable in padding syntax", "a''12b", result, true);
+}
+
+void NumberFormatTest::Test13737_ParseScientificStrict() {
+    IcuTestErrorCode status(*this, "Test13737_ParseScientificStrict");
+    LocalPointer<NumberFormat> df(NumberFormat::createScientificInstance("en", status), status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) {return;}
+    df->setLenient(FALSE);
+    // Parse Test
+    expect(*df, u"1.2", 1.2);
 }
 
 void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
@@ -8583,7 +8333,7 @@ void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
         DecimalFormat *dfmt = (DecimalFormat *) fmt.getAlias();
         dfmt->setCurrency(USD);
         UnicodeString result;
-    
+
         // This line should be a no-op. I am setting the positive prefix
         // to be the same thing it was before.
         dfmt->setPositivePrefix(dfmt->getPositivePrefix(result));
@@ -8604,7 +8354,7 @@ void NumberFormatTest::Test11376_getAndSetPositivePrefix() {
         UnicodeString result;
         UnicodeString tripleIntlCurrency(" \\u00a4\\u00a4\\u00a4");
         tripleIntlCurrency = tripleIntlCurrency.unescape();
-        assertEquals("", tripleIntlCurrency, dfmt->getPositiveSuffix(result));
+        assertEquals("", tripleIntlCurrency, dfmt->getPositiveSuffix(result)); // use ICU 61 behavior
         dfmt->setCurrency(USD);
 
         // getPositiveSuffix() always returns the suffix for the
@@ -8707,7 +8457,7 @@ void NumberFormatTest::Test11649_toPatternWithMultiCurrency() {
     static UChar USD[] = {0x55, 0x53, 0x44, 0x0};
     fmt.setCurrency(USD);
     UnicodeString appendTo;
-    
+
     assertEquals("", "US dollars 12.34", fmt.format(12.34, appendTo));
 
     UnicodeString topattern;
@@ -8717,11 +8467,66 @@ void NumberFormatTest::Test11649_toPatternWithMultiCurrency() {
         return;
     }
     fmt2.setCurrency(USD);
-    
+
     appendTo.remove();
     assertEquals("", "US dollars 12.34", fmt2.format(12.34, appendTo));
 }
 
+void NumberFormatTest::Test13327_numberingSystemBufferOverflow() {
+    UErrorCode status = U_ZERO_ERROR;
+    for (int runId = 0; runId < 2; runId++) {
+        // Construct a locale string with a very long "numbers" value.
+        // The first time, make the value length exactly equal to ULOC_KEYWORDS_CAPACITY.
+        // The second time, make it exceed ULOC_KEYWORDS_CAPACITY.
+        int extraLength = (runId == 0) ? 0 : 5;
+
+        CharString localeId("en@numbers=", status);
+        for (int i = 0; i < ULOC_KEYWORDS_CAPACITY + extraLength; i++) {
+            localeId.append('x', status);
+        }
+        assertSuccess("Constructing locale string", status);
+        Locale locale(localeId.data());
+
+        LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(locale, status));
+        assertFalse("Should not be null", ns.getAlias() == nullptr);
+        assertSuccess("Should create with no error", status);
+    }
+}
+
+void NumberFormatTest::Test13391_chakmaParsing() {
+    UErrorCode status = U_ZERO_ERROR;
+    LocalPointer<DecimalFormat> df(dynamic_cast<DecimalFormat*>(
+        NumberFormat::createInstance(Locale("ccp"), status)));
+    if (df == nullptr) {
+        dataerrln("%s %d Chakma df is null",  __FILE__, __LINE__);
+        return;
+    }
+    const UChar* expected = u"\U00011137\U00011138,\U00011139\U0001113A\U0001113B";
+    UnicodeString actual;
+    df->format(12345, actual, status);
+    assertSuccess("Should not fail when formatting in ccp", status);
+    assertEquals("Should produce expected output in ccp", expected, actual);
+
+    Formattable result;
+    df->parse(expected, result, status);
+    assertSuccess("Should not fail when parsing in ccp", status);
+    assertEquals("Should parse to 12345 in ccp", 12345, result);
+
+    const UChar* expectedScientific = u"\U00011137.\U00011139E\U00011138";
+    UnicodeString actualScientific;
+    df.adoptInstead(static_cast<DecimalFormat*>(
+        NumberFormat::createScientificInstance(Locale("ccp"), status)));
+    df->format(130, actualScientific, status);
+    assertSuccess("Should not fail when formatting scientific in ccp", status);
+    assertEquals("Should produce expected scientific output in ccp",
+        expectedScientific, actualScientific);
+
+    Formattable resultScientific;
+    df->parse(expectedScientific, resultScientific, status);
+    assertSuccess("Should not fail when parsing scientific in ccp", status);
+    assertEquals("Should parse scientific to 130 in ccp", 130, resultScientific);
+}
+
 
 void NumberFormatTest::verifyFieldPositionIterator(
         NumberFormatTest_Attributes *expected, FieldPositionIterator &iter) {
@@ -8742,25 +8547,618 @@ void NumberFormatTest::verifyFieldPositionIterator(
     }
 }
 
-void NumberFormatTest::checkExceptionIssue11735() {
-    UErrorCode status;
+void NumberFormatTest::Test11735_ExceptionIssue() {
+    IcuTestErrorCode status(*this, "Test11735_ExceptionIssue");
     Locale enLocale("en");
     DecimalFormatSymbols symbols(enLocale, status);
+    if (status.isSuccess()) {
+        DecimalFormat fmt("0", symbols, status);
+        assertSuccess("Fail: Construct DecimalFormat formatter", status, true, __FILE__, __LINE__);
+        ParsePosition ppos(0);
+        fmt.parseCurrency("53.45", ppos);  // NPE thrown here in ICU4J.
+        assertEquals("Issue11735 ppos", 0, ppos.getIndex());
+    }
+}
+
+void NumberFormatTest::Test11035_FormatCurrencyAmount() {
+    UErrorCode status = U_ZERO_ERROR;
+    double amount = 12345.67;
+    const char16_t* expected = u"12,345$67 ​";
+
+    // Test two ways to set a currency via API
 
+    Locale loc1 = Locale("pt_PT");
+    LocalPointer<NumberFormat> fmt1(NumberFormat::createCurrencyInstance("loc1", status),
+                                    status);
     if (U_FAILURE(status)) {
-      errln((UnicodeString)
-            "Fail: Construct DecimalFormatSymbols");
+      dataerrln("%s %d NumberFormat instance fmt1 is null",  __FILE__, __LINE__);
+      return;
+    }
+    fmt1->setCurrency(u"PTE", status);
+    assertSuccess("Setting currency on fmt1", status);
+    UnicodeString actualSetCurrency;
+    fmt1->format(amount, actualSetCurrency);
+
+    Locale loc2 = Locale("pt_PT@currency=PTE");
+    LocalPointer<NumberFormat> fmt2(NumberFormat::createCurrencyInstance(loc2, status));
+    assertSuccess("Creating fmt2", status);
+    UnicodeString actualLocaleString;
+    fmt2->format(amount, actualLocaleString);
+
+    // TODO: The following test will fail until DecimalFormat wraps NumberFormatter.
+    if (!logKnownIssue("13574")) {
+        assertEquals("Custom Currency Pattern, Set Currency", expected, actualSetCurrency);
     }
+}
 
-    DecimalFormat fmt("0", symbols, status);
+void NumberFormatTest::Test11318_DoubleConversion() {
+    IcuTestErrorCode status(*this, "Test11318_DoubleConversion");
+    LocalPointer<NumberFormat> nf(NumberFormat::createInstance("en", status), status);
     if (U_FAILURE(status)) {
-      errln((UnicodeString)
-            "Fail: Construct DecimalFormat formatter");
+      dataerrln("%s %d Error in NumberFormat instance creation",  __FILE__, __LINE__);
+      return;
+    }
+    nf->setMaximumFractionDigits(40);
+    nf->setMaximumIntegerDigits(40);
+    DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf.getAlias());
+    if (df != NULL) {
+        UErrorCode status = U_ZERO_ERROR;
+        df->setAttribute(UNUM_FORMAT_WITH_FULL_PRECISION, TRUE, status); // Apple
     }
+    UnicodeString appendTo;
+    nf->format(999999999999999.9, appendTo);
+    assertEquals("Should render all digits", u"999,999,999,999,999.9", appendTo);
+}
 
-    ParsePosition ppos(0);
-    fmt.parseCurrency("53.45", ppos);  // NPE thrown here in ICU4J.
-    assertEquals("Issue11735 ppos", 0, ppos.getIndex());
+void NumberFormatTest::TestParsePercentRegression() {
+    IcuTestErrorCode status(*this, "TestParsePercentRegression");
+    LocalPointer<DecimalFormat> df1((DecimalFormat*) NumberFormat::createInstance("en", status), status);
+    LocalPointer<DecimalFormat> df2((DecimalFormat*) NumberFormat::createPercentInstance("en", status), status);
+    if (status.isFailure()) {return; }
+    df1->setLenient(TRUE);
+    df2->setLenient(TRUE);
+
+    {
+        ParsePosition ppos;
+        Formattable result;
+        df1->parse("50%", result, ppos);
+        assertEquals("df1 should accept a number but not the percent sign", 2, ppos.getIndex());
+        assertEquals("df1 should return the number as 50", 50.0, result.getDouble(status));
+    }
+    {
+        ParsePosition ppos;
+        Formattable result;
+        df2->parse("50%", result, ppos);
+        assertEquals("df2 should accept the percent sign", 3, ppos.getIndex());
+        assertEquals("df2 should return the number as 0.5", 0.5, result.getDouble(status));
+    }
+    {
+        ParsePosition ppos;
+        Formattable result;
+        df2->parse("50", result, ppos);
+        assertEquals("df2 should return the number as 0.5 even though the percent sign is missing",
+                0.5,
+                result.getDouble(status));
+    }
+}
+
+void NumberFormatTest::TestMultiplierWithScale() {
+    // to be added
+}
+
+void NumberFormatTest::TestFastFormatInt32() {
+    IcuTestErrorCode status(*this, "TestFastFormatInt32");
+
+    // The two simplest formatters, old API and new API.
+    // Old API should use the fastpath for ints.
+    LocalizedNumberFormatter lnf = NumberFormatter::withLocale("en");
+    LocalPointer<NumberFormat> df(NumberFormat::createInstance("en", status), status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) {return;}
+
+    double nums[] = {
+            0.0,
+            -0.0,
+            NAN,
+            INFINITY,
+            0.1,
+            1.0,
+            1.1,
+            2.0,
+            3.0,
+            9.0,
+            10.0,
+            99.0,
+            100.0,
+            999.0,
+            1000.0,
+            9999.0,
+            10000.0,
+            99999.0,
+            100000.0,
+            999999.0,
+            1000000.0,
+            static_cast<double>(INT32_MAX) - 1,
+            static_cast<double>(INT32_MAX),
+            static_cast<double>(INT32_MAX) + 1,
+            static_cast<double>(INT32_MIN) - 1,
+            static_cast<double>(INT32_MIN),
+            static_cast<double>(INT32_MIN) + 1};
+
+    for (auto num : nums) {
+        UnicodeString expected = lnf.formatDouble(num, status).toString();
+        UnicodeString actual;
+        df->format(num, actual);
+        assertEquals(UnicodeString("d = ") + num, expected, actual);
+    }
+}
+
+void NumberFormatTest::Test11646_Equality() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols(Locale::getEnglish(), status);
+    UnicodeString pattern(u"\u00a4\u00a4\u00a4 0.00 %\u00a4\u00a4");
+    DecimalFormat fmt(pattern, symbols, status);
+    if (!assertSuccess("", status)) return;
+
+    // Test equality with affixes. set affix methods can't capture special
+    // characters which is why equality should fail.
+    {
+        DecimalFormat fmtCopy(fmt);
+        assertTrue("", fmt == fmtCopy);
+        UnicodeString positivePrefix;
+        fmtCopy.setPositivePrefix(fmtCopy.getPositivePrefix(positivePrefix));
+        assertFalse("", fmt == fmtCopy);
+    }
+    {
+        DecimalFormat fmtCopy = DecimalFormat(fmt);
+        assertTrue("", fmt == fmtCopy);
+        UnicodeString positivePrefix;
+        fmtCopy.setPositiveSuffix(fmtCopy.getPositiveSuffix(positivePrefix));
+        assertFalse("", fmt == fmtCopy);
+    }
+    {
+        DecimalFormat fmtCopy(fmt);
+        assertTrue("", fmt == fmtCopy);
+        UnicodeString negativePrefix;
+        fmtCopy.setNegativePrefix(fmtCopy.getNegativePrefix(negativePrefix));
+        assertFalse("", fmt == fmtCopy);
+    }
+    {
+        DecimalFormat fmtCopy(fmt);
+        assertTrue("", fmt == fmtCopy);
+        UnicodeString negativePrefix;
+        fmtCopy.setNegativeSuffix(fmtCopy.getNegativeSuffix(negativePrefix));
+        assertFalse("", fmt == fmtCopy);
+    }
+}
+
+void NumberFormatTest::TestParseNaN() {
+    IcuTestErrorCode status(*this, "TestParseNaN");
+
+    DecimalFormat df("0", { "en", status }, status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    Formattable parseResult;
+    df.parse(u"NaN", parseResult, status);
+    assertEquals("NaN should parse successfully", NAN, parseResult.getDouble());
+    assertFalse("Result NaN should be positive", std::signbit(parseResult.getDouble()));
+    UnicodeString formatResult;
+    df.format(parseResult.getDouble(), formatResult);
+    assertEquals("NaN should round-trip", u"NaN", formatResult);
+}
+
+void NumberFormatTest::Test11897_LocalizedPatternSeparator() {
+    IcuTestErrorCode status(*this, "Test11897_LocalizedPatternSeparator");
+
+    // In a locale with a different <list> symbol, like arabic,
+    // kPatternSeparatorSymbol should still be ';'
+    {
+        DecimalFormatSymbols dfs("ar", status);
+        assertEquals("pattern separator symbol should be ;",
+                u";",
+                dfs.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
+    }
+
+    // However, the custom symbol should be used in localized notation
+    // when set manually via API
+    {
+        DecimalFormatSymbols dfs("en", status);
+        dfs.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, u"!", FALSE);
+        DecimalFormat df(u"0", dfs, status);
+        if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+        df.applyPattern("a0;b0", status); // should not throw
+        UnicodeString result;
+        assertEquals("should apply the normal pattern",
+                df.getNegativePrefix(result.remove()),
+                "b");
+        df.applyLocalizedPattern(u"c0!d0", status); // should not throw
+        assertEquals("should apply the localized pattern",
+                df.getNegativePrefix(result.remove()),
+                "d");
+    }
+}
+
+void NumberFormatTest::Test13055_PercentageRounding() {
+  IcuTestErrorCode status(*this, "PercentageRounding");
+  UnicodeString actual;
+  LocalPointer<NumberFormat>pFormat(NumberFormat::createPercentInstance("en_US", status));
+  if (U_FAILURE(status)) {
+      dataerrln("Failure creating DecimalFormat %s", u_errorName(status));
+      return;
+  }
+  pFormat->setMaximumFractionDigits(0);
+  pFormat->setRoundingMode(DecimalFormat::kRoundHalfEven);
+  pFormat->format(2.155, actual);
+  assertEquals("Should round percent toward even number", "216%", actual);
+}
+  
+void NumberFormatTest::Test11839() {
+    IcuTestErrorCode errorCode(*this, "Test11839");
+    // Ticket #11839: DecimalFormat does not respect custom plus sign
+    LocalPointer<DecimalFormatSymbols> dfs(new DecimalFormatSymbols(Locale::getEnglish(), errorCode), errorCode);
+    if (!assertSuccess("", errorCode, true, __FILE__, __LINE__)) { return; }
+    dfs->setSymbol(DecimalFormatSymbols::kMinusSignSymbol, u"a∸");
+    dfs->setSymbol(DecimalFormatSymbols::kPlusSignSymbol, u"b∔"); //  ∔  U+2214 DOT PLUS
+    DecimalFormat df(u"0.00+;0.00-", dfs.orphan(), errorCode);
+    UnicodeString result;
+    df.format(-1.234, result, errorCode);
+    assertEquals("Locale-specific minus sign should be used", u"1.23a∸", result);
+    df.format(1.234, result.remove(), errorCode);
+    assertEquals("Locale-specific plus sign should be used", u"1.23b∔", result);
+    // Test round-trip with parse
+    expect2(df, -456, u"456.00a∸");
+    expect2(df, 456, u"456.00b∔");
+}
+
+void NumberFormatTest::Test10354() {
+    IcuTestErrorCode errorCode(*this, "Test10354");
+    // Ticket #10354: invalid FieldPositionIterator when formatting with empty NaN
+    DecimalFormatSymbols dfs(errorCode);
+    UnicodeString empty;
+    dfs.setSymbol(DecimalFormatSymbols::kNaNSymbol, empty);
+    DecimalFormat df(errorCode);
+    df.setDecimalFormatSymbols(dfs);
+    UnicodeString result;
+    FieldPositionIterator positions;
+    df.format(NAN, result, &positions, errorCode);
+    errorCode.errIfFailureAndReset("DecimalFormat.format(NAN, FieldPositionIterator) failed");
+    FieldPosition fp;
+    while (positions.next(fp)) {
+        // Should not loop forever
+    }
+}
+
+void NumberFormatTest::Test11645_ApplyPatternEquality() {
+    IcuTestErrorCode status(*this, "Test11645_ApplyPatternEquality");
+    const char16_t* pattern = u"#,##0.0#";
+    LocalPointer<DecimalFormat> fmt((DecimalFormat*) NumberFormat::createInstance(status), status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    fmt->applyPattern(pattern, status);
+    LocalPointer<DecimalFormat> fmtCopy;
+
+    static const int32_t newMultiplier = 37;
+    fmtCopy.adoptInstead(new DecimalFormat(*fmt));
+    assertFalse("Value before setter", fmtCopy->getMultiplier() == newMultiplier);
+    fmtCopy->setMultiplier(newMultiplier);
+    assertEquals("Value after setter", fmtCopy->getMultiplier(), newMultiplier);
+    fmtCopy->applyPattern(pattern, status);
+    //assertEquals("Value after applyPattern", fmtCopy->getMultiplier(), newMultiplier);
+    //assertFalse("multiplier", *fmt == *fmtCopy);
+
+    static const NumberFormat::ERoundingMode newRoundingMode = NumberFormat::ERoundingMode::kRoundCeiling;
+    fmtCopy.adoptInstead(new DecimalFormat(*fmt));
+    assertFalse("Value before setter", fmtCopy->getRoundingMode() == newRoundingMode);
+    fmtCopy->setRoundingMode(newRoundingMode);
+    assertEquals("Value after setter", fmtCopy->getRoundingMode(), newRoundingMode);
+    fmtCopy->applyPattern(pattern, status);
+    assertEquals("Value after applyPattern", fmtCopy->getRoundingMode(), newRoundingMode);
+    assertFalse("roundingMode", *fmt == *fmtCopy);
+
+    static const char16_t *const newCurrency = u"EAT";
+    fmtCopy.adoptInstead(new DecimalFormat(*fmt));
+    assertFalse("Value before setter", fmtCopy->getCurrency() == newCurrency);
+    fmtCopy->setCurrency(newCurrency);
+    assertEquals("Value after setter", fmtCopy->getCurrency(), newCurrency);
+    fmtCopy->applyPattern(pattern, status);
+    assertEquals("Value after applyPattern", fmtCopy->getCurrency(), newCurrency);
+    assertFalse("currency", *fmt == *fmtCopy);
+
+    static const UCurrencyUsage newCurrencyUsage = UCurrencyUsage::UCURR_USAGE_CASH;
+    fmtCopy.adoptInstead(new DecimalFormat(*fmt));
+    assertFalse("Value before setter", fmtCopy->getCurrencyUsage() == newCurrencyUsage);
+    fmtCopy->setCurrencyUsage(newCurrencyUsage, status);
+    assertEquals("Value after setter", fmtCopy->getCurrencyUsage(), newCurrencyUsage);
+    fmtCopy->applyPattern(pattern, status);
+    assertEquals("Value after applyPattern", fmtCopy->getCurrencyUsage(), newCurrencyUsage);
+    assertFalse("currencyUsage", *fmt == *fmtCopy);
+}
+
+void NumberFormatTest::Test12567() {
+    IcuTestErrorCode errorCode(*this, "Test12567");
+    // Ticket #12567: DecimalFormat.equals() may not be symmetric
+    LocalPointer<DecimalFormat> df1((DecimalFormat *)
+        NumberFormat::createInstance(Locale::getUS(), UNUM_CURRENCY, errorCode));
+    LocalPointer<DecimalFormat> df2((DecimalFormat *)
+        NumberFormat::createInstance(Locale::getUS(), UNUM_DECIMAL, errorCode));
+    if (!assertSuccess("", errorCode, true, __FILE__, __LINE__)) { return; }
+    // NOTE: CurrencyPluralInfo equality not tested in C++ because its operator== is not defined.
+    df1->applyPattern(u"0.00", errorCode);
+    df2->applyPattern(u"0.00", errorCode);
+    //assertTrue("df1 == df2", *df1 == *df2);
+    //assertTrue("df2 == df1", *df2 == *df1);
+    df2->setPositivePrefix(u"abc");
+    assertTrue("df1 != df2", *df1 != *df2);
+    assertTrue("df2 != df1", *df2 != *df1);
+}
+
+void NumberFormatTest::Test11626_CustomizeCurrencyPluralInfo() {
+    IcuTestErrorCode errorCode(*this, "Test11626_CustomizeCurrencyPluralInfo");
+    // Ticket #11626: No unit test demonstrating how to use CurrencyPluralInfo to
+    // change formatting spelled out currencies
+    // Use locale sr because it has interesting plural rules.
+    Locale locale("sr");
+    LocalPointer<DecimalFormatSymbols> symbols(new DecimalFormatSymbols(locale, errorCode), errorCode);
+    CurrencyPluralInfo info(locale, errorCode);
+    if (!assertSuccess("", errorCode, true, __FILE__, __LINE__)) { return; }
+    info.setCurrencyPluralPattern(u"one", u"0 qwerty", errorCode);
+    info.setCurrencyPluralPattern(u"few", u"0 dvorak", errorCode);
+    DecimalFormat df(u"#", symbols.orphan(), UNUM_CURRENCY_PLURAL, errorCode);
+    df.setCurrencyPluralInfo(info);
+    df.setCurrency(u"USD");
+    df.setMaximumFractionDigits(0);
+
+    UnicodeString result;
+    //assertEquals("Plural one", u"1 qwerty", df.format(1, result, errorCode));
+    //assertEquals("Plural few", u"3 dvorak", df.format(3, result.remove(), errorCode));
+    assertEquals("Plural other", u"99 америчких долара", df.format(99, result.remove(), errorCode));
+
+    info.setPluralRules(u"few: n is 1; one: n in 2..4", errorCode);
+    df.setCurrencyPluralInfo(info);
+    //assertEquals("Plural one", u"1 dvorak", df.format(1, result.remove(), errorCode));
+    //assertEquals("Plural few", u"3 qwerty", df.format(3, result.remove(), errorCode));
+    assertEquals("Plural other", u"99 америчких долара", df.format(99, result.remove(), errorCode));
+}
+
+void NumberFormatTest::Test13056_GroupingSize() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormat df(u"#,##0", status);
+    if (!assertSuccess("", status)) return;
+    assertEquals("Primary grouping should return 3", 3, df.getGroupingSize());
+    assertEquals("Secondary grouping should return 0", 0, df.getSecondaryGroupingSize());
+    df.setSecondaryGroupingSize(3);
+    assertEquals("Primary grouping should still return 3", 3, df.getGroupingSize());
+    assertEquals("Secondary grouping should round-trip", 3, df.getSecondaryGroupingSize());
+    df.setGroupingSize(4);
+    assertEquals("Primary grouping should return 4", 4, df.getGroupingSize());
+    assertEquals("Secondary should remember explicit setting and return 3", 3, df.getSecondaryGroupingSize());
+}
+
+
+void NumberFormatTest::Test11025_CurrencyPadding() {
+    UErrorCode status = U_ZERO_ERROR;
+    UnicodeString pattern(u"¤¤ **####0.00");
+    DecimalFormatSymbols sym(Locale::getFrance(), status);
+    if (!assertSuccess("", status)) return;
+    DecimalFormat fmt(pattern, sym, status);
+    if (!assertSuccess("", status)) return;
+    UnicodeString result;
+    fmt.format(433.0, result);
+    assertEquals("Number should be padded to 11 characters", "EUR *433,00", result);
+}
+
+void NumberFormatTest::Test11648_ExpDecFormatMalPattern() {
+    UErrorCode status = U_ZERO_ERROR;
+
+    DecimalFormat fmt("0.00", {"en", status}, status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    fmt.setScientificNotation(TRUE);
+    UnicodeString pattern;
+
+    assertEquals("A valid scientific notation pattern should be produced",
+            "0.00E0",
+            fmt.toPattern(pattern));
+
+    DecimalFormat fmt2(pattern, status);
+    assertSuccess("", status);
+}
+
+void NumberFormatTest::Test11649_DecFmtCurrencies() {
+    IcuTestErrorCode status(*this, "Test11649_DecFmtCurrencies");
+    UnicodeString pattern("\\u00a4\\u00a4\\u00a4 0.00");
+    pattern = pattern.unescape();
+    DecimalFormat fmt(pattern, status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    static const UChar USD[] = u"USD";
+    fmt.setCurrency(USD);
+    UnicodeString appendTo;
+
+    assertEquals("", "US dollars 12.34", fmt.format(12.34, appendTo));
+    UnicodeString topattern;
+
+    // assertEquals("", pattern, fmt.toPattern(topattern));
+    DecimalFormat fmt2(topattern, status);
+    fmt2.setCurrency(USD);
+
+    appendTo.remove();
+    assertEquals("", "US dollars 12.34", fmt2.format(12.34, appendTo));
+}
+
+void NumberFormatTest::Test13148_ParseGroupingSeparators() {
+  IcuTestErrorCode status(*this, "Test13148");
+  LocalPointer<DecimalFormat> fmt(
+      (DecimalFormat*)NumberFormat::createInstance("en-ZA", status), status);
+  if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+
+  DecimalFormatSymbols symbols = *fmt->getDecimalFormatSymbols();
+
+  symbols.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u'.');
+  symbols.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, u',');
+  fmt->setDecimalFormatSymbols(symbols);
+  Formattable number;
+  fmt->parse(u"300,000", number, status);
+  assertEquals("Should parse as 300000", 300000LL, number.getInt64(status));
+}
+
+void NumberFormatTest::Test12753_PatternDecimalPoint() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols symbols(Locale::getUS(), status);
+    symbols.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u"*", false);
+    DecimalFormat df(u"0.00", symbols, status);
+    if (!assertSuccess("", status)) return;
+    df.setDecimalPatternMatchRequired(true);
+    Formattable result;
+    df.parse(u"123",result, status);
+    assertEquals("Parsing integer succeeded even though setDecimalPatternMatchRequired was set",
+                 U_INVALID_FORMAT_ERROR, status);
+    }
+
+ void NumberFormatTest::Test11647_PatternCurrencySymbols() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormat df(status);
+    df.applyPattern(u"¤¤¤¤#", status);
+    if (!assertSuccess("", status)) return;
+    UnicodeString actual;
+    df.format(123, actual);
+    //assertEquals("Should replace 4 currency signs with U+FFFD", u"\uFFFD123", actual);
+}
+
+void NumberFormatTest::Test11913_BigDecimal() {
+    UErrorCode status = U_ZERO_ERROR;
+    LocalPointer<NumberFormat> df(NumberFormat::createInstance(Locale::getEnglish(), status), status);
+    if (!assertSuccess("", status)) return;
+    UnicodeString result;
+    df->format(StringPiece("1.23456789E400"), result, nullptr, status);
+    assertSuccess("", status);
+    assertEquals("Should format more than 309 digits", u"12,345,678", UnicodeString(result, 0, 10));
+    assertEquals("Should format more than 309 digits", 534, result.length());
+}
+
+void NumberFormatTest::Test11020_RoundingInScientificNotation() {
+    UErrorCode status = U_ZERO_ERROR;
+    DecimalFormatSymbols sym(Locale::getFrance(), status);
+    DecimalFormat fmt(u"0.05E0", sym, status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    assertSuccess("", status);
+    UnicodeString result;
+    fmt.format(12301.2, result);
+    assertEquals("Rounding increment should be applied after magnitude scaling", u"1,25E4", result);
+}
+
+void NumberFormatTest::Test11640_TripleCurrencySymbol() {
+    IcuTestErrorCode status(*this, "Test11640_TripleCurrencySymbol");
+    UnicodeString actual;
+    DecimalFormat dFormat(u"¤¤¤ 0", status);
+    if (U_FAILURE(status)) {
+        dataerrln("Failure creating DecimalFormat %s", u_errorName(status));
+        return;
+    }
+    dFormat.setCurrency(u"USD");
+    UnicodeString result;
+    dFormat.getPositivePrefix(result);
+    assertEquals("Triple-currency should give long name on getPositivePrefix",
+                "US dollars ", result);
+}
+
+
+void NumberFormatTest::Test13763_FieldPositionIteratorOffset() {
+    IcuTestErrorCode status(*this, "Test13763_FieldPositionIteratorOffset");
+    FieldPositionIterator fpi;
+    UnicodeString result(u"foo\U0001F4FBbar"); // 8 code units
+    LocalPointer<NumberFormat> nf(NumberFormat::createInstance("en", status), status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    nf->format(5142.3, result, &fpi, status);
+
+    int32_t expected[] = {
+      UNUM_GROUPING_SEPARATOR_FIELD, 9, 10,
+      UNUM_INTEGER_FIELD, 8, 13,
+      UNUM_DECIMAL_SEPARATOR_FIELD, 13, 14,
+      UNUM_FRACTION_FIELD, 14, 15,
+    };
+    int32_t tupleCount = UPRV_LENGTHOF(expected)/3;
+    expectPositions(fpi, expected, tupleCount, result);
+}
+
+void NumberFormatTest::Test13777_ParseLongNameNonCurrencyMode() {
+    IcuTestErrorCode status(*this, "Test13777_ParseLongNameNonCurrencyMode");
+
+    LocalPointer<NumberFormat> df(
+        NumberFormat::createInstance("en-us", UNumberFormatStyle::UNUM_CURRENCY_PLURAL, status), status);
+    if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+    expect2(*df, 1.5, u"1.50 US dollars");
+}
+
+void NumberFormatTest::Test13804_EmptyStringsWhenParsing() {
+    IcuTestErrorCode status(*this, "Test13804_EmptyStringsWhenParsing");
+
+    DecimalFormatSymbols dfs("en", status);
+    if (status.errIfFailureAndReset()) {
+        return;
+    }
+    dfs.setSymbol(DecimalFormatSymbols::kCurrencySymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kZeroDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kOneDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kTwoDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kThreeDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kFourDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kFiveDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kSixDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kSevenDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kEightDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kNineDigitSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kExponentMultiplicationSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kExponentialSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kInfinitySymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kNaNSymbol, u"", FALSE);
+    dfs.setPatternForCurrencySpacing(UNUM_CURRENCY_INSERT, FALSE, u"");
+    dfs.setPatternForCurrencySpacing(UNUM_CURRENCY_INSERT, TRUE, u"");
+    dfs.setSymbol(DecimalFormatSymbols::kPercentSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kPerMillSymbol, u"", FALSE);
+    dfs.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, u"", FALSE);
+
+    DecimalFormat df("0", dfs, status);
+    if (status.errIfFailureAndReset()) {
+        return;
+    }
+    df.setGroupingUsed(TRUE);
+    df.setScientificNotation(TRUE);
+    df.setLenient(TRUE); // enable all matchers
+    {
+        UnicodeString result;
+        df.format(0, result); // should not crash or hit infinite loop
+    }
+    const char16_t* samples[] = {
+            u"",
+            u"123",
+            u"$123",
+            u"-",
+            u"+",
+            u"44%",
+            u"1E+2.3"
+    };
+    for (auto& sample : samples) {
+        logln(UnicodeString(u"Attempting parse on: ") + sample);
+        status.setScope(sample);
+        // We don't care about the results, only that we don't crash and don't loop.
+        Formattable result;
+        ParsePosition ppos(0);
+        df.parse(sample, result, ppos);
+        ppos = ParsePosition(0);
+        LocalPointer<CurrencyAmount> curramt(df.parseCurrency(sample, ppos));
+        status.errIfFailureAndReset();
+    }
+
+    // Test with a nonempty exponent separator symbol to cover more code
+    dfs.setSymbol(DecimalFormatSymbols::kExponentialSymbol, u"E", FALSE);
+    df.setDecimalFormatSymbols(dfs);
+    {
+        Formattable result;
+        ParsePosition ppos(0);
+        df.parse(u"1E+2.3", result, ppos);
+    }
 }
 
 #endif /* #if !UCONFIG_NO_FORMATTING */