• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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