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
This commit is contained in:
Steven R. Loomis 2014-03-06 00:12:57 +00:00
parent 4c308228b1
commit f38544a2a6
4 changed files with 102 additions and 28 deletions

View File

@ -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) {

View File

@ -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<UNumberFormatAttribute,
UNUM_MAX_NONBOOLEAN_ATTRIBUTE+1,
UNUM_MAX_NONBOOLEAN_ATTRIBUTE+1,
UNUM_LIMIT_BOOLEAN_ATTRIBUTE>;
#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<UNumberFormatAttribute,
UNUM_MAX_NONBOOLEAN_ATTRIBUTE+1,
UNUM_LIMIT_BOOLEAN_ATTRIBUTE>
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];

View File

@ -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<DecimalFormat> 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

View File

@ -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);