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