• 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 UChar *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 
306     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
307 
308   private:
309     void expectedErrorSkeleton(const char16_t** cases, int32_t casesLen);
310 };
311 
312 class NumberRangeFormatterTest : public IntlTestWithFieldPosition {
313   public:
314     NumberRangeFormatterTest();
315     NumberRangeFormatterTest(UErrorCode &status);
316 
317     void testSanity();
318     void testBasic();
319     void testCollapse();
320     void testIdentity();
321     void testDifferentFormatters();
322     void testNaNInfinity();
323     void testPlurals();
324     void testFieldPositions();
325     void testCopyMove();
326     void toObject();
327     void testGetDecimalNumbers();
328     void test21684_Performance();
329     void test21358_SignPosition();
330     void test21683_StateLeak();
331     void testCreateLNRFFromNumberingSystemInSkeleton();
332 
333     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
334 
335   private:
336     CurrencyUnit USD;
337     CurrencyUnit CHF;
338     CurrencyUnit GBP;
339     CurrencyUnit PTE;
340 
341     MeasureUnit METER;
342     MeasureUnit KILOMETER;
343     MeasureUnit FAHRENHEIT;
344     MeasureUnit KELVIN;
345 
346     void assertFormatRange(
347       const char16_t* message,
348       const UnlocalizedNumberRangeFormatter& f,
349       Locale locale,
350       const char16_t* expected_10_50,
351       const char16_t* expected_49_51,
352       const char16_t* expected_50_50,
353       const char16_t* expected_00_30,
354       const char16_t* expected_00_00,
355       const char16_t* expected_30_3K,
356       const char16_t* expected_30K_50K,
357       const char16_t* expected_49K_51K,
358       const char16_t* expected_50K_50K,
359       const char16_t* expected_50K_50M);
360 
361     FormattedNumberRange assertFormattedRangeEquals(
362       const char16_t* message,
363       const LocalizedNumberRangeFormatter& l,
364       double first,
365       double second,
366       const char16_t* expected);
367 };
368 
369 class NumberPermutationTest : public IntlTest {
370   public:
371     void testPermutations();
372 
373     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
374 };
375 
376 
377 // NOTE: This macro is identical to the one in itformat.cpp
378 #define TESTCLASS(id, TestClass)          \
379     case id:                              \
380         name = #TestClass;                \
381         if (exec) {                       \
382             logln(#TestClass " test---"); \
383             logln((UnicodeString)"");     \
384             TestClass test;               \
385             callTest(test, par);          \
386         }                                 \
387         break
388 
389 class NumberTest : public IntlTest {
390   public:
391     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override {
392         if (exec) {
393             logln("TestSuite NumberTest: ");
394         }
395 
396         switch (index) {
397         TESTCLASS(0, AffixUtilsTest);
398         TESTCLASS(1, NumberFormatterApiTest);
399         TESTCLASS(2, DecimalQuantityTest);
400         TESTCLASS(3, ModifiersTest);
401         TESTCLASS(4, PatternModifierTest);
402         TESTCLASS(5, PatternStringTest);
403         TESTCLASS(6, DoubleConversionTest);
404         TESTCLASS(7, NumberParserTest);
405         TESTCLASS(8, NumberSkeletonTest);
406         TESTCLASS(9, NumberRangeFormatterTest);
407         TESTCLASS(10, NumberPermutationTest);
408         default: name = ""; break; // needed to end loop
409         }
410     }
411 };
412 
413 #endif /* #if !UCONFIG_NO_FORMATTING */
414