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