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