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