You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
11 KiB
381 lines
11 KiB
// © 2017 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
|
|
#include "unicode/utypes.h"
|
|
|
|
#if !UCONFIG_NO_FORMATTING
|
|
#pragma once
|
|
|
|
#include "formatted_string_builder.h"
|
|
#include "intltest.h"
|
|
#include "itformat.h"
|
|
#include "number_affixutils.h"
|
|
#include "string_segment.h"
|
|
#include "numrange_impl.h"
|
|
#include "unicode/locid.h"
|
|
#include "unicode/numberformatter.h"
|
|
#include "unicode/numberrangeformatter.h"
|
|
|
|
// ICU-20241 Solaris #defines ESP in sys/regset.h
|
|
#ifdef ESP
|
|
# undef ESP
|
|
#endif
|
|
|
|
using namespace icu::number;
|
|
using namespace icu::number::impl;
|
|
using namespace icu::numparse;
|
|
using namespace icu::numparse::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();
|
|
void testUnescape();
|
|
void testContainsReplaceType();
|
|
void testInvalid();
|
|
void testUnescapeWithSymbolProvider();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
|
|
private:
|
|
UnicodeString unescapeWithDefaults(const SymbolProvider &defaultProvider, UnicodeString input,
|
|
UErrorCode &status);
|
|
};
|
|
|
|
class NumberFormatterApiTest : public IntlTestWithFieldPosition {
|
|
public:
|
|
NumberFormatterApiTest();
|
|
NumberFormatterApiTest(UErrorCode &status);
|
|
|
|
void notationSimple();
|
|
void notationScientific();
|
|
void notationCompact();
|
|
void unitMeasure();
|
|
void unitCompoundMeasure();
|
|
void unitSkeletons();
|
|
void unitUsage();
|
|
void unitUsageErrorCodes();
|
|
void unitUsageSkeletons();
|
|
void unitCurrency();
|
|
void unitPercent();
|
|
void percentParity();
|
|
void roundingFraction();
|
|
void roundingFigures();
|
|
void roundingFractionFigures();
|
|
void roundingOther();
|
|
void grouping();
|
|
void padding();
|
|
void integerWidth();
|
|
void symbols();
|
|
// TODO: Add this method if currency symbols override support is added.
|
|
//void symbolsOverride();
|
|
void sign();
|
|
void signNearZero();
|
|
void signCoverage();
|
|
void decimal();
|
|
void scale();
|
|
void locale();
|
|
void skeletonUserGuideExamples();
|
|
void formatTypes();
|
|
void fieldPositionLogic();
|
|
void fieldPositionCoverage();
|
|
void toFormat();
|
|
void errors();
|
|
void validRanges();
|
|
void copyMove();
|
|
void localPointerCAPI();
|
|
void toObject();
|
|
void toDecimalNumber();
|
|
void microPropsInternals();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
|
|
private:
|
|
CurrencyUnit USD;
|
|
CurrencyUnit GBP;
|
|
CurrencyUnit CZK;
|
|
CurrencyUnit CAD;
|
|
CurrencyUnit ESP;
|
|
CurrencyUnit PTE;
|
|
CurrencyUnit RON;
|
|
CurrencyUnit TWD;
|
|
CurrencyUnit TRY;
|
|
CurrencyUnit CNY;
|
|
|
|
MeasureUnit METER;
|
|
MeasureUnit METER_PER_SECOND;
|
|
MeasureUnit DAY;
|
|
MeasureUnit SQUARE_METER;
|
|
MeasureUnit FAHRENHEIT;
|
|
MeasureUnit SECOND;
|
|
MeasureUnit POUND;
|
|
MeasureUnit POUND_FORCE;
|
|
MeasureUnit SQUARE_MILE;
|
|
MeasureUnit SQUARE_INCH;
|
|
MeasureUnit JOULE;
|
|
MeasureUnit FURLONG;
|
|
MeasureUnit KELVIN;
|
|
|
|
NumberingSystem MATHSANB;
|
|
NumberingSystem LATN;
|
|
|
|
DecimalFormatSymbols FRENCH_SYMBOLS;
|
|
DecimalFormatSymbols SWISS_SYMBOLS;
|
|
DecimalFormatSymbols MYANMAR_SYMBOLS;
|
|
|
|
/**
|
|
* skeleton is the full length skeleton, which must round-trip.
|
|
*
|
|
* conciseSkeleton should be the shortest available skeleton.
|
|
* The concise skeleton can be read but not printed.
|
|
*/
|
|
void assertFormatDescending(
|
|
const char16_t* message,
|
|
const char16_t* skeleton,
|
|
const char16_t* conciseSkeleton,
|
|
const UnlocalizedNumberFormatter& f,
|
|
Locale locale,
|
|
...);
|
|
|
|
/** See notes above regarding skeleton vs conciseSkeleton */
|
|
void assertFormatDescendingBig(
|
|
const char16_t* message,
|
|
const char16_t* skeleton,
|
|
const char16_t* conciseSkeleton,
|
|
const UnlocalizedNumberFormatter& f,
|
|
Locale locale,
|
|
...);
|
|
|
|
/** See notes above regarding skeleton vs conciseSkeleton */
|
|
FormattedNumber assertFormatSingle(
|
|
const char16_t* message,
|
|
const char16_t* skeleton,
|
|
const char16_t* conciseSkeleton,
|
|
const UnlocalizedNumberFormatter& f,
|
|
Locale locale,
|
|
double input,
|
|
const UnicodeString& expected);
|
|
|
|
void assertUndefinedSkeleton(const UnlocalizedNumberFormatter& f);
|
|
|
|
void assertNumberFieldPositions(
|
|
const char16_t* message,
|
|
const FormattedNumber& formattedNumber,
|
|
const UFieldPosition* expectedFieldPositions,
|
|
int32_t length);
|
|
};
|
|
|
|
class DecimalQuantityTest : public IntlTest {
|
|
public:
|
|
void testDecimalQuantityBehaviorStandalone();
|
|
void testSwitchStorage();
|
|
void testCopyMove();
|
|
void testAppend();
|
|
void testConvertToAccurateDouble();
|
|
void testUseApproximateDoubleWhenAble();
|
|
void testHardDoubleConversion();
|
|
void testToDouble();
|
|
void testMaxDigits();
|
|
void testNickelRounding();
|
|
void testCompactDecimalSuppressedExponent();
|
|
void testSuppressedExponentUnchangedByInitialScaling();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
|
|
private:
|
|
void assertDoubleEquals(UnicodeString message, double a, double b);
|
|
void assertHealth(const DecimalQuantity &fq);
|
|
void assertToStringAndHealth(const DecimalQuantity &fq, const UnicodeString &expected);
|
|
void checkDoubleBehavior(double d, bool explicitRequired);
|
|
};
|
|
|
|
class DoubleConversionTest : public IntlTest {
|
|
public:
|
|
void testDoubleConversionApi();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
};
|
|
|
|
class ModifiersTest : public IntlTest {
|
|
public:
|
|
void testConstantAffixModifier();
|
|
void testConstantMultiFieldModifier();
|
|
void testSimpleModifier();
|
|
void testCurrencySpacingEnabledModifier();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
|
|
private:
|
|
void assertModifierEquals(const Modifier &mod, int32_t expectedPrefixLength, bool expectedStrong,
|
|
UnicodeString expectedChars, UnicodeString expectedFields,
|
|
UErrorCode &status);
|
|
|
|
void assertModifierEquals(const Modifier &mod, FormattedStringBuilder &sb, int32_t expectedPrefixLength,
|
|
bool expectedStrong, UnicodeString expectedChars,
|
|
UnicodeString expectedFields, UErrorCode &status);
|
|
};
|
|
|
|
class PatternModifierTest : public IntlTest {
|
|
public:
|
|
void testBasic();
|
|
void testPatternWithNoPlaceholder();
|
|
void testMutableEqualsImmutable();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
|
|
private:
|
|
UnicodeString getPrefix(const MutablePatternModifier &mod, UErrorCode &status);
|
|
UnicodeString getSuffix(const MutablePatternModifier &mod, UErrorCode &status);
|
|
};
|
|
|
|
class PatternStringTest : public IntlTest {
|
|
public:
|
|
void testLocalized();
|
|
void testToPatternSimple();
|
|
void testExceptionOnInvalid();
|
|
void testBug13117();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
|
|
private:
|
|
};
|
|
|
|
class NumberParserTest : public IntlTest {
|
|
public:
|
|
void testBasic();
|
|
void testLocaleFi();
|
|
void testSeriesMatcher();
|
|
void testCombinedCurrencyMatcher();
|
|
void testAffixPatternMatcher();
|
|
void testGroupingDisabled();
|
|
void testCaseFolding();
|
|
void test20360_BidiOverflow();
|
|
void testInfiniteRecursion();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
};
|
|
|
|
class NumberSkeletonTest : public IntlTest {
|
|
public:
|
|
void validTokens();
|
|
void invalidTokens();
|
|
void unknownTokens();
|
|
void unexpectedTokens();
|
|
void duplicateValues();
|
|
void stemsRequiringOption();
|
|
void defaultTokens();
|
|
void flexibleSeparators();
|
|
void wildcardCharacters();
|
|
void perUnitInArabic();
|
|
void perUnitToSkeleton();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
|
|
private:
|
|
void expectedErrorSkeleton(const char16_t** cases, int32_t casesLen);
|
|
};
|
|
|
|
class NumberRangeFormatterTest : public IntlTestWithFieldPosition {
|
|
public:
|
|
NumberRangeFormatterTest();
|
|
NumberRangeFormatterTest(UErrorCode &status);
|
|
|
|
void testSanity();
|
|
void testBasic();
|
|
void testCollapse();
|
|
void testIdentity();
|
|
void testDifferentFormatters();
|
|
void testPlurals();
|
|
void testFieldPositions();
|
|
void testCopyMove();
|
|
void toObject();
|
|
void testGetDecimalNumbers();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
|
|
private:
|
|
CurrencyUnit USD;
|
|
CurrencyUnit GBP;
|
|
CurrencyUnit PTE;
|
|
|
|
MeasureUnit METER;
|
|
MeasureUnit KILOMETER;
|
|
MeasureUnit FAHRENHEIT;
|
|
MeasureUnit KELVIN;
|
|
|
|
void assertFormatRange(
|
|
const char16_t* message,
|
|
const UnlocalizedNumberRangeFormatter& f,
|
|
Locale locale,
|
|
const char16_t* expected_10_50,
|
|
const char16_t* expected_49_51,
|
|
const char16_t* expected_50_50,
|
|
const char16_t* expected_00_30,
|
|
const char16_t* expected_00_00,
|
|
const char16_t* expected_30_3K,
|
|
const char16_t* expected_30K_50K,
|
|
const char16_t* expected_49K_51K,
|
|
const char16_t* expected_50K_50K,
|
|
const char16_t* expected_50K_50M);
|
|
|
|
FormattedNumberRange assertFormattedRangeEquals(
|
|
const char16_t* message,
|
|
const LocalizedNumberRangeFormatter& l,
|
|
double first,
|
|
double second,
|
|
const char16_t* expected);
|
|
};
|
|
|
|
class NumberPermutationTest : public IntlTest {
|
|
public:
|
|
void testPermutations();
|
|
|
|
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
|
|
};
|
|
|
|
|
|
// 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, DoubleConversionTest);
|
|
TESTCLASS(7, NumberParserTest);
|
|
TESTCLASS(8, NumberSkeletonTest);
|
|
TESTCLASS(9, NumberRangeFormatterTest);
|
|
TESTCLASS(10, NumberPermutationTest);
|
|
default: name = ""; break; // needed to end loop
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif /* #if !UCONFIG_NO_FORMATTING */
|