• 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) override;
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 unitNounClass();
70     void unitGender();
71     void unitNotConvertible();
72     void unitPercent();
73     void unitLocaleTags();
74     void percentParity();
75     void roundingFraction();
76     void roundingFigures();
77     void roundingFractionFigures();
78     void roundingOther();
79     void roundingIncrementRegressionTest();
80     void roundingPriorityCoverageTest();
81     void grouping();
82     void padding();
83     void integerWidth();
84     void symbols();
85     // TODO: Add this method if currency symbols override support is added.
86     //void symbolsOverride();
87     void sign();
88     void signNearZero();
89     void signCoverage();
90     void decimal();
91     void scale();
92     void locale();
93     void skeletonUserGuideExamples();
94     void formatTypes();
95     void fieldPositionLogic();
96     void fieldPositionCoverage();
97     void toFormat();
98     void errors();
99     void validRanges();
100     void copyMove();
101     void localPointerCAPI();
102     void toObject();
103     void toDecimalNumber();
104     void microPropsInternals();
105     void formatUnitsAliases();
106     void testIssue22378();
107 
108     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
109 
110   private:
111     CurrencyUnit USD;
112     CurrencyUnit GBP;
113     CurrencyUnit CZK;
114     CurrencyUnit CAD;
115     CurrencyUnit ESP;
116     CurrencyUnit PTE;
117     CurrencyUnit RON;
118     CurrencyUnit TWD;
119     CurrencyUnit TRY;
120     CurrencyUnit CNY;
121 
122     MeasureUnit METER;
123     MeasureUnit METER_PER_SECOND;
124     MeasureUnit DAY;
125     MeasureUnit SQUARE_METER;
126     MeasureUnit FAHRENHEIT;
127     MeasureUnit SECOND;
128     MeasureUnit POUND;
129     MeasureUnit POUND_FORCE;
130     MeasureUnit SQUARE_MILE;
131     MeasureUnit SQUARE_INCH;
132     MeasureUnit JOULE;
133     MeasureUnit FURLONG;
134     MeasureUnit KELVIN;
135 
136     NumberingSystem MATHSANB;
137     NumberingSystem LATN;
138 
139     DecimalFormatSymbols FRENCH_SYMBOLS;
140     DecimalFormatSymbols SWISS_SYMBOLS;
141     DecimalFormatSymbols MYANMAR_SYMBOLS;
142 
143     /**
144      * skeleton is the full length skeleton, which must round-trip.
145      *
146      * conciseSkeleton should be the shortest available skeleton.
147      * The concise skeleton can be read but not printed.
148      */
149     void assertFormatDescending(
150       const char16_t* message,
151       const char16_t* skeleton,
152       const char16_t* conciseSkeleton,
153       const UnlocalizedNumberFormatter& f,
154       Locale locale,
155       ...);
156 
157     /** See notes above regarding skeleton vs conciseSkeleton */
158     void assertFormatDescendingBig(
159       const char16_t* message,
160       const char16_t* skeleton,
161       const char16_t* conciseSkeleton,
162       const UnlocalizedNumberFormatter& f,
163       Locale locale,
164       ...);
165 
166     /** See notes above regarding skeleton vs conciseSkeleton */
167     FormattedNumber assertFormatSingle(
168       const char16_t* message,
169       const char16_t* skeleton,
170       const char16_t* conciseSkeleton,
171       const UnlocalizedNumberFormatter& f,
172       Locale locale,
173       double input,
174       const UnicodeString& expected);
175 
176     void assertUndefinedSkeleton(const UnlocalizedNumberFormatter& f);
177 
178     void assertNumberFieldPositions(
179       const char16_t* message,
180       const FormattedNumber& formattedNumber,
181       const UFieldPosition* expectedFieldPositions,
182       int32_t length);
183 
184     struct UnitInflectionTestCase {
185         const char *unitIdentifier;
186         const char *locale;
187         const char *unitDisplayCase;
188         double value;
189         const char16_t *expected;
190     };
191 
192     void runUnitInflectionsTestCases(UnlocalizedNumberFormatter unf,
193                                      UnicodeString skeleton,
194                                      const UnitInflectionTestCase *cases,
195                                      int32_t numCases,
196                                      IcuTestErrorCode &status);
197 };
198 
199 class DecimalQuantityTest : public IntlTest {
200   public:
201     void testDecimalQuantityBehaviorStandalone();
202     void testSwitchStorage();
203     void testCopyMove();
204     void testAppend();
205     void testConvertToAccurateDouble();
206     void testUseApproximateDoubleWhenAble();
207     void testHardDoubleConversion();
208     void testFitsInLong();
209     void testToDouble();
210     void testMaxDigits();
211     void testNickelRounding();
212     void testScientificAndCompactSuppressedExponent();
213     void testSuppressedExponentUnchangedByInitialScaling();
214     void testDecimalQuantityParseFormatRoundTrip();
215 
216     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
217 
218   private:
219     void assertDoubleEquals(UnicodeString message, double a, double b);
220     void assertHealth(const DecimalQuantity &fq);
221     void assertToStringAndHealth(const DecimalQuantity &fq, const UnicodeString &expected);
222     void checkDoubleBehavior(double d, bool explicitRequired);
223 };
224 
225 class DoubleConversionTest : public IntlTest {
226   public:
227     void testDoubleConversionApi();
228 
229     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
230 };
231 
232 class ModifiersTest : public IntlTest {
233   public:
234     void testConstantAffixModifier();
235     void testConstantMultiFieldModifier();
236     void testSimpleModifier();
237     void testCurrencySpacingEnabledModifier();
238 
239     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
240 
241   private:
242     void assertModifierEquals(const Modifier &mod, int32_t expectedPrefixLength, bool expectedStrong,
243                               UnicodeString expectedChars, UnicodeString expectedFields,
244                               UErrorCode &status);
245 
246     void assertModifierEquals(const Modifier &mod, FormattedStringBuilder &sb, int32_t expectedPrefixLength,
247                               bool expectedStrong, UnicodeString expectedChars,
248                               UnicodeString expectedFields, UErrorCode &status);
249 };
250 
251 class PatternModifierTest : public IntlTest {
252   public:
253     void testBasic();
254     void testPatternWithNoPlaceholder();
255     void testMutableEqualsImmutable();
256 
257     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
258 
259   private:
260     UnicodeString getPrefix(const MutablePatternModifier &mod, UErrorCode &status);
261     UnicodeString getSuffix(const MutablePatternModifier &mod, UErrorCode &status);
262 };
263 
264 class PatternStringTest : public IntlTestWithFieldPosition {
265   public:
266     void testLocalized();
267     void testToPatternSimple();
268     void testExceptionOnInvalid();
269     void testBug13117();
270     void testCurrencyDecimal();
271 
272     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
273 
274   private:
275 };
276 
277 class NumberParserTest : public IntlTest {
278   public:
279     void testBasic();
280     void testLocaleFi();
281     void testSeriesMatcher();
282     void testCombinedCurrencyMatcher();
283     void testAffixPatternMatcher();
284     void testGroupingDisabled();
285     void testCaseFolding();
286     void test20360_BidiOverflow();
287     void testInfiniteRecursion();
288 
289     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
290 };
291 
292 class NumberSkeletonTest : public IntlTest {
293   public:
294     void validTokens();
295     void invalidTokens();
296     void unknownTokens();
297     void unexpectedTokens();
298     void duplicateValues();
299     void stemsRequiringOption();
300     void defaultTokens();
301     void flexibleSeparators();
302     void wildcardCharacters();
303     void perUnitInArabic();
304     void perUnitToSkeleton();
305     void measurementSystemOverride();
306 
307     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
308 
309   private:
310     void expectedErrorSkeleton(const char16_t** cases, int32_t casesLen);
311 };
312 
313 class NumberRangeFormatterTest : public IntlTestWithFieldPosition {
314   public:
315     NumberRangeFormatterTest();
316     NumberRangeFormatterTest(UErrorCode &status);
317 
318     void testSanity();
319     void testBasic();
320     void testCollapse();
321     void testIdentity();
322     void testDifferentFormatters();
323     void testNaNInfinity();
324     void testPlurals();
325     void testFieldPositions();
326     void testCopyMove();
327     void toObject();
328     void testGetDecimalNumbers();
329     void test21684_Performance();
330     void test21358_SignPosition();
331     void test21683_StateLeak();
332     void testCreateLNRFFromNumberingSystemInSkeleton();
333 
334     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
335 
336   private:
337     CurrencyUnit USD;
338     CurrencyUnit CHF;
339     CurrencyUnit GBP;
340     CurrencyUnit PTE;
341 
342     MeasureUnit METER;
343     MeasureUnit KILOMETER;
344     MeasureUnit FAHRENHEIT;
345     MeasureUnit KELVIN;
346 
347     void assertFormatRange(
348       const char16_t* message,
349       const UnlocalizedNumberRangeFormatter& f,
350       Locale locale,
351       const char16_t* expected_10_50,
352       const char16_t* expected_49_51,
353       const char16_t* expected_50_50,
354       const char16_t* expected_00_30,
355       const char16_t* expected_00_00,
356       const char16_t* expected_30_3K,
357       const char16_t* expected_30K_50K,
358       const char16_t* expected_49K_51K,
359       const char16_t* expected_50K_50K,
360       const char16_t* expected_50K_50M);
361 
362     FormattedNumberRange assertFormattedRangeEquals(
363       const char16_t* message,
364       const LocalizedNumberRangeFormatter& l,
365       double first,
366       double second,
367       const char16_t* expected);
368 };
369 
370 class SimpleNumberFormatterTest : public IntlTestWithFieldPosition {
371   public:
372     void testBasic();
373     void testWithOptions();
374     void testSymbols();
375     void testSign();
376     void testCopyMove();
377     void testCAPI();
378 
379     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
380 };
381 
382 class NumberPermutationTest : public IntlTest {
383   public:
384     void testPermutations();
385 
386     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
387 };
388 
389 
390 // NOTE: This macro is identical to the one in itformat.cpp
391 #define TESTCLASS(id, TestClass)          \
392     case id:                              \
393         name = #TestClass;                \
394         if (exec) {                       \
395             logln(#TestClass " test---"); \
396             logln((UnicodeString)"");     \
397             TestClass test;               \
398             callTest(test, par);          \
399         }                                 \
400         break
401 
402 class NumberTest : public IntlTest {
403   public:
404     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override {
405         if (exec) {
406             logln("TestSuite NumberTest: ");
407         }
408 
409         switch (index) {
410         TESTCLASS(0, AffixUtilsTest);
411         TESTCLASS(1, NumberFormatterApiTest);
412         TESTCLASS(2, DecimalQuantityTest);
413         TESTCLASS(3, ModifiersTest);
414         TESTCLASS(4, PatternModifierTest);
415         TESTCLASS(5, PatternStringTest);
416         TESTCLASS(6, DoubleConversionTest);
417         TESTCLASS(7, NumberParserTest);
418         TESTCLASS(8, NumberSkeletonTest);
419         TESTCLASS(9, NumberRangeFormatterTest);
420         TESTCLASS(10, SimpleNumberFormatterTest);
421         TESTCLASS(11, NumberPermutationTest);
422         default: name = ""; break; // needed to end loop
423         }
424     }
425 };
426 
427 #endif /* #if !UCONFIG_NO_FORMATTING */
428