mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 22:44:49 +00:00
ICU-13740 Moving ICU4C data-driven number test to its own file, like in Java. De-clutters numfmtst.cpp. No behavior changes.
X-SVN-Rev: 41397
This commit is contained in:
parent
50bdd810ef
commit
649ce80f42
6 changed files with 540 additions and 541 deletions
|
@ -66,7 +66,7 @@ numbertest_affixutils.o numbertest_api.o numbertest_decimalquantity.o \
|
|||
numbertest_modifiers.o numbertest_patternmodifier.o numbertest_patternstring.o \
|
||||
numbertest_stringbuilder.o numbertest_stringsegment.o \
|
||||
numbertest_parse.o numbertest_doubleconversion.o numbertest_skeletons.o \
|
||||
static_unisets_test.o
|
||||
static_unisets_test.o numfmtdatadriventest.o
|
||||
|
||||
DEPS = $(OBJECTS:.o=.d)
|
||||
|
||||
|
|
|
@ -257,6 +257,7 @@
|
|||
<ClCompile Include="numbertest_doubleconversion.cpp" />
|
||||
<ClCompile Include="numbertest_skeletons.cpp" />
|
||||
<ClCompile Include="numfmtst.cpp" />
|
||||
<ClCompile Include="numfmtdatadriventest.cpp" />
|
||||
<ClCompile Include="numrgts.cpp" />
|
||||
<ClCompile Include="pluralmaptest.cpp" />
|
||||
<ClCompile Include="plurfmts.cpp" />
|
||||
|
|
|
@ -292,6 +292,9 @@
|
|||
<ClCompile Include="numfmtst.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="numfmtdatadriventest.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="numrgts.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
|
|
505
icu4c/source/test/intltest/numfmtdatadriventest.cpp
Normal file
505
icu4c/source/test/intltest/numfmtdatadriventest.cpp
Normal file
|
@ -0,0 +1,505 @@
|
|||
// © 2018 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "numfmtst.h"
|
||||
#include "number_decimalquantity.h"
|
||||
#include "putilimp.h"
|
||||
#include "charstr.h"
|
||||
#include <cmath>
|
||||
|
||||
using icu::number::impl::DecimalQuantity;
|
||||
|
||||
void NumberFormatDataDrivenTest::runIndexedTest(int32_t index, UBool exec, const char*& name, char*) {
|
||||
if (exec) {
|
||||
logln("TestSuite NumberFormatDataDrivenTest: ");
|
||||
}
|
||||
TESTCASE_AUTO_BEGIN;
|
||||
TESTCASE_AUTO(TestNumberFormatTestTuple);
|
||||
TESTCASE_AUTO(TestDataDrivenICU4C);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
static DecimalQuantity&
|
||||
strToDigitList(const UnicodeString& str, DecimalQuantity& digitList, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return digitList;
|
||||
}
|
||||
if (str == "NaN") {
|
||||
digitList.setToDouble(uprv_getNaN());
|
||||
return digitList;
|
||||
}
|
||||
if (str == "-Inf") {
|
||||
digitList.setToDouble(-1 * uprv_getInfinity());
|
||||
return digitList;
|
||||
}
|
||||
if (str == "Inf") {
|
||||
digitList.setToDouble(uprv_getInfinity());
|
||||
return digitList;
|
||||
}
|
||||
CharString formatValue;
|
||||
formatValue.appendInvariantChars(str, status);
|
||||
digitList.setToDecNumber({formatValue.data(), formatValue.length()}, status);
|
||||
return digitList;
|
||||
}
|
||||
|
||||
static UnicodeString&
|
||||
format(const DecimalFormat& fmt, const DecimalQuantity& 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.signAlwaysShownFlag) {
|
||||
fmt.setSignAlwaysShown(tuple.signAlwaysShown != 0);
|
||||
}
|
||||
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.");
|
||||
}
|
||||
}
|
||||
if (tuple.parseCaseSensitiveFlag) {
|
||||
fmt.setParseCaseSensitive(tuple.parseCaseSensitive != 0);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
UBool NumberFormatDataDrivenTest::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;
|
||||
}
|
||||
DecimalQuantity 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.toDouble();
|
||||
DecimalQuantity doubleCheck;
|
||||
doubleCheck.setToDouble(doubleVal);
|
||||
if (digitList == doubleCheck) { // skip cases where the double does not round-trip
|
||||
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) && digitList.fitsInLong()) {
|
||||
int64_t intVal = digitList.toLong();
|
||||
{
|
||||
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 NumberFormatDataDrivenTest::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 NumberFormatDataDrivenTest::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) {
|
||||
appendErrorMessage.append("Parse failed; got error index ");
|
||||
appendErrorMessage = appendErrorMessage + ppos.getErrorIndex();
|
||||
return FALSE;
|
||||
}
|
||||
if (tuple.output == "fail") {
|
||||
appendErrorMessage.append(
|
||||
UnicodeString("Parse succeeded: ") + result.getDouble() + ", but was expected to fail.");
|
||||
return TRUE; // TRUE because failure handling is in the test suite
|
||||
}
|
||||
if (tuple.output == "NaN") {
|
||||
if (!uprv_isNaN(result.getDouble())) {
|
||||
appendErrorMessage.append(UnicodeString("Expected NaN, but got: ") + result.getDouble());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
} else if (tuple.output == "Inf") {
|
||||
if (!uprv_isInfinite(result.getDouble()) || result.getDouble() < 0) {
|
||||
appendErrorMessage.append(UnicodeString("Expected Inf, but got: ") + result.getDouble());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
} else if (tuple.output == "-Inf") {
|
||||
if (!uprv_isInfinite(result.getDouble()) || result.getDouble() > 0) {
|
||||
appendErrorMessage.append(UnicodeString("Expected -Inf, but got: ") + result.getDouble());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
} else if (tuple.output == "-0.0") {
|
||||
if (!std::signbit(result.getDouble()) || result.getDouble() != 0) {
|
||||
appendErrorMessage.append(UnicodeString("Expected -0.0, but got: ") + result.getDouble());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
// All other cases parse to a DecimalQuantity, not a double.
|
||||
|
||||
DecimalQuantity expectedQuantity;
|
||||
strToDigitList(tuple.output, expectedQuantity, status);
|
||||
UnicodeString expectedString = expectedQuantity.toScientificString();
|
||||
if (U_FAILURE(status)) {
|
||||
appendErrorMessage.append("[Error parsing decnumber] ");
|
||||
// If this happens, assume that tuple.output is exactly the same format as
|
||||
// DecimalQuantity.toScientificString()
|
||||
expectedString = tuple.output;
|
||||
status = U_ZERO_ERROR;
|
||||
}
|
||||
UnicodeString actualString = result.getDecimalQuantity()->toScientificString();
|
||||
if (expectedString != actualString) {
|
||||
appendErrorMessage.append(
|
||||
UnicodeString("Expected: ") + tuple.output + " (i.e., " + expectedString + "), but got: " +
|
||||
actualString + " (" + ppos.getIndex() + ":" + ppos.getErrorIndex() + ")");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UBool NumberFormatDataDrivenTest::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) {
|
||||
appendErrorMessage.append("Parse failed; got error index ");
|
||||
appendErrorMessage = appendErrorMessage + ppos.getErrorIndex();
|
||||
return FALSE;
|
||||
}
|
||||
UnicodeString currStr(currAmt->getISOCurrency());
|
||||
U_ASSERT(currAmt->getNumber().getDecimalQuantity() != nullptr); // no doubles in currency tests
|
||||
UnicodeString resultStr = currAmt->getNumber().getDecimalQuantity()->toScientificString();
|
||||
if (tuple.output == "fail") {
|
||||
appendErrorMessage.append(
|
||||
UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail.");
|
||||
return TRUE; // TRUE because failure handling is in the test suite
|
||||
}
|
||||
|
||||
DecimalQuantity expectedQuantity;
|
||||
strToDigitList(tuple.output, expectedQuantity, status);
|
||||
UnicodeString expectedString = expectedQuantity.toScientificString();
|
||||
if (U_FAILURE(status)) {
|
||||
appendErrorMessage.append("Error parsing decnumber");
|
||||
// If this happens, assume that tuple.output is exactly the same format as
|
||||
// DecimalQuantity.toNumberString()
|
||||
expectedString = tuple.output;
|
||||
status = U_ZERO_ERROR;
|
||||
}
|
||||
if (expectedString != resultStr) {
|
||||
appendErrorMessage.append(
|
||||
UnicodeString("Expected: ") + tuple.output + " (i.e., " + expectedString + "), but got: " +
|
||||
resultStr + " (" + ppos.getIndex() + ":" + ppos.getErrorIndex() + ")");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (currStr != tuple.outputCurrency) {
|
||||
appendErrorMessage.append(
|
||||
UnicodeString(
|
||||
"Expected currency: ") + tuple.outputCurrency + ", got: " + currStr + ". ");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void NumberFormatDataDrivenTest::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 NumberFormatDataDrivenTest::TestDataDrivenICU4C() {
|
||||
run("numberformattestspecification.txt", TRUE);
|
||||
}
|
||||
|
||||
#endif // !UCONFIG_NO_FORMATTING
|
|
@ -39,7 +39,6 @@
|
|||
#include "unicode/numsys.h"
|
||||
#include "fmtableimp.h"
|
||||
#include "numberformattesttuple.h"
|
||||
#include "datadrivennumberformattestsuite.h"
|
||||
#include "unicode/msgfmt.h"
|
||||
#include "number_decimalquantity.h"
|
||||
#include "unicode/numberformatter.h"
|
||||
|
@ -68,476 +67,6 @@ namespace std {
|
|||
using icu::number::impl::DecimalQuantity;
|
||||
using namespace icu::number;
|
||||
|
||||
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 DecimalQuantity &strToDigitList(
|
||||
const UnicodeString &str,
|
||||
DecimalQuantity &digitList,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return digitList;
|
||||
}
|
||||
if (str == "NaN") {
|
||||
digitList.setToDouble(uprv_getNaN());
|
||||
return digitList;
|
||||
}
|
||||
if (str == "-Inf") {
|
||||
digitList.setToDouble(-1*uprv_getInfinity());
|
||||
return digitList;
|
||||
}
|
||||
if (str == "Inf") {
|
||||
digitList.setToDouble(uprv_getInfinity());
|
||||
return digitList;
|
||||
}
|
||||
CharString formatValue;
|
||||
formatValue.appendInvariantChars(str, status);
|
||||
digitList.setToDecNumber({formatValue.data(), formatValue.length()}, status);
|
||||
return digitList;
|
||||
}
|
||||
|
||||
static UnicodeString &format(
|
||||
const DecimalFormat &fmt,
|
||||
const DecimalQuantity &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.signAlwaysShownFlag) {
|
||||
fmt.setSignAlwaysShown(tuple.signAlwaysShown != 0);
|
||||
}
|
||||
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.");
|
||||
}
|
||||
}
|
||||
if (tuple.parseCaseSensitiveFlag) {
|
||||
fmt.setParseCaseSensitive(tuple.parseCaseSensitive != 0);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
DecimalQuantity 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.toDouble();
|
||||
DecimalQuantity doubleCheck;
|
||||
doubleCheck.setToDouble(doubleVal);
|
||||
if (digitList == doubleCheck) { // skip cases where the double does not round-trip
|
||||
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) && digitList.fitsInLong()) {
|
||||
int64_t intVal = digitList.toLong();
|
||||
{
|
||||
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) {
|
||||
appendErrorMessage.append("Parse failed; got error index ");
|
||||
appendErrorMessage = appendErrorMessage + ppos.getErrorIndex();
|
||||
return FALSE;
|
||||
}
|
||||
if (tuple.output == "fail") {
|
||||
appendErrorMessage.append(UnicodeString("Parse succeeded: ") + result.getDouble() + ", but was expected to fail.");
|
||||
return TRUE; // TRUE because failure handling is in the test suite
|
||||
}
|
||||
if (tuple.output == "NaN") {
|
||||
if (!uprv_isNaN(result.getDouble())) {
|
||||
appendErrorMessage.append(UnicodeString("Expected NaN, but got: ") + result.getDouble());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
} else if (tuple.output == "Inf") {
|
||||
if (!uprv_isInfinite(result.getDouble()) || result.getDouble() < 0) {
|
||||
appendErrorMessage.append(UnicodeString("Expected Inf, but got: ") + result.getDouble());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
} else if (tuple.output == "-Inf") {
|
||||
if (!uprv_isInfinite(result.getDouble()) || result.getDouble() > 0) {
|
||||
appendErrorMessage.append(UnicodeString("Expected -Inf, but got: ") + result.getDouble());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
} else if (tuple.output == "-0.0") {
|
||||
if (!std::signbit(result.getDouble()) || result.getDouble() != 0) {
|
||||
appendErrorMessage.append(UnicodeString("Expected -0.0, but got: ") + result.getDouble());
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
// All other cases parse to a DecimalQuantity, not a double.
|
||||
|
||||
DecimalQuantity expectedQuantity;
|
||||
strToDigitList(tuple.output, expectedQuantity, status);
|
||||
UnicodeString expectedString = expectedQuantity.toScientificString();
|
||||
if (U_FAILURE(status)) {
|
||||
appendErrorMessage.append("[Error parsing decnumber] ");
|
||||
// If this happens, assume that tuple.output is exactly the same format as
|
||||
// DecimalQuantity.toScientificString()
|
||||
expectedString = tuple.output;
|
||||
status = U_ZERO_ERROR;
|
||||
}
|
||||
UnicodeString actualString = result.getDecimalQuantity()->toScientificString();
|
||||
if (expectedString != actualString) {
|
||||
appendErrorMessage.append(
|
||||
UnicodeString("Expected: ") + tuple.output + " (i.e., " + expectedString + "), but got: " +
|
||||
actualString + " (" + ppos.getIndex() + ":" + ppos.getErrorIndex() + ")");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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) {
|
||||
appendErrorMessage.append("Parse failed; got error index ");
|
||||
appendErrorMessage = appendErrorMessage + ppos.getErrorIndex();
|
||||
return FALSE;
|
||||
}
|
||||
UnicodeString currStr(currAmt->getISOCurrency());
|
||||
U_ASSERT(currAmt->getNumber().getDecimalQuantity() != nullptr); // no doubles in currency tests
|
||||
UnicodeString resultStr = currAmt->getNumber().getDecimalQuantity()->toScientificString();
|
||||
if (tuple.output == "fail") {
|
||||
appendErrorMessage.append(UnicodeString("Parse succeeded: ") + resultStr + ", but was expected to fail.");
|
||||
return TRUE; // TRUE because failure handling is in the test suite
|
||||
}
|
||||
|
||||
DecimalQuantity expectedQuantity;
|
||||
strToDigitList(tuple.output, expectedQuantity, status);
|
||||
UnicodeString expectedString = expectedQuantity.toScientificString();
|
||||
if (U_FAILURE(status)) {
|
||||
appendErrorMessage.append("Error parsing decnumber");
|
||||
// If this happens, assume that tuple.output is exactly the same format as
|
||||
// DecimalQuantity.toNumberString()
|
||||
expectedString = tuple.output;
|
||||
status = U_ZERO_ERROR;
|
||||
}
|
||||
if (expectedString != resultStr) {
|
||||
appendErrorMessage.append(
|
||||
UnicodeString("Expected: ") + tuple.output + " (i.e., " + expectedString + "), but got: " +
|
||||
resultStr + " (" + ppos.getIndex() + ":" + ppos.getErrorIndex() + ")");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (currStr != tuple.outputCurrency) {
|
||||
appendErrorMessage.append(UnicodeString(
|
||||
"Expected currency: ") + tuple.outputCurrency + ", got: " + currStr + ". ");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//#define NUMFMTST_CACHE_DEBUG 1
|
||||
#include "stdio.h" /* for sprintf */
|
||||
// #include "iostream" // for cout
|
||||
|
@ -640,8 +169,6 @@ 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(TestGetAffixes);
|
||||
TESTCASE_AUTO(TestToPatternScientific11648);
|
||||
|
@ -8474,71 +8001,6 @@ void NumberFormatTest::TestCurrencyUsage() {
|
|||
}
|
||||
}
|
||||
|
||||
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", TRUE);
|
||||
}
|
||||
|
||||
|
||||
// Check the constant MAX_INT64_IN_DOUBLE.
|
||||
// The value should convert to a double with no loss of precision.
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "unicode/numfmt.h"
|
||||
#include "unicode/decimfmt.h"
|
||||
#include "caltztst.h"
|
||||
#include "datadrivennumberformattestsuite.h"
|
||||
|
||||
/**
|
||||
* Expected field positions from field position iterator. Tests should
|
||||
|
@ -30,6 +31,35 @@ struct NumberFormatTest_Attributes {
|
|||
int32_t epos;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Header for the data-driven test, powered by numberformattestspecification.txt
|
||||
*/
|
||||
class NumberFormatDataDrivenTest : public DataDrivenNumberFormatTestSuite {
|
||||
public:
|
||||
void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par );
|
||||
void TestNumberFormatTestTuple();
|
||||
void TestDataDrivenICU4C();
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs various in-depth test on NumberFormat
|
||||
**/
|
||||
|
@ -200,8 +230,6 @@ class NumberFormatTest: public CalendarTimeZoneTest {
|
|||
void TestEquality();
|
||||
|
||||
void TestCurrencyUsage();
|
||||
void TestNumberFormatTestTuple();
|
||||
void TestDataDriven();
|
||||
|
||||
void TestDoubleLimit11439();
|
||||
void TestFastPathConsistent11524();
|
||||
|
|
Loading…
Add table
Reference in a new issue