Frank Tang | 3e05d9d | 2021-11-08 14:04:04 -0800 | [diff] [blame] | 1 | // © 2016 and later: Unicode, Inc. and others. |
| 2 | // License & terms of use: http://www.unicode.org/copyright.html |
| 3 | /************************************************************************ |
| 4 | * COPYRIGHT: |
| 5 | * Copyright (c) 1997-2016, International Business Machines Corporation |
| 6 | * and others. All Rights Reserved. |
| 7 | ************************************************************************/ |
| 8 | |
| 9 | #ifndef _NUMBERFORMATTEST_ |
| 10 | #define _NUMBERFORMATTEST_ |
| 11 | |
| 12 | #include "unicode/utypes.h" |
| 13 | |
| 14 | #if !UCONFIG_NO_FORMATTING |
| 15 | |
| 16 | #include "unicode/numfmt.h" |
| 17 | #include "unicode/decimfmt.h" |
| 18 | #include "caltztst.h" |
| 19 | #include "datadrivennumberformattestsuite.h" |
| 20 | |
| 21 | /** |
| 22 | * Expected field positions from field position iterator. Tests should |
| 23 | * stack allocate an array of these making sure that the last element is |
| 24 | * {0, -1, 0} (The sentinel element indicating end of iterator). Then test |
| 25 | * should call verifyFieldPositionIterator() passing both this array of |
| 26 | * expected results and the field position iterator from the format method. |
| 27 | */ |
| 28 | struct NumberFormatTest_Attributes { |
| 29 | int32_t id; |
| 30 | int32_t spos; |
| 31 | int32_t epos; |
| 32 | }; |
| 33 | |
| 34 | |
| 35 | /** |
| 36 | * Header for the data-driven test, powered by numberformattestspecification.txt |
| 37 | */ |
| 38 | class NumberFormatDataDrivenTest : public DataDrivenNumberFormatTestSuite { |
| 39 | public: |
| 40 | void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par ) override; |
| 41 | void TestNumberFormatTestTuple(); |
| 42 | void TestDataDrivenICU4C(); |
| 43 | |
| 44 | protected: |
| 45 | UBool isFormatPass( |
| 46 | const NumberFormatTestTuple &tuple, |
| 47 | UnicodeString &appendErrorMessage, |
| 48 | UErrorCode &status) override; |
| 49 | UBool isToPatternPass( |
| 50 | const NumberFormatTestTuple &tuple, |
| 51 | UnicodeString &appendErrorMessage, |
| 52 | UErrorCode &status) override; |
| 53 | UBool isParsePass( |
| 54 | const NumberFormatTestTuple &tuple, |
| 55 | UnicodeString &appendErrorMessage, |
| 56 | UErrorCode &status) override; |
| 57 | UBool isParseCurrencyPass( |
| 58 | const NumberFormatTestTuple &tuple, |
| 59 | UnicodeString &appendErrorMessage, |
| 60 | UErrorCode &status) override; |
| 61 | }; |
| 62 | |
| 63 | /** |
| 64 | * Performs various in-depth test on NumberFormat |
| 65 | **/ |
| 66 | class NumberFormatTest: public CalendarTimeZoneTest { |
| 67 | |
| 68 | // IntlTest override |
| 69 | void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par ) override; |
| 70 | public: |
| 71 | |
| 72 | /** |
| 73 | * Test APIs (to increase code coverage) |
| 74 | */ |
| 75 | void TestAPI(void); |
| 76 | |
| 77 | void TestCoverage(void); |
| 78 | void TestLocalizedPatternSymbolCoverage(); |
| 79 | |
| 80 | /** |
| 81 | * Test the handling of quotes |
| 82 | **/ |
| 83 | void TestQuotes(void); |
| 84 | /** |
| 85 | * Test patterns with exponential representation |
| 86 | **/ |
| 87 | void TestExponential(void); |
| 88 | /** |
| 89 | * Test handling of patterns with currency symbols |
| 90 | **/ |
| 91 | void TestCurrencySign(void); |
| 92 | /** |
| 93 | * Test different format patterns |
| 94 | **/ |
| 95 | void TestPatterns(void); |
| 96 | /** |
| 97 | * API coverage for DigitList |
| 98 | **/ |
| 99 | //void TestDigitList(void); |
| 100 | |
| 101 | void Test20186_SpacesAroundSemicolon(void); |
| 102 | |
| 103 | /** |
| 104 | * Test localized currency patterns. |
| 105 | */ |
| 106 | void TestCurrency(void); |
| 107 | |
| 108 | /** |
| 109 | * Test the Currency object handling, new as of ICU 2.2. |
| 110 | */ |
| 111 | void TestCurrencyObject(void); |
| 112 | |
| 113 | void TestCurrencyPatterns(void); |
| 114 | |
| 115 | /** |
| 116 | * Do rudimentary testing of parsing. |
| 117 | */ |
| 118 | void TestParse(void); |
| 119 | /** |
| 120 | * Test proper rounding by the format method. |
| 121 | */ |
| 122 | void TestRounding487(void); |
| 123 | |
| 124 | // New tests for alphaWorks upgrade |
| 125 | void TestExponent(void); |
| 126 | |
| 127 | void TestScientific(void); |
| 128 | |
| 129 | void TestScientific2(void); |
| 130 | |
| 131 | void TestScientificGrouping(void); |
| 132 | |
| 133 | void TestInt64(void); |
| 134 | |
| 135 | void TestSurrogateSupport(void); |
| 136 | |
| 137 | /** |
| 138 | * Test the functioning of the secondary grouping value. |
| 139 | */ |
| 140 | void TestSecondaryGrouping(void); |
| 141 | |
| 142 | void TestWhiteSpaceParsing(void); |
| 143 | |
| 144 | void TestComplexCurrency(void); |
| 145 | |
| 146 | void TestPad(void); |
| 147 | void TestPatterns2(void); |
| 148 | |
| 149 | /** |
| 150 | * Test currency registration. |
| 151 | */ |
| 152 | void TestRegCurrency(void); |
| 153 | |
| 154 | void TestCurrencyNames(void); |
| 155 | |
| 156 | void TestCurrencyVariants(void); |
| 157 | |
| 158 | void TestCurrencyAmount(void); |
| 159 | |
| 160 | void TestCurrencyUnit(void); |
| 161 | |
| 162 | void TestSymbolsWithBadLocale(void); |
| 163 | |
| 164 | void TestAdoptDecimalFormatSymbols(void); |
| 165 | |
| 166 | void TestPerMill(void); |
| 167 | |
| 168 | void TestIllegalPatterns(void); |
| 169 | |
| 170 | void TestCases(void); |
| 171 | |
| 172 | void TestJB3832(void); |
| 173 | |
| 174 | void TestHost(void); |
| 175 | |
| 176 | void TestHostClone(void); |
| 177 | |
| 178 | void TestCurrencyFormat(void); |
| 179 | |
| 180 | /* Port of ICU4J rounding test. */ |
| 181 | void TestRounding(void); |
| 182 | |
| 183 | void TestRoundingPattern(void); |
| 184 | |
| 185 | void TestNonpositiveMultiplier(void); |
| 186 | |
| 187 | void TestNumberingSystems(); |
| 188 | |
| 189 | |
| 190 | void TestSpaceParsing(); |
| 191 | void TestMultiCurrencySign(); |
| 192 | void TestCurrencyFormatForMixParsing(); |
| 193 | void TestMismatchedCurrencyFormatFail(); |
| 194 | void TestDecimalFormatCurrencyParse(); |
| 195 | void TestCurrencyIsoPluralFormat(); |
| 196 | void TestCurrencyParsing(); |
| 197 | void TestParseCurrencyInUCurr(); |
| 198 | void TestFormatAttributes(); |
| 199 | void TestFieldPositionIterator(); |
| 200 | |
| 201 | void TestLenientParse(); |
| 202 | |
| 203 | void TestDecimal(); |
| 204 | void TestCurrencyFractionDigits(); |
| 205 | |
| 206 | void TestExponentParse(); |
| 207 | void TestExplicitParents(); |
| 208 | void TestAvailableNumberingSystems(); |
| 209 | void Test9087(); |
| 210 | void TestFormatFastpaths(); |
| 211 | |
| 212 | void TestFormattableSize(); |
| 213 | |
| 214 | void TestUFormattable(); |
| 215 | |
| 216 | void TestEnumSet(); |
| 217 | |
| 218 | void TestSignificantDigits(); |
| 219 | void TestShowZero(); |
| 220 | |
| 221 | void TestCompatibleCurrencies(); |
| 222 | void TestBug9936(); |
| 223 | void TestParseNegativeWithFaLocale(); |
| 224 | void TestParseNegativeWithAlternateMinusSign(); |
| 225 | |
| 226 | void TestCustomCurrencySignAndSeparator(); |
| 227 | |
| 228 | void TestParseSignsAndMarks(); |
| 229 | void Test10419RoundingWith0FractionDigits(); |
| 230 | void Test10468ApplyPattern(); |
| 231 | void TestRoundingScientific10542(); |
| 232 | void TestZeroScientific10547(); |
| 233 | void TestAccountingCurrency(); |
| 234 | void TestCurrencyFormatForMissingLocale(); |
| 235 | void TestEquality(); |
| 236 | |
| 237 | void TestCurrencyUsage(); |
| 238 | |
| 239 | void TestDoubleLimit11439(); |
| 240 | void TestFastPathConsistent11524(); |
| 241 | void TestGetAffixes(); |
| 242 | void TestToPatternScientific11648(); |
| 243 | void TestBenchmark(); |
| 244 | void TestCtorApplyPatternDifference(); |
| 245 | void TestFractionalDigitsForCurrency(); |
| 246 | void TestFormatCurrencyPlural(); |
| 247 | void Test11868(); |
| 248 | void Test11739_ParseLongCurrency(); |
| 249 | void Test13035_MultiCodePointPaddingInPattern(); |
| 250 | void Test13737_ParseScientificStrict(); |
| 251 | void Test10727_RoundingZero(); |
| 252 | void Test11376_getAndSetPositivePrefix(); |
| 253 | void Test11475_signRecognition(); |
| 254 | void Test11640_getAffixes(); |
| 255 | void Test11649_toPatternWithMultiCurrency(); |
| 256 | void Test13327_numberingSystemBufferOverflow(); |
| 257 | void Test13391_chakmaParsing(); |
| 258 | |
| 259 | void Test11735_ExceptionIssue(); |
| 260 | void Test11035_FormatCurrencyAmount(); |
| 261 | void Test11318_DoubleConversion(); |
| 262 | void TestParsePercentRegression(); |
| 263 | void TestMultiplierWithScale(); |
| 264 | void TestFastFormatInt32(); |
| 265 | void Test11646_Equality(); |
| 266 | void TestParseNaN(); |
| 267 | void TestFormatFailIfMoreThanMaxDigits(); |
| 268 | void TestParseCaseSensitive(); |
| 269 | void TestParseNoExponent(); |
| 270 | void TestSignAlwaysShown(); |
| 271 | void TestMinimumGroupingDigits(); |
| 272 | void Test11897_LocalizedPatternSeparator(); |
| 273 | void Test13055_PercentageRounding(); |
| 274 | void Test11839(); |
| 275 | void Test10354(); |
| 276 | void Test11645_ApplyPatternEquality(); |
| 277 | void Test12567(); |
| 278 | void Test11626_CustomizeCurrencyPluralInfo(); |
| 279 | void Test20073_StrictPercentParseErrorIndex(); |
| 280 | void Test13056_GroupingSize(); |
| 281 | void Test11025_CurrencyPadding(); |
| 282 | void Test11648_ExpDecFormatMalPattern(); |
| 283 | void Test11649_DecFmtCurrencies(); |
| 284 | void Test13148_ParseGroupingSeparators(); |
| 285 | void Test12753_PatternDecimalPoint(); |
| 286 | void Test11647_PatternCurrencySymbols(); |
| 287 | void Test11913_BigDecimal(); |
| 288 | void Test11020_RoundingInScientificNotation(); |
| 289 | void Test11640_TripleCurrencySymbol(); |
| 290 | void Test13763_FieldPositionIteratorOffset(); |
| 291 | void Test13777_ParseLongNameNonCurrencyMode(); |
| 292 | void Test13804_EmptyStringsWhenParsing(); |
| 293 | void Test20037_ScientificIntegerOverflow(); |
| 294 | void Test13840_ParseLongStringCrash(); |
| 295 | void Test13850_EmptyStringCurrency(); |
| 296 | void Test20348_CurrencyPrefixOverride(); |
| 297 | void Test20956_MonetarySymbolGetters(); |
| 298 | void Test20358_GroupingInPattern(); |
| 299 | void Test13731_DefaultCurrency(); |
| 300 | void Test20499_CurrencyVisibleDigitsPlural(); |
| 301 | void Test13735_GroupingSizeGetter(); |
| 302 | void Test13734_StrictFlexibleWhitespace(); |
| 303 | void Test20961_CurrencyPluralPattern(); |
| 304 | void Test21134_ToNumberFormatter(); |
| 305 | void Test13733_StrictAndLenient(); |
| 306 | void Test20425_IntegerIncrement(); |
| 307 | void Test20425_FractionWithIntegerIncrement(); |
| 308 | void Test21232_ParseTimeout(); |
| 309 | void Test10997_FormatCurrency(); |
| 310 | void Test21556_CurrencyAsDecimal(); |
Frank Tang | 1f164ee | 2022-11-08 12:31:27 -0800 | [diff] [blame^] | 311 | void Test22088_Ethiopic(); |
Frank Tang | 3e05d9d | 2021-11-08 14:04:04 -0800 | [diff] [blame] | 312 | |
| 313 | private: |
| 314 | UBool testFormattableAsUFormattable(const char *file, int line, Formattable &f); |
| 315 | |
| 316 | void expectParseCurrency(const NumberFormat &fmt, const UChar* currency, double amount, const char *text); |
| 317 | |
| 318 | static UBool equalValue(const Formattable& a, const Formattable& b); |
| 319 | |
| 320 | void expectPositions(FieldPositionIterator& iter, int32_t *values, int32_t tupleCount, |
| 321 | const UnicodeString& str); |
| 322 | |
| 323 | void expectPosition(FieldPosition& pos, int32_t id, int32_t start, int32_t limit, |
| 324 | const UnicodeString& str); |
| 325 | |
| 326 | void expect2(NumberFormat& fmt, const Formattable& n, const UnicodeString& str); |
| 327 | |
| 328 | void expect3(NumberFormat& fmt, const Formattable& n, const UnicodeString& str); |
| 329 | |
| 330 | void expect2(NumberFormat& fmt, const Formattable& n, const char* str) { |
| 331 | expect2(fmt, n, UnicodeString(str, "")); |
| 332 | } |
| 333 | |
| 334 | void expect2(NumberFormat* fmt, const Formattable& n, const UnicodeString& str, UErrorCode ec); |
| 335 | |
| 336 | void expect2(NumberFormat* fmt, const Formattable& n, const char* str, UErrorCode ec) { |
| 337 | expect2(fmt, n, UnicodeString(str, ""), ec); |
| 338 | } |
| 339 | |
| 340 | void expect(NumberFormat& fmt, const UnicodeString& str, const Formattable& n); |
| 341 | |
| 342 | void expect(NumberFormat& fmt, const char *str, const Formattable& n) { |
| 343 | expect(fmt, UnicodeString(str, ""), n); |
| 344 | } |
| 345 | |
| 346 | void expect(NumberFormat& fmt, const Formattable& n, |
Frank Tang | 1f164ee | 2022-11-08 12:31:27 -0800 | [diff] [blame^] | 347 | const UnicodeString& exp, UBool rt=true); |
Frank Tang | 3e05d9d | 2021-11-08 14:04:04 -0800 | [diff] [blame] | 348 | |
| 349 | void expect(NumberFormat& fmt, const Formattable& n, |
Frank Tang | 1f164ee | 2022-11-08 12:31:27 -0800 | [diff] [blame^] | 350 | const char *exp, UBool rt=true) { |
Frank Tang | 3e05d9d | 2021-11-08 14:04:04 -0800 | [diff] [blame] | 351 | expect(fmt, n, UnicodeString(exp, ""), rt); |
| 352 | } |
| 353 | |
| 354 | void expect(NumberFormat* fmt, const Formattable& n, |
| 355 | const UnicodeString& exp, UBool rt, UErrorCode errorCode); |
| 356 | |
| 357 | void expect(NumberFormat* fmt, const Formattable& n, |
| 358 | const char *exp, UBool rt, UErrorCode errorCode) { |
| 359 | expect(fmt, n, UnicodeString(exp, ""), rt, errorCode); |
| 360 | } |
| 361 | |
| 362 | void expect(NumberFormat* fmt, const Formattable& n, |
| 363 | const UnicodeString& exp, UErrorCode errorCode) { |
Frank Tang | 1f164ee | 2022-11-08 12:31:27 -0800 | [diff] [blame^] | 364 | expect(fmt, n, exp, true, errorCode); |
Frank Tang | 3e05d9d | 2021-11-08 14:04:04 -0800 | [diff] [blame] | 365 | } |
| 366 | |
| 367 | void expect(NumberFormat* fmt, const Formattable& n, |
| 368 | const char *exp, UErrorCode errorCode) { |
Frank Tang | 1f164ee | 2022-11-08 12:31:27 -0800 | [diff] [blame^] | 369 | expect(fmt, n, UnicodeString(exp, ""), true, errorCode); |
Frank Tang | 3e05d9d | 2021-11-08 14:04:04 -0800 | [diff] [blame] | 370 | } |
| 371 | |
| 372 | void expectCurrency(NumberFormat& nf, const Locale& locale, |
| 373 | double value, const UnicodeString& string); |
| 374 | |
| 375 | void expectPad(DecimalFormat& fmt, const UnicodeString& pat, |
| 376 | int32_t pos, int32_t width, UChar pad); |
| 377 | |
| 378 | void expectPad(DecimalFormat& fmt, const char *pat, |
| 379 | int32_t pos, int32_t width, UChar pad) { |
| 380 | expectPad(fmt, UnicodeString(pat, ""), pos, width, pad); |
| 381 | } |
| 382 | |
| 383 | void expectPad(DecimalFormat& fmt, const UnicodeString& pat, |
| 384 | int32_t pos, int32_t width, const UnicodeString& pad); |
| 385 | |
| 386 | void expectPad(DecimalFormat& fmt, const char *pat, |
| 387 | int32_t pos, int32_t width, const UnicodeString& pad) { |
| 388 | expectPad(fmt, UnicodeString(pat, ""), pos, width, pad); |
| 389 | } |
| 390 | |
| 391 | void expectPat(DecimalFormat& fmt, const UnicodeString& exp); |
| 392 | |
| 393 | void expectPat(DecimalFormat& fmt, const char *exp) { |
| 394 | expectPat(fmt, UnicodeString(exp, "")); |
| 395 | } |
| 396 | |
| 397 | void expectPad(DecimalFormat& fmt, const UnicodeString& pat, |
| 398 | int32_t pos); |
| 399 | |
| 400 | void expectPad(DecimalFormat& fmt, const char *pat, |
| 401 | int32_t pos) { |
| 402 | expectPad(fmt, pat, pos, 0, (UChar)0); |
| 403 | } |
| 404 | |
| 405 | void expect_rbnf(NumberFormat& fmt, const UnicodeString& str, const Formattable& n); |
| 406 | |
| 407 | void expect_rbnf(NumberFormat& fmt, const Formattable& n, |
Frank Tang | 1f164ee | 2022-11-08 12:31:27 -0800 | [diff] [blame^] | 408 | const UnicodeString& exp, UBool rt=true); |
Frank Tang | 3e05d9d | 2021-11-08 14:04:04 -0800 | [diff] [blame] | 409 | |
| 410 | // internal utility routine |
| 411 | static UnicodeString& escape(UnicodeString& s); |
| 412 | |
| 413 | enum { ILLEGAL = -1 }; |
| 414 | |
| 415 | // internal subtest used by TestRounding487 |
| 416 | void roundingTest(NumberFormat& nf, double x, int32_t maxFractionDigits, const char* expected); |
| 417 | |
| 418 | // internal rounding checking for TestRounding |
| 419 | void checkRounding(DecimalFormat* df, double base, int iterations, double increment); |
| 420 | |
| 421 | double checkRound(DecimalFormat* df, double iValue, double lastParsed); |
| 422 | |
| 423 | void verifyRounding( |
| 424 | DecimalFormat& format, |
| 425 | const double *values, |
| 426 | const char * const *expected, |
| 427 | const DecimalFormat::ERoundingMode *roundingModes, |
| 428 | const char * const *descriptions, |
| 429 | int32_t valueSize, |
| 430 | int32_t roundingModeSize); |
| 431 | |
| 432 | void verifyFieldPositionIterator( |
| 433 | NumberFormatTest_Attributes *expected, |
| 434 | FieldPositionIterator &iter); |
| 435 | |
| 436 | }; |
| 437 | |
| 438 | #endif /* #if !UCONFIG_NO_FORMATTING */ |
| 439 | |
| 440 | #endif // _NUMBERFORMATTEST_ |