From: Steven R. Loomis Date: Thu, 6 Mar 2014 00:12:57 +0000 (+0000) Subject: ICU-10756 regression tests added for case where setGroupingUsed didn't call handleCha... X-Git-Tag: milestone-59-0-1~2066 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f38544a2a66c335e3feafaa578478ab5f57866a9;p=icu ICU-10756 regression tests added for case where setGroupingUsed didn't call handleChanged() and thus the fastpath status would be incorrect. Fixed by overriding three functions in DecimalFormat but delegating to NumberFormat. The other two functions don't affect fastpath, but are overridden for future changes where they might. X-SVN-Rev: 35351 --- diff --git a/icu4c/source/i18n/decimfmt.cpp b/icu4c/source/i18n/decimfmt.cpp index b7a56ff0fbe..12f5e70548c 100644 --- a/icu4c/source/i18n/decimfmt.cpp +++ b/icu4c/source/i18n/decimfmt.cpp @@ -5313,6 +5313,29 @@ DecimalFormat::copyHashForAffixPattern(const Hashtable* source, } } +// this is only overridden to call handleChanged() for fastpath purposes. +void +DecimalFormat::setGroupingUsed(UBool newValue) { + NumberFormat::setGroupingUsed(newValue); + handleChanged(); +} + +// this is only overridden to call handleChanged() for fastpath purposes. +void +DecimalFormat::setParseIntegerOnly(UBool newValue) { + NumberFormat::setParseIntegerOnly(newValue); + handleChanged(); +} + +// this is only overridden to call handleChanged() for fastpath purposes. +// setContext doesn't affect the fastPath right now, but this is called for completeness +void +DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) { + NumberFormat::setContext(value, status); + handleChanged(); +} + + DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr, int32_t newValue, UErrorCode &status) { diff --git a/icu4c/source/i18n/unicode/decimfmt.h b/icu4c/source/i18n/unicode/decimfmt.h index e7e3bc44611..4a0fc4c2e0e 100644 --- a/icu4c/source/i18n/unicode/decimfmt.h +++ b/icu4c/source/i18n/unicode/decimfmt.h @@ -1,6 +1,6 @@ /* ******************************************************************************** -* Copyright (C) 1997-2013, International Business Machines +* Copyright (C) 1997-2014, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************** * @@ -63,7 +63,7 @@ class FixedDecimal; // explicit template instantiation. see digitlst.h #if defined (_MSC_VER) template class U_I18N_API EnumSet; #endif @@ -678,8 +678,8 @@ public: kRoundHalfUp, /**< Round towards the nearest integer, or away from zero if equidistant */ /** - * Return U_FORMAT_INEXACT_ERROR if number does not format exactly. - * @stable ICU 4.8 + * Return U_FORMAT_INEXACT_ERROR if number does not format exactly. + * @stable ICU 4.8 */ kRoundUnnecessary }; @@ -803,7 +803,34 @@ public: virtual int32_t getAttribute( UNumberFormatAttribute attr, UErrorCode &status) const; + + /** + * Set whether or not grouping will be used in this format. + * @param newValue True, grouping will be used in this format. + * @see getGroupingUsed + * @stable ICU 2.0 + */ + virtual void setGroupingUsed(UBool newValue); + + /** + * Sets whether or not numbers should be parsed as integers only. + * @param value set True, this format will parse numbers as integers + * only. + * @see isParseIntegerOnly + * @stable ICU 2.0 + */ + virtual void setParseIntegerOnly(UBool value); + /** + * Set a particular UDisplayContext value in the formatter, such as + * UDISPCTX_CAPITALIZATION_FOR_STANDALONE. + * @param value The UDisplayContext value to set. + * @param status Input/output status. If at entry this indicates a failure + * status, the function will do nothing; otherwise this will be + * updated with any new status from the function. + * @draft ICU 53 + */ + virtual void setContext(UDisplayContext value, UErrorCode& status); /** * Create a DecimalFormat from the given pattern and symbols. @@ -1065,7 +1092,7 @@ public: /** - * Format a decimal number. + * Format a decimal number. * The number is a DigitList wrapper onto a floating point decimal number. * The default implementation in NumberFormat converts the decimal number * to a double and formats that. @@ -1085,10 +1112,10 @@ public: UErrorCode& status) const; /** - * Format a decimal number. + * Format a decimal number. * The number is a DigitList wrapper onto a floating point decimal number. * The default implementation in NumberFormat converts the decimal number - * to a double and formats that. + * to a double and formats that. * * @param number The number, a DigitList format Decimal Floating Point. * @param appendTo Output parameter to receive result. @@ -1337,7 +1364,7 @@ public: virtual ERoundingMode getRoundingMode(void) const; /** - * Set the rounding mode. + * Set the rounding mode. * @param roundingMode A rounding mode * @see #setRoundingIncrement * @see #getRoundingIncrement @@ -1988,7 +2015,7 @@ private: UnicodeString& subformat(UnicodeString& appendTo, FieldPositionHandler& handler, DigitList& digits, - UBool isInteger, + UBool isInteger, UErrorCode &status) const; @@ -2184,7 +2211,7 @@ private: ChoiceFormat* fCurrencyChoice; DigitList * fMultiplier; // NULL for multiplier of one - int32_t fScale; + int32_t fScale; int32_t fGroupingSize; int32_t fGroupingSize2; UBool fDecimalSeparatorAlwaysShown; @@ -2199,8 +2226,8 @@ private: UBool fExponentSignAlwaysShown; EnumSet + UNUM_MAX_NONBOOLEAN_ATTRIBUTE+1, + UNUM_LIMIT_BOOLEAN_ATTRIBUTE> fBoolFlags; DigitList* fRoundingIncrement; // NULL if no rounding increment specified. @@ -2373,7 +2400,7 @@ protected: #if UCONFIG_FORMAT_FASTPATHS_49 private: /** - * Internal state. + * Internal state. * @internal */ uint8_t fReserved[UNUM_DECIMALFORMAT_INTERNAL_SIZE]; diff --git a/icu4c/source/test/intltest/dcfmapts.cpp b/icu4c/source/test/intltest/dcfmapts.cpp index cba32304757..bac939d7827 100644 --- a/icu4c/source/test/intltest/dcfmapts.cpp +++ b/icu4c/source/test/intltest/dcfmapts.cpp @@ -1,6 +1,6 @@ /******************************************************************** - * COPYRIGHT: - * Copyright (c) 1997-2013, International Business Machines Corporation and + * COPYRIGHT: + * Copyright (c) 1997-2014, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -32,7 +32,7 @@ void IntlTestDecimalFormatAPI::runIndexedTest( int32_t index, UBool exec, const { if (exec) logln((UnicodeString)"TestSuite DecimalFormatAPI"); switch (index) { - case 0: name = "DecimalFormat API test"; + case 0: name = "DecimalFormat API test"; if (exec) { logln((UnicodeString)"DecimalFormat API test---"); logln((UnicodeString)""); UErrorCode status = U_ZERO_ERROR; @@ -75,6 +75,12 @@ void IntlTestDecimalFormatAPI::runIndexedTest( int32_t index, UBool exec, const TestFixedDecimal(); } break; + case 6: name = "TestBadFastpath"; + if(exec) { + logln((UnicodeString)"TestBadFastpath ---"); + TestBadFastpath(); + } + break; default: name = ""; break; } } @@ -156,7 +162,7 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/) UnicodeString res1, res2, res3, res4; FieldPosition pos1(0), pos2(0), pos3(0), pos4(0); - + res1 = def.format(d, res1, pos1); logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1); @@ -287,7 +293,7 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/) if(sn != TRUE) { errln((UnicodeString)"ERROR: setScientificNotation() failed"); } - + // Added by Ken Liu testing set/getMinimumExponentDigits int8_t MinimumExponentDigits = 0; pat.setMinimumExponentDigits(2); @@ -416,7 +422,7 @@ void IntlTestDecimalFormatAPI::TestCurrencyPluralInfo(){ if(U_FAILURE(status)) { errln((UnicodeString)"ERROR: CurrencyPluralInfo::setLocale"); } - + cpi->setPluralRules("",status); if(U_FAILURE(status)) { errln((UnicodeString)"ERROR: CurrencyPluralInfo::setPluralRules"); @@ -448,7 +454,7 @@ void IntlTestDecimalFormatAPI::testRounding(/*char *par*/) 3.0, -3.0, // kRoundUp 3, 3.0, -3.0, // kRoundHalfEven 4, 3.0, -3.0, // kRoundHalfDown 5, - 3.0, -3.0 // kRoundHalfUp 6 + 3.0, -3.0 // kRoundHalfUp 6 }; DecimalFormat pat(status); if(U_FAILURE(status)) { @@ -515,11 +521,11 @@ void IntlTestDecimalFormatAPI::testRoundingInc(/*char *par*/) return; } - // With rounding now being handled by decNumber, we no longer + // With rounding now being handled by decNumber, we no longer // set a rounding increment to enable non-default mode rounding, // checking of which was the original point of this test. - // set rounding mode with zero increment. Rounding + // set rounding mode with zero increment. Rounding // increment should not be set by this operation pat.setRoundingMode((DecimalFormat::ERoundingMode)0); roundingInc = pat.getRoundingIncrement(); @@ -566,7 +572,7 @@ void IntlTestDecimalFormatAPI::TestScale() } pat.setAttribute(UNUM_SCALE,testData[i].inputScale,status); pat.format(testData[i].inputValue, resultStr); - message = UnicodeString("Unexpected output for ") + testData[i].inputValue + UnicodeString(" and scale ") + + message = UnicodeString("Unexpected output for ") + testData[i].inputValue + UnicodeString(" and scale ") + testData[i].inputScale + UnicodeString(". Got: "); exp = testData[i].expectedOutput; verifyString(message, resultStr, exp); @@ -792,5 +798,22 @@ void IntlTestDecimalFormatAPI::TestFixedDecimal() { ASSERT_EQUAL(FALSE, fd.isNegative); } - -#endif /* #if !UCONFIG_NO_FORMATTING */ + +void IntlTestDecimalFormatAPI::TestBadFastpath() { + UErrorCode status = U_ZERO_ERROR; + + LocalPointer df(new DecimalFormat("###", status)); + TEST_ASSERT_STATUS(status); + + UnicodeString fmt; + fmt.remove(); + assertEquals("Format 1234", "1234", df->format(1234, fmt)); + df->setGroupingUsed(FALSE); + fmt.remove(); + assertEquals("Format 1234", "1234", df->format(1234, fmt)); + df->setGroupingUsed(TRUE); + fmt.remove(); + assertEquals("Format 1234 w/ grouping", "1,234", df->format(1234, fmt)); +} + +#endif /* #if !UCONFIG_NO_FORMATTING */x diff --git a/icu4c/source/test/intltest/dcfmapts.h b/icu4c/source/test/intltest/dcfmapts.h index d13a2d7ae05..10be89fab25 100644 --- a/icu4c/source/test/intltest/dcfmapts.h +++ b/icu4c/source/test/intltest/dcfmapts.h @@ -1,6 +1,6 @@ /******************************************************************** - * COPYRIGHT: - * Copyright (c) 1997-2013, International Business Machines Corporation and + * COPYRIGHT: + * Copyright (c) 1997-2014, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -17,7 +17,7 @@ class IntlTestDecimalFormatAPI: public IntlTest { - void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); + void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); public: /** @@ -29,6 +29,7 @@ public: void TestCurrencyPluralInfo(); void TestScale(); void TestFixedDecimal(); + void TestBadFastpath(); private: /*Helper functions */ void verify(const UnicodeString& message, const UnicodeString& got, double expected);