• 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 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