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 unitSkeletons(); 63 void unitUsage(); 64 void unitUsageErrorCodes(); 65 void unitUsageSkeletons(); 66 void unitCurrency(); 67 void unitPercent(); 68 void percentParity(); 69 void roundingFraction(); 70 void roundingFigures(); 71 void roundingFractionFigures(); 72 void roundingOther(); 73 void grouping(); 74 void padding(); 75 void integerWidth(); 76 void symbols(); 77 // TODO: Add this method if currency symbols override support is added. 78 //void symbolsOverride(); 79 void sign(); 80 void signNearZero(); 81 void signCoverage(); 82 void decimal(); 83 void scale(); 84 void locale(); 85 void skeletonUserGuideExamples(); 86 void formatTypes(); 87 void fieldPositionLogic(); 88 void fieldPositionCoverage(); 89 void toFormat(); 90 void errors(); 91 void validRanges(); 92 void copyMove(); 93 void localPointerCAPI(); 94 void toObject(); 95 void toDecimalNumber(); 96 void microPropsInternals(); 97 98 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 99 100 private: 101 CurrencyUnit USD; 102 CurrencyUnit GBP; 103 CurrencyUnit CZK; 104 CurrencyUnit CAD; 105 CurrencyUnit ESP; 106 CurrencyUnit PTE; 107 CurrencyUnit RON; 108 CurrencyUnit TWD; 109 CurrencyUnit TRY; 110 CurrencyUnit CNY; 111 112 MeasureUnit METER; 113 MeasureUnit METER_PER_SECOND; 114 MeasureUnit DAY; 115 MeasureUnit SQUARE_METER; 116 MeasureUnit FAHRENHEIT; 117 MeasureUnit SECOND; 118 MeasureUnit POUND; 119 MeasureUnit POUND_FORCE; 120 MeasureUnit SQUARE_MILE; 121 MeasureUnit SQUARE_INCH; 122 MeasureUnit JOULE; 123 MeasureUnit FURLONG; 124 MeasureUnit KELVIN; 125 126 NumberingSystem MATHSANB; 127 NumberingSystem LATN; 128 129 DecimalFormatSymbols FRENCH_SYMBOLS; 130 DecimalFormatSymbols SWISS_SYMBOLS; 131 DecimalFormatSymbols MYANMAR_SYMBOLS; 132 133 /** 134 * skeleton is the full length skeleton, which must round-trip. 135 * 136 * conciseSkeleton should be the shortest available skeleton. 137 * The concise skeleton can be read but not printed. 138 */ 139 void assertFormatDescending( 140 const char16_t* message, 141 const char16_t* skeleton, 142 const char16_t* conciseSkeleton, 143 const UnlocalizedNumberFormatter& f, 144 Locale locale, 145 ...); 146 147 /** See notes above regarding skeleton vs conciseSkeleton */ 148 void assertFormatDescendingBig( 149 const char16_t* message, 150 const char16_t* skeleton, 151 const char16_t* conciseSkeleton, 152 const UnlocalizedNumberFormatter& f, 153 Locale locale, 154 ...); 155 156 /** See notes above regarding skeleton vs conciseSkeleton */ 157 FormattedNumber assertFormatSingle( 158 const char16_t* message, 159 const char16_t* skeleton, 160 const char16_t* conciseSkeleton, 161 const UnlocalizedNumberFormatter& f, 162 Locale locale, 163 double input, 164 const UnicodeString& expected); 165 166 void assertUndefinedSkeleton(const UnlocalizedNumberFormatter& f); 167 168 void assertNumberFieldPositions( 169 const char16_t* message, 170 const FormattedNumber& formattedNumber, 171 const UFieldPosition* expectedFieldPositions, 172 int32_t length); 173 }; 174 175 class DecimalQuantityTest : public IntlTest { 176 public: 177 void testDecimalQuantityBehaviorStandalone(); 178 void testSwitchStorage(); 179 void testCopyMove(); 180 void testAppend(); 181 void testConvertToAccurateDouble(); 182 void testUseApproximateDoubleWhenAble(); 183 void testHardDoubleConversion(); 184 void testToDouble(); 185 void testMaxDigits(); 186 void testNickelRounding(); 187 void testCompactDecimalSuppressedExponent(); 188 void testSuppressedExponentUnchangedByInitialScaling(); 189 190 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 191 192 private: 193 void assertDoubleEquals(UnicodeString message, double a, double b); 194 void assertHealth(const DecimalQuantity &fq); 195 void assertToStringAndHealth(const DecimalQuantity &fq, const UnicodeString &expected); 196 void checkDoubleBehavior(double d, bool explicitRequired); 197 }; 198 199 class DoubleConversionTest : public IntlTest { 200 public: 201 void testDoubleConversionApi(); 202 203 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 204 }; 205 206 class ModifiersTest : public IntlTest { 207 public: 208 void testConstantAffixModifier(); 209 void testConstantMultiFieldModifier(); 210 void testSimpleModifier(); 211 void testCurrencySpacingEnabledModifier(); 212 213 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 214 215 private: 216 void assertModifierEquals(const Modifier &mod, int32_t expectedPrefixLength, bool expectedStrong, 217 UnicodeString expectedChars, UnicodeString expectedFields, 218 UErrorCode &status); 219 220 void assertModifierEquals(const Modifier &mod, FormattedStringBuilder &sb, int32_t expectedPrefixLength, 221 bool expectedStrong, UnicodeString expectedChars, 222 UnicodeString expectedFields, UErrorCode &status); 223 }; 224 225 class PatternModifierTest : public IntlTest { 226 public: 227 void testBasic(); 228 void testPatternWithNoPlaceholder(); 229 void testMutableEqualsImmutable(); 230 231 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 232 233 private: 234 UnicodeString getPrefix(const MutablePatternModifier &mod, UErrorCode &status); 235 UnicodeString getSuffix(const MutablePatternModifier &mod, UErrorCode &status); 236 }; 237 238 class PatternStringTest : public IntlTest { 239 public: 240 void testLocalized(); 241 void testToPatternSimple(); 242 void testExceptionOnInvalid(); 243 void testBug13117(); 244 245 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 246 247 private: 248 }; 249 250 class NumberParserTest : public IntlTest { 251 public: 252 void testBasic(); 253 void testLocaleFi(); 254 void testSeriesMatcher(); 255 void testCombinedCurrencyMatcher(); 256 void testAffixPatternMatcher(); 257 void testGroupingDisabled(); 258 void testCaseFolding(); 259 void test20360_BidiOverflow(); 260 void testInfiniteRecursion(); 261 262 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 263 }; 264 265 class NumberSkeletonTest : public IntlTest { 266 public: 267 void validTokens(); 268 void invalidTokens(); 269 void unknownTokens(); 270 void unexpectedTokens(); 271 void duplicateValues(); 272 void stemsRequiringOption(); 273 void defaultTokens(); 274 void flexibleSeparators(); 275 void wildcardCharacters(); 276 void perUnitInArabic(); 277 void perUnitToSkeleton(); 278 279 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 280 281 private: 282 void expectedErrorSkeleton(const char16_t** cases, int32_t casesLen); 283 }; 284 285 class NumberRangeFormatterTest : public IntlTestWithFieldPosition { 286 public: 287 NumberRangeFormatterTest(); 288 NumberRangeFormatterTest(UErrorCode &status); 289 290 void testSanity(); 291 void testBasic(); 292 void testCollapse(); 293 void testIdentity(); 294 void testDifferentFormatters(); 295 void testPlurals(); 296 void testFieldPositions(); 297 void testCopyMove(); 298 void toObject(); 299 void testGetDecimalNumbers(); 300 301 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 302 303 private: 304 CurrencyUnit USD; 305 CurrencyUnit GBP; 306 CurrencyUnit PTE; 307 308 MeasureUnit METER; 309 MeasureUnit KILOMETER; 310 MeasureUnit FAHRENHEIT; 311 MeasureUnit KELVIN; 312 313 void assertFormatRange( 314 const char16_t* message, 315 const UnlocalizedNumberRangeFormatter& f, 316 Locale locale, 317 const char16_t* expected_10_50, 318 const char16_t* expected_49_51, 319 const char16_t* expected_50_50, 320 const char16_t* expected_00_30, 321 const char16_t* expected_00_00, 322 const char16_t* expected_30_3K, 323 const char16_t* expected_30K_50K, 324 const char16_t* expected_49K_51K, 325 const char16_t* expected_50K_50K, 326 const char16_t* expected_50K_50M); 327 328 FormattedNumberRange assertFormattedRangeEquals( 329 const char16_t* message, 330 const LocalizedNumberRangeFormatter& l, 331 double first, 332 double second, 333 const char16_t* expected); 334 }; 335 336 class NumberPermutationTest : public IntlTest { 337 public: 338 void testPermutations(); 339 340 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0); 341 }; 342 343 344 // NOTE: This macro is identical to the one in itformat.cpp 345 #define TESTCLASS(id, TestClass) \ 346 case id: \ 347 name = #TestClass; \ 348 if (exec) { \ 349 logln(#TestClass " test---"); \ 350 logln((UnicodeString)""); \ 351 TestClass test; \ 352 callTest(test, par); \ 353 } \ 354 break 355 356 class NumberTest : public IntlTest { 357 public: 358 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) { 359 if (exec) { 360 logln("TestSuite NumberTest: "); 361 } 362 363 switch (index) { 364 TESTCLASS(0, AffixUtilsTest); 365 TESTCLASS(1, NumberFormatterApiTest); 366 TESTCLASS(2, DecimalQuantityTest); 367 TESTCLASS(3, ModifiersTest); 368 TESTCLASS(4, PatternModifierTest); 369 TESTCLASS(5, PatternStringTest); 370 TESTCLASS(6, DoubleConversionTest); 371 TESTCLASS(7, NumberParserTest); 372 TESTCLASS(8, NumberSkeletonTest); 373 TESTCLASS(9, NumberRangeFormatterTest); 374 TESTCLASS(10, NumberPermutationTest); 375 default: name = ""; break; // needed to end loop 376 } 377 } 378 }; 379 380 #endif /* #if !UCONFIG_NO_FORMATTING */ 381