From: Shane Carr Date: Wed, 27 Sep 2017 03:02:02 +0000 (+0000) Subject: ICU-13177 NumberFormatter tests are passing. X-Git-Tag: release-60-rc~98^2~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d7a61a6e9162217647cc6e0278d3d492c014701e;p=icu ICU-13177 NumberFormatter tests are passing. X-SVN-Rev: 40467 --- diff --git a/icu4c/source/i18n/number_affixutils.cpp b/icu4c/source/i18n/number_affixutils.cpp index 85af1d18d21..ec8b5b05240 100644 --- a/icu4c/source/i18n/number_affixutils.cpp +++ b/icu4c/source/i18n/number_affixutils.cpp @@ -149,7 +149,7 @@ int32_t AffixUtils::unescape(const CharSequence &affixPattern, NumberStringBuilder &output, int32_t position, const SymbolProvider &provider, UErrorCode &status) { int32_t length = 0; - AffixTag tag = {0}; + AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); if (tag.type == TYPE_CURRENCY_OVERFLOW) { @@ -168,7 +168,7 @@ AffixUtils::unescape(const CharSequence &affixPattern, NumberStringBuilder &outp int32_t AffixUtils::unescapedCodePointCount(const CharSequence &affixPattern, const SymbolProvider &provider, UErrorCode &status) { int32_t length = 0; - AffixTag tag = {0}; + AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); if (tag.type == TYPE_CURRENCY_OVERFLOW) { @@ -187,7 +187,7 @@ AffixUtils::containsType(const CharSequence &affixPattern, AffixPatternType type if (affixPattern.length() == 0) { return false; } - AffixTag tag = {0}; + AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); if (tag.type == type) { @@ -201,7 +201,7 @@ bool AffixUtils::hasCurrencySymbols(const CharSequence &affixPattern, UErrorCode if (affixPattern.length() == 0) { return false; } - AffixTag tag = {0}; + AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); if (tag.type < 0 && getFieldForType(tag.type) == UNUM_CURRENCY_FIELD) { @@ -217,7 +217,7 @@ UnicodeString AffixUtils::replaceType(const CharSequence &affixPattern, AffixPat if (affixPattern.length() == 0) { return output; }; - AffixTag tag = {0}; + AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); if (tag.type == type) { diff --git a/icu4c/source/i18n/number_affixutils.h b/icu4c/source/i18n/number_affixutils.h index 5fc2719cb56..5ff331420ae 100644 --- a/icu4c/source/i18n/number_affixutils.h +++ b/icu4c/source/i18n/number_affixutils.h @@ -34,6 +34,8 @@ struct AffixTag { AffixPatternState state; AffixPatternType type; + AffixTag() : offset(0), state(STATE_BASE) {} + AffixTag(int32_t offset) : offset(offset) {} AffixTag(int32_t offset, UChar32 codePoint, AffixPatternState state, AffixPatternType type) diff --git a/icu4c/source/i18n/number_decimalquantity.cpp b/icu4c/source/i18n/number_decimalquantity.cpp index a4112d09b67..a355f96d3f1 100644 --- a/icu4c/source/i18n/number_decimalquantity.cpp +++ b/icu4c/source/i18n/number_decimalquantity.cpp @@ -141,7 +141,7 @@ uint64_t DecimalQuantity::getPositionFingerprint() const { } void DecimalQuantity::roundToIncrement(double roundingIncrement, RoundingMode roundingMode, - UErrorCode& status) { + int32_t minMaxFrac, UErrorCode& status) { // TODO: This is innefficient. Improve? // TODO: Should we convert to decNumber instead? double temp = toDouble(); @@ -151,6 +151,9 @@ void DecimalQuantity::roundToIncrement(double roundingIncrement, RoundingMode ro temp = toDouble(); temp *= roundingIncrement; setToDouble(temp); + // Since we reset the value to a double, we need to specify the rounding boundary + // in order to get the DecimalQuantity out of approximation mode. + roundToMagnitude(minMaxFrac, roundingMode, status); } void DecimalQuantity::multiplyBy(int32_t multiplicand) { diff --git a/icu4c/source/i18n/number_decimalquantity.h b/icu4c/source/i18n/number_decimalquantity.h index ec0d69ebdaa..e2a6e92022b 100644 --- a/icu4c/source/i18n/number_decimalquantity.h +++ b/icu4c/source/i18n/number_decimalquantity.h @@ -67,7 +67,8 @@ class DecimalQuantity : public IFixedDecimal, public UMemory { * @param roundingIncrement The increment to which to round. * @param mathContext The {@link RoundingMode} to use if rounding is necessary. */ - void roundToIncrement(double roundingIncrement, RoundingMode roundingMode, UErrorCode& status); + void roundToIncrement(double roundingIncrement, RoundingMode roundingMode, + int32_t minMaxFrac, UErrorCode& status); /** * Rounds the number to a specified magnitude (power of ten). diff --git a/icu4c/source/i18n/number_patternmodifier.cpp b/icu4c/source/i18n/number_patternmodifier.cpp index 0874c83ed18..80121d84a75 100644 --- a/icu4c/source/i18n/number_patternmodifier.cpp +++ b/icu4c/source/i18n/number_patternmodifier.cpp @@ -22,7 +22,7 @@ void MutablePatternModifier::setPatternAttributes(UNumberSignDisplay signDisplay void MutablePatternModifier::setSymbols(const DecimalFormatSymbols *symbols, const CurrencyUnit ¤cy, const UNumberUnitWidth unitWidth, const PluralRules *rules) { - U_ASSERT((rules == nullptr) == needsPlurals()); + U_ASSERT((rules != nullptr) == needsPlurals()); this->symbols = symbols; uprv_memcpy(static_cast(this->currencyCode), currency.getISOCurrency(), diff --git a/icu4c/source/i18n/number_patternmodifier.h b/icu4c/source/i18n/number_patternmodifier.h index be2fbfbeabe..475b427e12e 100644 --- a/icu4c/source/i18n/number_patternmodifier.h +++ b/icu4c/source/i18n/number_patternmodifier.h @@ -195,7 +195,7 @@ class MutablePatternModifier const MicroPropsGenerator *parent; // Transient CharSequence fields - bool inCharSequenceMode; + bool inCharSequenceMode = false; int32_t fFlags; int32_t fLength; bool prependSign; diff --git a/icu4c/source/i18n/number_rounding.cpp b/icu4c/source/i18n/number_rounding.cpp index 52229f9ad33..e51158acb19 100644 --- a/icu4c/source/i18n/number_rounding.cpp +++ b/icu4c/source/i18n/number_rounding.cpp @@ -318,7 +318,8 @@ void Rounder::apply(impl::DecimalQuantity &value, UErrorCode& status) const { } case RND_INCREMENT: - value.roundToIncrement(fUnion.increment.fIncrement, fRoundingMode, status); + value.roundToIncrement( + fUnion.increment.fIncrement, fRoundingMode, fUnion.increment.fMinFrac, status); value.setFractionLength(fUnion.increment.fMinFrac, fUnion.increment.fMinFrac); break; diff --git a/icu4c/source/test/intltest/itformat.cpp b/icu4c/source/test/intltest/itformat.cpp index 6059930b7d0..0b3bf8a481c 100644 --- a/icu4c/source/test/intltest/itformat.cpp +++ b/icu4c/source/test/intltest/itformat.cpp @@ -223,13 +223,7 @@ void IntlTestFormat::runIndexedTest( int32_t index, UBool exec, const char* &nam callTest(*test, par); } break; - TESTCLASS(51,AffixUtilsTest); - TESTCLASS(52,NumberFormatterApiTest); - TESTCLASS(53,DecimalQuantityTest); - TESTCLASS(54,ModifiersTest); - TESTCLASS(55,PatternModifierTest); - TESTCLASS(56,PatternStringTest); - TESTCLASS(57,NumberStringBuilderTest); + TESTCLASS(51,NumberTest); default: name = ""; break; //needed to end loop } if (exec) { diff --git a/icu4c/source/test/intltest/numbertest.h b/icu4c/source/test/intltest/numbertest.h index 9848e5fd4dc..39f07ec2b3a 100644 --- a/icu4c/source/test/intltest/numbertest.h +++ b/icu4c/source/test/intltest/numbertest.h @@ -10,6 +10,14 @@ using namespace icu::number; using namespace icu::number::impl; +//////////////////////////////////////////////////////////////////////////////////////// +// INSTRUCTIONS: // +// To add new NumberFormat unit test classes, create a new class like the ones below, // +// and then add it as a switch statement in NumberTest at the bottom of this file. ///////// +// To add new methods to existing unit test classes, add the method to the class declaration // +// below, and also add it to the class's implementation of runIndexedTest(). // +/////////////////////////////////////////////////////////////////////////////////////////////// + class AffixUtilsTest : public IntlTest { public: void testEscape(); @@ -154,3 +162,36 @@ class NumberStringBuilderTest : public IntlTest { private: void assertEqualsImpl(const UnicodeString &a, const NumberStringBuilder &b); }; + + +// NOTE: This macro is identical to the one in itformat.cpp +#define TESTCLASS(id, TestClass) \ + case id: \ + name = #TestClass; \ + if (exec) { \ + logln(#TestClass " test---"); \ + logln((UnicodeString)""); \ + TestClass test; \ + callTest(test, par); \ + } \ + break + +class NumberTest : public IntlTest { + public: + void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) { + if (exec) { + logln("TestSuite NumberTest: "); + } + + switch (index) { + TESTCLASS(0, AffixUtilsTest); + TESTCLASS(1, NumberFormatterApiTest); + TESTCLASS(2, DecimalQuantityTest); + TESTCLASS(3, ModifiersTest); + TESTCLASS(4, PatternModifierTest); + TESTCLASS(5, PatternStringTest); + TESTCLASS(6, NumberStringBuilderTest); + default: name = ""; break; // needed to end loop + } + } +}; diff --git a/icu4c/source/test/intltest/numbertest_decimalquantity.cpp b/icu4c/source/test/intltest/numbertest_decimalquantity.cpp index 94dd384260e..322480869ef 100644 --- a/icu4c/source/test/intltest/numbertest_decimalquantity.cpp +++ b/icu4c/source/test/intltest/numbertest_decimalquantity.cpp @@ -78,7 +78,7 @@ void DecimalQuantityTest::testDecimalQuantityBehaviorStandalone() { assertToStringAndHealth(fq, ""); fq.roundToInfinity(); assertToStringAndHealth(fq, ""); - fq.roundToIncrement(0.005, RoundingMode::UNUM_ROUND_HALFEVEN, status); + fq.roundToIncrement(0.005, RoundingMode::UNUM_ROUND_HALFEVEN, 3, status); assertSuccess("Rounding to increment", status); assertToStringAndHealth(fq, ""); fq.roundToMagnitude(-2, RoundingMode::UNUM_ROUND_HALFEVEN, status);