1 // © 2017 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 #include "unicode/utypes.h" 5 6 #if !UCONFIG_NO_FORMATTING 7 #pragma once 8 9 #include "formatted_string_builder.h" 10 #include "intltest.h" 11 #include "itformat.h" 12 #include "number_affixutils.h" 13 #include "string_segment.h" 14 #include "numrange_impl.h" 15 #include "unicode/locid.h" 16 #include "unicode/numberformatter.h" 17 #include "unicode/numberrangeformatter.h" 18 19 // ICU-20241 Solaris #defines ESP in sys/regset.h 20 #ifdef ESP 21 # undef ESP 22 #endif 23 24 using namespace icu::number; 25 using namespace icu::number::impl; 26 using namespace icu::numparse; 27 using namespace icu::numparse::impl; 28 29 //////////////////////////////////////////////////////////////////////////////////////// 30 // INSTRUCTIONS: // 31 // To add new NumberFormat unit test classes, create a new class like the ones below, // 32 // and then add it as a switch statement in NumberTest at the bottom of this file. ///////// 33 // To add new methods to existing unit test classes, add the method to the class declaration // 34 // below, and also add it to the class's implementation of runIndexedTest(). // 35 /////////////////////////////////////////////////////////////////////////////////////////////// 36 37 class AffixUtilsTest : public IntlTest { 38 public: 39 void testEscape(); 40 void testUnescape(); 41 void testContainsReplaceType(); 42 void testInvalid(); 43 void testUnescapeWithSymbolProvider(); 44 45 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 46 47 private: 48 UnicodeString unescapeWithDefaults(const SymbolProvider &defaultProvider, UnicodeString input, 49 UErrorCode &status); 50 }; 51 52 class NumberFormatterApiTest : public IntlTestWithFieldPosition { 53 public: 54 NumberFormatterApiTest(); 55 NumberFormatterApiTest(UErrorCode &status); 56 57 void notationSimple(); 58 void notationScientific(); 59 void notationCompact(); 60 void unitMeasure(); 61 void unitCompoundMeasure(); 62 void unitArbitraryMeasureUnits(); 63 void unitSkeletons(); 64 void unitUsage(); 65 void unitUsageErrorCodes(); 66 void unitUsageSkeletons(); 67 void unitCurrency(); 68 void unitInflections(); 69 void unitGender(); 70 void unitPercent(); 71 void percentParity(); 72 void roundingFraction(); 73 void roundingFigures(); 74 void roundingFractionFigures(); 75 void roundingOther(); 76 void grouping(); 77 void padding(); 78 void integerWidth(); 79 void symbols(); 80 // TODO: Add this method if currency symbols override support is added. 81 //void symbolsOverride(); 82 void sign(); 83 void signNearZero(); 84 void signCoverage(); 85 void decimal(); 86 void scale(); 87 void locale(); 88 void skeletonUserGuideExamples(); 89 void formatTypes(); 90 void fieldPositionLogic(); 91 void fieldPositionCoverage(); 92 void toFormat(); 93 void errors(); 94 void validRanges(); 95 void copyMove(); 96 void localPointerCAPI(); 97 void toObject(); 98 void toDecimalNumber(); 99 void microPropsInternals(); 100 101 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 102 103 private: 104 CurrencyUnit USD; 105 CurrencyUnit GBP; 106 CurrencyUnit CZK; 107 CurrencyUnit CAD; 108 CurrencyUnit ESP; 109 CurrencyUnit PTE; 110 CurrencyUnit RON; 111 CurrencyUnit TWD; 112 CurrencyUnit TRY; 113 CurrencyUnit CNY; 114 115 MeasureUnit METER; 116 MeasureUnit METER_PER_SECOND; 117 MeasureUnit DAY; 118 MeasureUnit SQUARE_METER; 119 MeasureUnit FAHRENHEIT; 120 MeasureUnit SECOND; 121 MeasureUnit POUND; 122 MeasureUnit POUND_FORCE; 123 MeasureUnit SQUARE_MILE; 124 MeasureUnit SQUARE_INCH; 125 MeasureUnit JOULE; 126 MeasureUnit FURLONG; 127 MeasureUnit KELVIN; 128 129 NumberingSystem MATHSANB; 130 NumberingSystem LATN; 131 132 DecimalFormatSymbols FRENCH_SYMBOLS; 133 DecimalFormatSymbols SWISS_SYMBOLS; 134 DecimalFormatSymbols MYANMAR_SYMBOLS; 135 136 /** 137 * skeleton is the full length skeleton, which must round-trip. 138 * 139 * conciseSkeleton should be the shortest available skeleton. 140 * The concise skeleton can be read but not printed. 141 */ 142 void assertFormatDescending( 143 const char16_t* message, 144 const char16_t* skeleton, 145 const char16_t* conciseSkeleton, 146 const UnlocalizedNumberFormatter& f, 147 Locale locale, 148 ...); 149 150 /** See notes above regarding skeleton vs conciseSkeleton */ 151 void assertFormatDescendingBig( 152 const char16_t* message, 153 const char16_t* skeleton, 154 const char16_t* conciseSkeleton, 155 const UnlocalizedNumberFormatter& f, 156 Locale locale, 157 ...); 158 159 /** See notes above regarding skeleton vs conciseSkeleton */ 160 FormattedNumber assertFormatSingle( 161 const char16_t* message, 162 const char16_t* skeleton, 163 const char16_t* conciseSkeleton, 164 const UnlocalizedNumberFormatter& f, 165 Locale locale, 166 double input, 167 const UnicodeString& expected); 168 169 void assertUndefinedSkeleton(const UnlocalizedNumberFormatter& f); 170 171 void assertNumberFieldPositions( 172 const char16_t* message, 173 const FormattedNumber& formattedNumber, 174 const UFieldPosition* expectedFieldPositions, 175 int32_t length); 176 177 struct UnitInflectionTestCase { 178 const char *unitIdentifier; 179 const char *locale; 180 const char *unitDisplayCase; 181 double value; 182 const UChar *expected; 183 }; 184 185 void runUnitInflectionsTestCases(UnlocalizedNumberFormatter unf, 186 UnicodeString skeleton, 187 const UnitInflectionTestCase *cases, 188 int32_t numCases, 189 IcuTestErrorCode &status); 190 }; 191 192 class DecimalQuantityTest : public IntlTest { 193 public: 194 void testDecimalQuantityBehaviorStandalone(); 195 void testSwitchStorage(); 196 void testCopyMove(); 197 void testAppend(); 198 void testConvertToAccurateDouble(); 199 void testUseApproximateDoubleWhenAble(); 200 void testHardDoubleConversion(); 201 void testFitsInLong(); 202 void testToDouble(); 203 void testMaxDigits(); 204 void testNickelRounding(); 205 void testScientificAndCompactSuppressedExponent(); 206 void testSuppressedExponentUnchangedByInitialScaling(); 207 208 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 209 210 private: 211 void assertDoubleEquals(UnicodeString message, double a, double b); 212 void assertHealth(const DecimalQuantity &fq); 213 void assertToStringAndHealth(const DecimalQuantity &fq, const UnicodeString &expected); 214 void checkDoubleBehavior(double d, bool explicitRequired); 215 }; 216 217 class DoubleConversionTest : public IntlTest { 218 public: 219 void testDoubleConversionApi(); 220 221 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 222 }; 223 224 class ModifiersTest : public IntlTest { 225 public: 226 void testConstantAffixModifier(); 227 void testConstantMultiFieldModifier(); 228 void testSimpleModifier(); 229 void testCurrencySpacingEnabledModifier(); 230 231 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 232 233 private: 234 void assertModifierEquals(const Modifier &mod, int32_t expectedPrefixLength, bool expectedStrong, 235 UnicodeString expectedChars, UnicodeString expectedFields, 236 UErrorCode &status); 237 238 void assertModifierEquals(const Modifier &mod, FormattedStringBuilder &sb, int32_t expectedPrefixLength, 239 bool expectedStrong, UnicodeString expectedChars, 240 UnicodeString expectedFields, UErrorCode &status); 241 }; 242 243 class PatternModifierTest : public IntlTest { 244 public: 245 void testBasic(); 246 void testPatternWithNoPlaceholder(); 247 void testMutableEqualsImmutable(); 248 249 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 250 251 private: 252 UnicodeString getPrefix(const MutablePatternModifier &mod, UErrorCode &status); 253 UnicodeString getSuffix(const MutablePatternModifier &mod, UErrorCode &status); 254 }; 255 256 class PatternStringTest : public IntlTest { 257 public: 258 void testLocalized(); 259 void testToPatternSimple(); 260 void testExceptionOnInvalid(); 261 void testBug13117(); 262 263 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 264 265 private: 266 }; 267 268 class NumberParserTest : public IntlTest { 269 public: 270 void testBasic(); 271 void testLocaleFi(); 272 void testSeriesMatcher(); 273 void testCombinedCurrencyMatcher(); 274 void testAffixPatternMatcher(); 275 void testGroupingDisabled(); 276 void testCaseFolding(); 277 void test20360_BidiOverflow(); 278 void testInfiniteRecursion(); 279 280 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 281 }; 282 283 class NumberSkeletonTest : public IntlTest { 284 public: 285 void validTokens(); 286 void invalidTokens(); 287 void unknownTokens(); 288 void unexpectedTokens(); 289 void duplicateValues(); 290 void stemsRequiringOption(); 291 void defaultTokens(); 292 void flexibleSeparators(); 293 void wildcardCharacters(); 294 void perUnitInArabic(); 295 void perUnitToSkeleton(); 296 297 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 298 299 private: 300 void expectedErrorSkeleton(const char16_t** cases, int32_t casesLen); 301 }; 302 303 class NumberRangeFormatterTest : public IntlTestWithFieldPosition { 304 public: 305 NumberRangeFormatterTest(); 306 NumberRangeFormatterTest(UErrorCode &status); 307 308 void testSanity(); 309 void testBasic(); 310 void testCollapse(); 311 void testIdentity(); 312 void testDifferentFormatters(); 313 void testPlurals(); 314 void testFieldPositions(); 315 void testCopyMove(); 316 void toObject(); 317 void testGetDecimalNumbers(); 318 319 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 320 321 private: 322 CurrencyUnit USD; 323 CurrencyUnit GBP; 324 CurrencyUnit PTE; 325 326 MeasureUnit METER; 327 MeasureUnit KILOMETER; 328 MeasureUnit FAHRENHEIT; 329 MeasureUnit KELVIN; 330 331 void assertFormatRange( 332 const char16_t* message, 333 const UnlocalizedNumberRangeFormatter& f, 334 Locale locale, 335 const char16_t* expected_10_50, 336 const char16_t* expected_49_51, 337 const char16_t* expected_50_50, 338 const char16_t* expected_00_30, 339 const char16_t* expected_00_00, 340 const char16_t* expected_30_3K, 341 const char16_t* expected_30K_50K, 342 const char16_t* expected_49K_51K, 343 const char16_t* expected_50K_50K, 344 const char16_t* expected_50K_50M); 345 346 FormattedNumberRange assertFormattedRangeEquals( 347 const char16_t* message, 348 const LocalizedNumberRangeFormatter& l, 349 double first, 350 double second, 351 const char16_t* expected); 352 }; 353 354 class NumberPermutationTest : public IntlTest { 355 public: 356 void testPermutations(); 357 358 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 359 }; 360 361 362 // NOTE: This macro is identical to the one in itformat.cpp 363 #define TESTCLASS(id, TestClass) \ 364 case id: \ 365 name = #TestClass; \ 366 if (exec) { \ 367 logln(#TestClass " test---"); \ 368 logln((UnicodeString)""); \ 369 TestClass test; \ 370 callTest(test, par); \ 371 } \ 372 break 373 374 class NumberTest : public IntlTest { 375 public: 376 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) { 377 if (exec) { 378 logln("TestSuite NumberTest: "); 379 } 380 381 switch (index) { 382 TESTCLASS(0, AffixUtilsTest); 383 TESTCLASS(1, NumberFormatterApiTest); 384 TESTCLASS(2, DecimalQuantityTest); 385 TESTCLASS(3, ModifiersTest); 386 TESTCLASS(4, PatternModifierTest); 387 TESTCLASS(5, PatternStringTest); 388 TESTCLASS(6, DoubleConversionTest); 389 TESTCLASS(7, NumberParserTest); 390 TESTCLASS(8, NumberSkeletonTest); 391 TESTCLASS(9, NumberRangeFormatterTest); 392 TESTCLASS(10, NumberPermutationTest); 393 default: name = ""; break; // needed to end loop 394 } 395 } 396 }; 397 398 #endif /* #if !UCONFIG_NO_FORMATTING */ 399